Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Several range algorithms #565

Merged
merged 7 commits into from
Mar 5, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
798 changes: 798 additions & 0 deletions stl/inc/algorithm

Large diffs are not rendered by default.

67 changes: 25 additions & 42 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 @@ -182,11 +180,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
&& 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 +195,21 @@ 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_testable_impl = convertible_to<_Ty, bool>;

// CONCEPT boolean
#if _HAS_STD_BOOLEAN
#define _STL_BOOLEAN_CONCEPT boolean
#else
#define _STL_BOOLEAN_CONCEPT _Boolean
#endif
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) {
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved
{ !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,14 @@ 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>&>>
&& equality_comparable_with<_Ty1, _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>;
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved

// CONCEPT semiregular
template <class _Ty>
Expand All @@ -301,13 +280,17 @@ 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>
&& predicate<_FTy, _Ty2, _Ty1>;
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved

// 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
8 changes: 2 additions & 6 deletions stl/inc/ranges
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,11 @@ 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 @@ -276,7 +276,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 @@ -309,7 +309,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