-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Implement P2408R5: Ranges Iterators As Inputs To Non-Ranges Algorithms #2960
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
Changes from all commits
0a3430a
2103356
96c60cc
f6d471f
4354bcd
aed6afc
158d873
dd099a2
37898ed
8293ef2
58d98f9
59e775f
a4391db
8283a09
aea8deb
0b38f67
eccf5b4
687e8c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -843,16 +843,48 @@ template <class _Ty> | |
| struct _Is_iterator : bool_constant<_Is_iterator_v<_Ty>> {}; | ||
|
|
||
| template <class _Iter> | ||
| _INLINE_VAR constexpr bool _Is_input_iter_v = is_convertible_v<_Iter_cat_t<_Iter>, input_iterator_tag>; | ||
| _INLINE_VAR constexpr bool _Is_cpp17_input_iter_v = is_convertible_v<_Iter_cat_t<_Iter>, input_iterator_tag>; | ||
|
|
||
| template <class _Iter> | ||
| _INLINE_VAR constexpr bool _Is_fwd_iter_v = is_convertible_v<_Iter_cat_t<_Iter>, forward_iterator_tag>; | ||
| _INLINE_VAR constexpr bool _Is_ranges_input_iter_v = | ||
| #ifdef __cpp_lib_concepts | ||
| (input_iterator<_Iter> && sentinel_for<_Iter, _Iter>) || | ||
| #endif | ||
| _Is_cpp17_input_iter_v<_Iter>; | ||
|
|
||
| template <class _Iter> | ||
| _INLINE_VAR constexpr bool _Is_cpp17_fwd_iter_v = is_convertible_v<_Iter_cat_t<_Iter>, forward_iterator_tag>; | ||
|
|
||
| template <class _Iter> | ||
| _INLINE_VAR constexpr bool _Is_ranges_fwd_iter_v = | ||
| #ifdef __cpp_lib_concepts | ||
| forward_iterator<_Iter> || | ||
| #endif | ||
| _Is_cpp17_fwd_iter_v<_Iter>; | ||
|
|
||
| template <class _Iter> | ||
| _INLINE_VAR constexpr bool _Is_cpp17_bidi_iter_v = is_convertible_v<_Iter_cat_t<_Iter>, bidirectional_iterator_tag>; | ||
|
|
||
| template <class _Iter> | ||
| _INLINE_VAR constexpr bool _Is_bidi_iter_v = is_convertible_v<_Iter_cat_t<_Iter>, bidirectional_iterator_tag>; | ||
| _INLINE_VAR constexpr bool _Is_ranges_bidi_iter_v = | ||
| #ifdef __cpp_lib_concepts | ||
| bidirectional_iterator<_Iter> || | ||
| #endif | ||
| _Is_cpp17_bidi_iter_v<_Iter>; | ||
|
|
||
| template <class _Iter> | ||
| _INLINE_VAR constexpr bool _Is_cpp17_random_iter_v = is_convertible_v<_Iter_cat_t<_Iter>, random_access_iterator_tag>; | ||
|
|
||
| template <class _Iter> | ||
| _INLINE_VAR constexpr bool _Is_random_iter_v = is_convertible_v<_Iter_cat_t<_Iter>, random_access_iterator_tag>; | ||
| _INLINE_VAR constexpr bool _Is_ranges_random_iter_v = | ||
| #if defined(__cpp_lib_concepts) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| random_access_iterator<_Iter> || | ||
| #endif | ||
| _Is_cpp17_random_iter_v<_Iter>; | ||
|
|
||
| #define _REQUIRE_CPP17_MUTABLE_ITERATOR(_Iter) \ | ||
| static_assert(_Is_cpp17_fwd_iter_v<_Iter>, \ | ||
| "Non-ranges algorithms require that mutable iterators be Cpp17ForwardIterators or stronger.") | ||
|
|
||
| template <class, class = void> | ||
| struct _Is_checked_helper {}; // default definition, no longer used, retained due to pseudo-documentation | ||
|
|
@@ -1037,14 +1069,14 @@ template <class _ExPo> | |
| using _Enable_if_execution_policy_t = typename remove_reference_t<_ExPo>::_Standard_execution_policy; | ||
|
|
||
| #define _REQUIRE_PARALLEL_ITERATOR(_Iter) \ | ||
| static_assert(_Is_fwd_iter_v<_Iter>, "Parallel algorithms require forward iterators or stronger.") | ||
| static_assert(_Is_ranges_fwd_iter_v<_Iter>, "Parallel algorithms require forward iterators or stronger.") | ||
|
|
||
| #endif // _HAS_CXX17 | ||
|
|
||
| template <class _Checked, class _Iter> | ||
| _NODISCARD constexpr auto _Idl_distance(const _Iter& _First, const _Iter& _Last) { | ||
| // tries to get the distance between _First and _Last if they are random-access iterators | ||
| if constexpr (_Is_random_iter_v<_Iter>) { | ||
| if constexpr (_Is_ranges_random_iter_v<_Iter>) { | ||
| return static_cast<_Iter_diff_t<_Checked>>(_Last - _First); | ||
| } else { | ||
| return _Distance_unknown{}; | ||
|
|
@@ -1098,7 +1130,7 @@ constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept | |
| template <class _InIt, class _Sentinel, class _Pr> | ||
| constexpr void _Debug_order_unchecked(_InIt _First, _Sentinel _Last, _Pr&& _Pred) { | ||
| // test if range is ordered by predicate | ||
| if constexpr (_Is_fwd_iter_v<_InIt>) { | ||
| if constexpr (_Is_ranges_fwd_iter_v<_InIt>) { | ||
| if (_First != _Last) { | ||
| for (auto _Next = _First; ++_Next != _Last; _First = _Next) { | ||
| _STL_VERIFY(!static_cast<bool>(_Pred(*_Next, *_First)), "sequence not ordered"); | ||
|
|
@@ -1110,7 +1142,7 @@ constexpr void _Debug_order_unchecked(_InIt _First, _Sentinel _Last, _Pr&& _Pred | |
| template <class _OtherIt, class _InIt, class _Pr> | ||
| constexpr void _Debug_order_set_unchecked(_InIt _First, _InIt _Last, _Pr&& _Pred) { | ||
| // test if range is ordered by predicate | ||
| if constexpr (is_same_v<_Iter_value_t<_OtherIt>, _Iter_value_t<_InIt>> && _Is_fwd_iter_v<_InIt>) { | ||
| if constexpr (is_same_v<_Iter_value_t<_OtherIt>, _Iter_value_t<_InIt>>) { | ||
|
strega-nil-ms marked this conversation as resolved.
|
||
| _Debug_order_unchecked(_First, _Last, _Pred); | ||
| } | ||
| } | ||
|
|
@@ -1119,17 +1151,17 @@ constexpr void _Debug_order_set_unchecked(_InIt _First, _InIt _Last, _Pr&& _Pred | |
| // from <iterator> | ||
| template <class _InIt, class _Diff> | ||
| _CONSTEXPR17 void advance(_InIt& _Where, _Diff _Off) { // increment iterator by offset | ||
| if constexpr (_Is_random_iter_v<_InIt>) { | ||
| if constexpr (_Is_ranges_random_iter_v<_InIt>) { | ||
| _Where += _Off; | ||
| } else { | ||
| if constexpr (is_signed_v<_Diff> && !_Is_bidi_iter_v<_InIt>) { | ||
| if constexpr (is_signed_v<_Diff> && !_Is_ranges_bidi_iter_v<_InIt>) { | ||
| _STL_ASSERT(_Off >= 0, "negative advance of non-bidirectional iterator"); | ||
| } | ||
|
|
||
| decltype(auto) _UWhere = _Get_unwrapped_n(_STD move(_Where), _Off); | ||
| constexpr bool _Need_rewrap = !is_reference_v<decltype(_Get_unwrapped_n(_STD move(_Where), _Off))>; | ||
|
|
||
| if constexpr (is_signed_v<_Diff> && _Is_bidi_iter_v<_InIt>) { | ||
| if constexpr (is_signed_v<_Diff> && _Is_ranges_bidi_iter_v<_InIt>) { | ||
| for (; _Off < 0; ++_Off) { | ||
| --_UWhere; | ||
| } | ||
|
|
@@ -1147,7 +1179,7 @@ _CONSTEXPR17 void advance(_InIt& _Where, _Diff _Off) { // increment iterator by | |
|
|
||
| template <class _InIt> | ||
| _NODISCARD _CONSTEXPR17 _Iter_diff_t<_InIt> distance(_InIt _First, _InIt _Last) { | ||
| if constexpr (_Is_random_iter_v<_InIt>) { | ||
| if constexpr (_Is_ranges_random_iter_v<_InIt>) { | ||
| return _Last - _First; // assume the iterator will do debug checking | ||
| } else { | ||
| _Adl_verify_range(_First, _Last); | ||
|
|
@@ -1169,7 +1201,7 @@ constexpr _InIt _Next_iter(_InIt _First) { // increment iterator | |
|
|
||
| template <class _InIt> | ||
| _NODISCARD _CONSTEXPR17 _InIt next(_InIt _First, _Iter_diff_t<_InIt> _Off = 1) { // increment iterator | ||
| static_assert(_Is_input_iter_v<_InIt>, "next requires input iterator"); | ||
| static_assert(_Is_ranges_input_iter_v<_InIt>, "next requires input iterator"); | ||
|
|
||
| _STD advance(_First, _Off); | ||
| return _First; | ||
|
|
@@ -1182,7 +1214,7 @@ constexpr _BidIt _Prev_iter(_BidIt _First) { // decrement iterator | |
|
|
||
| template <class _BidIt> | ||
| _NODISCARD _CONSTEXPR17 _BidIt prev(_BidIt _First, _Iter_diff_t<_BidIt> _Off = 1) { // decrement iterator | ||
| static_assert(_Is_bidi_iter_v<_BidIt>, "prev requires bidirectional iterator"); | ||
| static_assert(_Is_ranges_bidi_iter_v<_BidIt>, "prev requires bidirectional iterator"); | ||
|
strega-nil-ms marked this conversation as resolved.
|
||
|
|
||
| _STD advance(_First, -_Off); | ||
| return _First; | ||
|
|
@@ -3688,7 +3720,7 @@ _FwdIt2 copy(_ExPo&&, _FwdIt1 _First, _FwdIt1 _Last, _FwdIt2 _Dest) noexcept /* | |
| // copy [_First, _Last) to [_Dest, ...) | ||
| // not parallelized as benchmarks show it isn't worth it | ||
| _REQUIRE_PARALLEL_ITERATOR(_FwdIt1); | ||
| _REQUIRE_PARALLEL_ITERATOR(_FwdIt2); | ||
| _REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt2); | ||
| return _STD copy(_First, _Last, _Dest); | ||
| } | ||
| #endif // _HAS_CXX17 | ||
|
|
@@ -3828,7 +3860,7 @@ _FwdIt2 copy_n(_ExPo&&, _FwdIt1 _First, _Diff _Count_raw, _FwdIt2 _Dest) noexcep | |
| // copy [_First, _First + _Count) to [_Dest, ...) | ||
| // not parallelized as benchmarks show it isn't worth it | ||
| _REQUIRE_PARALLEL_ITERATOR(_FwdIt1); | ||
| _REQUIRE_PARALLEL_ITERATOR(_FwdIt2); | ||
| _REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt2); | ||
| return _STD copy_n(_First, _Count_raw, _Dest); | ||
| } | ||
| #endif // _HAS_CXX17 | ||
|
|
@@ -3922,8 +3954,8 @@ template <class _ExPo, class _FwdIt1, class _FwdIt2, _Enable_if_execution_policy | |
| _FwdIt2 move(_ExPo&&, _FwdIt1 _First, _FwdIt1 _Last, _FwdIt2 _Dest) noexcept /* terminates */ { | ||
| // move [_First, _Last) to [_Dest, ...) | ||
| // not parallelized as benchmarks show it isn't worth it | ||
| _REQUIRE_PARALLEL_ITERATOR(_FwdIt1); | ||
| _REQUIRE_PARALLEL_ITERATOR(_FwdIt2); | ||
| _REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt1); | ||
| _REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt2); | ||
| return _STD move(_First, _Last, _Dest); | ||
| } | ||
| #endif // _HAS_CXX17 | ||
|
|
@@ -4068,7 +4100,7 @@ template <class _ExPo, class _FwdIt, class _Ty, _Enable_if_execution_policy_t<_E | |
| void fill(_ExPo&&, _FwdIt _First, _FwdIt _Last, const _Ty& _Val) noexcept /* terminates */ { | ||
| // copy _Val through [_First, _Last) | ||
| // not parallelized as benchmarks show it isn't worth it | ||
| _REQUIRE_PARALLEL_ITERATOR(_FwdIt); | ||
| _REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt); | ||
| return _STD fill(_First, _Last, _Val); | ||
| } | ||
| #endif // _HAS_CXX17 | ||
|
|
@@ -4116,7 +4148,7 @@ template <class _ExPo, class _FwdIt, class _Diff, class _Ty, _Enable_if_executio | |
| _FwdIt fill_n(_ExPo&&, _FwdIt _Dest, _Diff _Count_raw, const _Ty& _Val) noexcept /* terminates */ { | ||
| // copy _Val _Count times through [_Dest, ...) | ||
| // not parallelized as benchmarks show it isn't worth it | ||
| _REQUIRE_PARALLEL_ITERATOR(_FwdIt); | ||
| _REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt); | ||
| return _STD fill_n(_Dest, _Count_raw, _Val); | ||
| } | ||
| #endif // _HAS_CXX17 | ||
|
|
@@ -4315,7 +4347,7 @@ _NODISCARD _CONSTEXPR20 bool equal( | |
| const auto _ULast1 = _Get_unwrapped(_Last1); | ||
| auto _UFirst2 = _Get_unwrapped(_First2); | ||
| const auto _ULast2 = _Get_unwrapped(_Last2); | ||
| if constexpr (_Is_random_iter_v<_InIt1> && _Is_random_iter_v<_InIt2>) { | ||
| if constexpr (_Is_ranges_random_iter_v<_InIt1> && _Is_ranges_random_iter_v<_InIt2>) { | ||
| if (_ULast1 - _UFirst1 != _ULast2 - _UFirst2) { | ||
| return false; | ||
| } | ||
|
|
@@ -5119,7 +5151,7 @@ _NODISCARD _CONSTEXPR20 bool _Check_match_counts( | |
| // test if [_First1, _Last1) == permuted [_First2, _Last2), after matching prefix removal | ||
| _STL_INTERNAL_CHECK(!_Pred(*_First1, *_First2)); | ||
| _STL_INTERNAL_CHECK(_STD distance(_First1, _Last1) == _STD distance(_First2, _Last2)); | ||
| if constexpr (_Is_bidi_iter_v<_FwdIt1> && _Is_bidi_iter_v<_FwdIt2>) { | ||
| if constexpr (_Is_ranges_bidi_iter_v<_FwdIt1> && _Is_ranges_bidi_iter_v<_FwdIt2>) { | ||
| do { // find last inequality | ||
| --_Last1; | ||
| --_Last2; | ||
|
|
@@ -5232,12 +5264,12 @@ _CONSTEXPR20 _FwdIt rotate(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last) { | |
| return _First; | ||
| } | ||
|
|
||
| if constexpr (_Is_random_iter_v<_FwdIt>) { | ||
| if constexpr (_Is_cpp17_random_iter_v<_FwdIt>) { | ||
| _STD reverse(_UFirst, _UMid); | ||
| _STD reverse(_UMid, _ULast); | ||
| _STD reverse(_UFirst, _ULast); | ||
| _Seek_wrapped(_First, _UFirst + (_ULast - _UMid)); | ||
| } else if constexpr (_Is_bidi_iter_v<_FwdIt>) { | ||
| } else if constexpr (_Is_cpp17_bidi_iter_v<_FwdIt>) { | ||
| _STD reverse(_UFirst, _UMid); | ||
| _STD reverse(_UMid, _ULast); | ||
| auto _Tmp = _Reverse_until_sentinel_unchecked(_UFirst, _UMid, _ULast); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -270,6 +270,7 @@ | |
| // P2367R0 Remove Misuses Of List-Initialization From Clause 24 Ranges | ||
| // P2372R3 Fixing Locale Handling In chrono Formatters | ||
| // P2393R1 Cleaning Up Integer-Class Types | ||
| // P2408R5 Ranges Iterators As Inputs To Non-Ranges Algorithms | ||
| // P2415R2 What Is A view? | ||
| // P2418R2 Add Support For std::generator-like Types To std::format | ||
| // P2432R1 Fix istream_view | ||
|
|
@@ -1349,6 +1350,14 @@ | |
| #endif // __cpp_impl_coroutine | ||
|
|
||
| #if _HAS_CXX20 | ||
|
strega-nil-ms marked this conversation as resolved.
strega-nil-ms marked this conversation as resolved.
|
||
| #if !defined(__EDG__) || defined(__INTELLISENSE__) // TRANSITION, EDG concepts support | ||
| #define __cpp_lib_concepts 202002L | ||
| #endif // !defined(__EDG__) || defined(__INTELLISENSE__) | ||
|
|
||
| #if defined(__cpp_lib_concepts) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto |
||
| #define __cpp_lib_algorithm_iterator_requirements 202207L | ||
|
strega-nil-ms marked this conversation as resolved.
|
||
| #endif | ||
|
|
||
|
strega-nil-ms marked this conversation as resolved.
|
||
| #define __cpp_lib_assume_aligned 201811L | ||
| #define __cpp_lib_atomic_flag_test 201907L | ||
| #define __cpp_lib_atomic_float 201711L | ||
|
|
@@ -1362,10 +1371,6 @@ | |
| #define __cpp_lib_bitops 201907L | ||
| #define __cpp_lib_bounded_array_traits 201902L | ||
|
|
||
| #if !defined(__EDG__) || defined(__INTELLISENSE__) // TRANSITION, EDG concepts support | ||
| #define __cpp_lib_concepts 202002L | ||
| #endif // !defined(__EDG__) || defined(__INTELLISENSE__) | ||
|
|
||
| #define __cpp_lib_constexpr_algorithms 201806L | ||
| #define __cpp_lib_constexpr_complex 201711L | ||
| #define __cpp_lib_constexpr_dynamic_alloc 201907L | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Copyright (c) Microsoft Corporation. | ||
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
|
||
| RUNALL_INCLUDE ..\strict_concepts_20_matrix.lst |
Uh oh!
There was an error while loading. Please reload this page.