Skip to content

Commit

Permalink
Merge pull request #46 from microsoft/master
Browse files Browse the repository at this point in the history
Several range algorithms (microsoft#565)
  • Loading branch information
fengjixuchui authored Mar 5, 2020
2 parents a12a20b + 930b843 commit 56e8ca7
Show file tree
Hide file tree
Showing 47 changed files with 3,342 additions and 327 deletions.
800 changes: 800 additions & 0 deletions stl/inc/algorithm

Large diffs are not rendered by default.

83 changes: 38 additions & 45 deletions stl/inc/concepts
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,9 @@ concept derived_from = __is_base_of(_Base, _Derived)
// CONCEPT convertible_to
template <class _From, class _To>
concept convertible_to = __is_convertible_to(_From, _To)
#if 1 // Implement the PR of LWG-3151
&& requires { static_cast<_To>(_STD declval<_From>()); };
#else // ^^^ LWG-3151 / N4810 vvv
&& requires(_From (&_Fn)()) { static_cast<_To>(_Fn()); };
#endif // select LWG-3151 vs. N4810
&& requires(add_rvalue_reference_t<_From> (&_Fn)()) {
static_cast<_To>(_Fn());
};

// CONCEPT common_reference_with
template <class _Ty1, class _Ty2>
Expand Down Expand Up @@ -181,12 +179,7 @@ concept swappable = requires(_Ty& __x, _Ty& __y) {

// CONCEPT swappable_with
template <class _Ty1, class _Ty2>
concept swappable_with =
#if 1 // Implement the PR of LWG-3175
common_reference_with<_Ty1, _Ty2>
#else // ^^^ LWG-3175 / N4810 vvv
common_reference_with<const remove_reference_t<_Ty1>&, const remove_reference_t<_Ty2>&>
#endif // select LWG-3175 vs. N4810
concept swappable_with = common_reference_with<_Ty1, _Ty2>
&& requires(_Ty1&& __t, _Ty2&& __u) {
_RANGES swap(static_cast<_Ty1&&>(__t), static_cast<_Ty1&&>(__t));
_RANGES swap(static_cast<_Ty2&&>(__u), static_cast<_Ty2&&>(__u));
Expand All @@ -201,41 +194,22 @@ concept copy_constructible = move_constructible<_Ty>
&& constructible_from<_Ty, const _Ty&> && convertible_to<const _Ty&, _Ty>
&& constructible_from<_Ty, const _Ty> && convertible_to<const _Ty, _Ty>;

// CONCEPT movable
// CONCEPT _Boolean_testable
template <class _Ty>
concept movable = is_object_v<_Ty> && move_constructible<_Ty> && assignable_from<_Ty&, _Ty> && swappable<_Ty>;

// CONCEPT boolean
#if _HAS_STD_BOOLEAN
#define _STL_BOOLEAN_CONCEPT boolean
#else
#define _STL_BOOLEAN_CONCEPT _Boolean
#endif
concept _Boolean_testable_impl = convertible_to<_Ty, bool>;

template <class _Ty>
concept _STL_BOOLEAN_CONCEPT = movable<remove_cvref_t<_Ty>>
&& requires(const remove_reference_t<_Ty>& __x, const remove_reference_t<_Ty>& __y, const bool __b) {
{ __x } -> convertible_to<bool>;
{ !__x } -> convertible_to<bool>;
{ __x && __y } -> same_as<bool>;
{ __x && __b } -> same_as<bool>;
{ __b && __y } -> same_as<bool>;
{ __x || __y } -> same_as<bool>;
{ __x || __b } -> same_as<bool>;
{ __b || __y } -> same_as<bool>;
{ __x == __y } -> convertible_to<bool>;
{ __x == __b } -> convertible_to<bool>;
{ __b == __y } -> convertible_to<bool>;
{ __x != __y } -> convertible_to<bool>;
{ __x != __b } -> convertible_to<bool>;
{ __b != __y } -> convertible_to<bool>;
concept _Boolean_testable = _Boolean_testable_impl<_Ty>
&& requires (_Ty&& __t) {
{ !static_cast<_Ty&&>(__t) } -> _Boolean_testable_impl;
};

// CONCEPT _Weakly_equality_comparable_with
template <class _Ty1, class _Ty2>
concept _Half_equality_comparable =
requires(const remove_reference_t<_Ty1>& __x, const remove_reference_t<_Ty2>& __y) {
{ __x == __y } -> _STL_BOOLEAN_CONCEPT;
{ __x != __y } -> _STL_BOOLEAN_CONCEPT;
{ __x == __y } -> _Boolean_testable;
{ __x != __y } -> _Boolean_testable;
};

template <class _Ty1, class _Ty2>
Expand All @@ -257,10 +231,10 @@ concept equality_comparable_with = equality_comparable<_Ty1> && equality_compara
// CONCEPT _Partially_ordered_with
template <class _Ty1, class _Ty2>
concept _Half_ordered = requires(const remove_reference_t<_Ty1>& __t, const remove_reference_t<_Ty2>& __u) {
{ __t < __u } -> _STL_BOOLEAN_CONCEPT;
{ __t > __u } -> _STL_BOOLEAN_CONCEPT;
{ __t <= __u } -> _STL_BOOLEAN_CONCEPT;
{ __t >= __u } -> _STL_BOOLEAN_CONCEPT;
{ __t < __u } -> _Boolean_testable;
{ __t > __u } -> _Boolean_testable;
{ __t <= __u } -> _Boolean_testable;
{ __t >= __u } -> _Boolean_testable;
};

template <class _Ty1, class _Ty2>
Expand All @@ -277,9 +251,20 @@ concept totally_ordered_with = totally_ordered<_Ty1> && totally_ordered<_Ty2>
&& totally_ordered<common_reference_t<const remove_reference_t<_Ty1>&, const remove_reference_t<_Ty2>&>>
&& _Partially_ordered_with<_Ty1, _Ty2>;

// CONCEPT movable
template <class _Ty>
concept movable = is_object_v<_Ty>
&& move_constructible<_Ty>
&& assignable_from<_Ty&, _Ty>
&& swappable<_Ty>;

// CONCEPT copyable
template <class _Ty>
concept copyable = copy_constructible<_Ty> && movable<_Ty> && assignable_from<_Ty&, const _Ty&>;
concept copyable = copy_constructible<_Ty>
&& movable<_Ty>
&& assignable_from<_Ty&, _Ty&>
&& assignable_from<_Ty&, const _Ty&>
&& assignable_from<_Ty&, const _Ty>;

// CONCEPT semiregular
template <class _Ty>
Expand All @@ -301,13 +286,21 @@ concept regular_invocable = invocable<_FTy, _ArgTys...>;

// CONCEPT predicate
template <class _FTy, class... _ArgTys>
concept predicate = regular_invocable<_FTy, _ArgTys...> && _STL_BOOLEAN_CONCEPT<invoke_result_t<_FTy, _ArgTys...>>;
concept predicate = regular_invocable<_FTy, _ArgTys...>
&& _Boolean_testable<invoke_result_t<_FTy, _ArgTys...>>;

// CONCEPT relation
template <class _FTy, class _Ty1, class _Ty2>
concept relation = predicate<_FTy, _Ty1, _Ty1> && predicate<_FTy, _Ty2, _Ty2> && predicate<_FTy, _Ty1, _Ty2>
concept relation =
predicate<_FTy, _Ty1, _Ty1>
&& predicate<_FTy, _Ty2, _Ty2>
&& predicate<_FTy, _Ty1, _Ty2>
&& predicate<_FTy, _Ty2, _Ty1>;

// CONCEPT equivalence_relation
template <class _FTy, class _Ty1, class _Ty2>
concept equivalence_relation = relation<_FTy, _Ty1, _Ty2>;

// CONCEPT strict_weak_order
template <class _FTy, class _Ty1, class _Ty2>
concept strict_weak_order = relation<_FTy, _Ty1, _Ty2>;
Expand Down
12 changes: 0 additions & 12 deletions stl/inc/functional
Original file line number Diff line number Diff line change
Expand Up @@ -658,18 +658,6 @@ _NODISCARD _Mem_fn<_Rx _Ty::*> mem_fn(_Rx _Ty::*_Pm) noexcept {
return _Mem_fn<_Rx _Ty::*>(_Pm);
}

#if _HAS_CXX20
// STRUCT identity
struct identity {
template <class _Ty>
_NODISCARD constexpr _Ty&& operator()(_Ty&& _Left) const noexcept {
return _STD forward<_Ty>(_Left);
}

using is_transparent = int;
};
#endif // _HAS_CXX20

#if _HAS_CXX17
// FUNCTION TEMPLATE not_fn
struct _Not_fn_tag {
Expand Down
9 changes: 3 additions & 6 deletions stl/inc/ranges
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,12 @@ namespace ranges {
// Much machinery defined in <xutility>

// clang-format off
// CONCEPT ranges::common_range
template <class _Rng>
concept common_range = range<_Rng> && same_as<iterator_t<_Rng>, sentinel_t<_Rng>>;

// CONCEPT ranges::viewable_range
template <class _Rng>
concept viewable_range = range<_Rng> && (safe_range<_Rng> || view<remove_cvref_t<_Rng>>);
// clang-format on
concept viewable_range = range<_Rng>
&& (borrowed_range<_Rng> || view<remove_cvref_t<_Rng>>);
} // namespace ranges

_STD_END

#pragma pop_macro("new")
Expand Down
4 changes: 2 additions & 2 deletions stl/inc/span
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ class span;
#ifdef __cpp_lib_concepts
namespace ranges {
template <class _Ty, size_t _Extent>
inline constexpr bool enable_safe_range<span<_Ty, _Extent>> = true;
inline constexpr bool enable_borrowed_range<span<_Ty, _Extent>> = true;
} // namespace ranges

// VARIABLE TEMPLATE _Is_span_v
Expand Down Expand Up @@ -293,7 +293,7 @@ concept _Is_span_compatible_range =
&& !_Is_std_array_v<remove_cvref_t<_Rng>>
&& _RANGES contiguous_range<_Rng>
&& _RANGES sized_range<_Rng>
&& (_RANGES safe_range<_Rng> || is_const_v<_Ty>)
&& (_RANGES borrowed_range<_Rng> || is_const_v<_Ty>)
&& is_convertible_v<remove_reference_t<_RANGES range_reference_t<_Rng>>(*)[], _Ty(*)[]>;
// clang-format on
#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv
Expand Down
2 changes: 1 addition & 1 deletion stl/inc/xstring
Original file line number Diff line number Diff line change
Expand Up @@ -1576,7 +1576,7 @@ private:
#ifdef __cpp_lib_concepts
namespace ranges {
template <class _Elem, class _Traits>
inline constexpr bool enable_safe_range<basic_string_view<_Elem, _Traits>> = true;
inline constexpr bool enable_borrowed_range<basic_string_view<_Elem, _Traits>> = true;
} // namespace ranges
#endif // __cpp_lib_concepts

Expand Down
Loading

0 comments on commit 56e8ca7

Please sign in to comment.