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

Consistent iterator type checking for parallel algorithms #3899

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
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
26 changes: 21 additions & 5 deletions stl/inc/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ _STD pair<_Ty*, _Ty*> __std_minmax_element(_Ty* _First, _Ty* _Last) noexcept {
#endif // _USE_STD_VECTOR_ALGORITHMS

_STD_BEGIN
#define _REQUIRE_CPP17_MUTABLE_RANDOM_ACCESS_ITERATOR(_Iter) \
static_assert(_Is_cpp17_random_iter_v<_Iter>, \
"This algorithm requires that mutable iterators be Cpp17RandomAccessIterators or stronger.")

_INLINE_VAR constexpr int _ISORT_MAX = 32; // maximum size for insertion sort

template <class _It>
Expand Down Expand Up @@ -581,8 +585,6 @@ _EXPORT_STD template <class _ExPo, class _FwdIt1, class _FwdIt2, _Enable_if_exec
_NODISCARD pair<_FwdIt1, _FwdIt2> mismatch(
_ExPo&& _Exec, const _FwdIt1 _First1, const _FwdIt1 _Last1, const _FwdIt2 _First2) noexcept /* terminates */ {
// return [_First1, _Last1)/[_First2, ...) mismatch
_REQUIRE_PARALLEL_ITERATOR(_FwdIt1);
_REQUIRE_PARALLEL_ITERATOR(_FwdIt2);
return _STD mismatch(_STD forward<_ExPo>(_Exec), _First1, _Last1, _First2, equal_to{});
}
#endif // _HAS_CXX17
Expand Down Expand Up @@ -636,8 +638,6 @@ _EXPORT_STD template <class _ExPo, class _FwdIt1, class _FwdIt2, _Enable_if_exec
_NODISCARD pair<_FwdIt1, _FwdIt2> mismatch(
_ExPo&& _Exec, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _FwdIt2 _Last2) noexcept /* terminates */ {
// return [_First1, _Last1)/[_First2, _Last2) mismatch
_REQUIRE_PARALLEL_ITERATOR(_FwdIt1);
_REQUIRE_PARALLEL_ITERATOR(_FwdIt2);
return _STD mismatch(_STD forward<_ExPo>(_Exec), _First1, _Last1, _First2, _Last2, equal_to{});
}
#endif // _HAS_CXX17
Expand Down Expand Up @@ -3432,6 +3432,8 @@ _EXPORT_STD template <class _ExPo, class _FwdIt1, class _FwdIt2, _Enable_if_exec
_FwdIt2 swap_ranges(_ExPo&&, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _Dest) noexcept /* terminates */ {
// swap [_First1, _Last1) with [_Dest, ...)
// not parallelized as benchmarks show it isn't worth it
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt1);
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt2);
return _STD swap_ranges(_First1, _Last1, _Dest);
}
#endif // _HAS_CXX17
Expand Down Expand Up @@ -4055,6 +4057,7 @@ _EXPORT_STD template <class _ExPo, class _FwdIt, class _Fn, _Enable_if_execution
void generate(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Fn _Func) noexcept /* terminates */ {
// replace [_First, _Last) with _Func()
// not parallelized at present due to unclear parallelism requirements on _Func
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt);
return _STD generate(_First, _Last, _Pass_fn(_Func));
}
#endif // _HAS_CXX17
Expand Down Expand Up @@ -4418,13 +4421,15 @@ _EXPORT_STD template <class _ExPo, class _FwdIt, class _Pr, _Enable_if_execution
_NODISCARD_UNIQUE_ALG _FwdIt unique(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Pr _Pred) noexcept /* terminates */ {
// remove each satisfying _Pred with previous
// not parallelized at present, parallelism expected to be feasible in a future release
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt);
return _STD unique(_First, _Last, _Pass_fn(_Pred));
}

_EXPORT_STD template <class _ExPo, class _FwdIt, _Enable_if_execution_policy_t<_ExPo> = 0>
_NODISCARD_UNIQUE_ALG _FwdIt unique(_ExPo&&, _FwdIt _First, _FwdIt _Last) noexcept /* terminates */ {
// remove each matching previous
// not parallelized at present, parallelism expected to be feasible in a future release
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt);
return _STD unique(_First, _Last);
}
#endif // _HAS_CXX17
Expand Down Expand Up @@ -4805,7 +4810,7 @@ _EXPORT_STD template <class _ExPo, class _BidIt, class _FwdIt, _Enable_if_execut
_FwdIt reverse_copy(_ExPo&&, _BidIt _First, _BidIt _Last, _FwdIt _Dest) noexcept /* terminates */ {
// copy reversing elements in [_First, _Last)
// not parallelized as benchmarks show it isn't worth it
_REQUIRE_PARALLEL_ITERATOR(_BidIt);
static_assert(_Is_ranges_bidi_iter_v<_BidIt>, "This algorithm requires bidirectional iterators or stronger.");
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt);
return _STD reverse_copy(_First, _Last, _Dest);
}
Expand Down Expand Up @@ -5498,6 +5503,7 @@ _EXPORT_STD template <class _ExPo, class _FwdIt, _Enable_if_execution_policy_t<_
_FwdIt shift_left(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Iter_diff_t<_FwdIt> _Pos_to_shift) noexcept /* terminates */ {
// shift [_First, _Last) left by _Pos_to_shift positions
// not parallelized as benchmarks show it isn't worth it
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt);
return _STD shift_left(_First, _Last, _Pos_to_shift);
}

Expand Down Expand Up @@ -5579,6 +5585,7 @@ _EXPORT_STD template <class _ExPo, class _FwdIt, _Enable_if_execution_policy_t<_
_FwdIt shift_right(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Iter_diff_t<_FwdIt> _Pos_to_shift) noexcept /* terminates */ {
// shift [_First, _Last) right by _Pos_to_shift positions
// not parallelized as benchmarks show it isn't worth it
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt);
return _STD shift_right(_First, _Last, _Pos_to_shift);
}
#endif // _HAS_CXX20
Expand Down Expand Up @@ -6121,6 +6128,7 @@ _EXPORT_STD template <class _ExPo, class _BidIt, class _Pr, _Enable_if_execution
_BidIt stable_partition(_ExPo&&, _BidIt _First, _BidIt _Last, _Pr _Pred) noexcept /* terminates */ {
// partition preserving order of equivalents
// not parallelized at present, parallelism expected to be feasible in a future release
_REQUIRE_CPP17_MUTABLE_BIDIRECTIONAL_ITERATOR(_BidIt);
return _STD stable_partition(_First, _Last, _Pass_fn(_Pred));
}
#endif // _HAS_CXX17
Expand Down Expand Up @@ -7572,13 +7580,15 @@ _EXPORT_STD template <class _ExPo, class _BidIt, class _Pr, _Enable_if_execution
void inplace_merge(_ExPo&&, _BidIt _First, _BidIt _Mid, _BidIt _Last, _Pr _Pred) noexcept /* terminates */ {
// merge [_First, _Mid) with [_Mid, _Last)
// not parallelized at present, parallelism expected to be feasible in a future release
_REQUIRE_CPP17_MUTABLE_BIDIRECTIONAL_ITERATOR(_BidIt);
_STD inplace_merge(_First, _Mid, _Last, _Pass_fn(_Pred));
}

_EXPORT_STD template <class _ExPo, class _BidIt, _Enable_if_execution_policy_t<_ExPo> = 0>
void inplace_merge(_ExPo&&, _BidIt _First, _BidIt _Mid, _BidIt _Last) noexcept /* terminates */ {
// merge [_First, _Mid) with [_Mid, _Last)
// not parallelized at present, parallelism expected to be feasible in a future release
_REQUIRE_CPP17_MUTABLE_BIDIRECTIONAL_ITERATOR(_BidIt);
_STD inplace_merge(_First, _Mid, _Last);
}
#endif // _HAS_CXX17
Expand Down Expand Up @@ -8784,13 +8794,15 @@ _EXPORT_STD template <class _ExPo, class _RanIt, class _Pr, _Enable_if_execution
void partial_sort(_ExPo&&, _RanIt _First, _RanIt _Mid, _RanIt _Last, _Pr _Pred) noexcept /* terminates */ {
// order [_First, _Last) up to _Mid
// parallelism suspected to be infeasible
_REQUIRE_CPP17_MUTABLE_RANDOM_ACCESS_ITERATOR(_RanIt);
return _STD partial_sort(_First, _Mid, _Last, _Pass_fn(_Pred));
}

_EXPORT_STD template <class _ExPo, class _RanIt, _Enable_if_execution_policy_t<_ExPo> = 0>
void partial_sort(_ExPo&&, _RanIt _First, _RanIt _Mid, _RanIt _Last) noexcept /* terminates */ {
// order [_First, _Last) up to _Mid
// parallelism suspected to be infeasible
_REQUIRE_CPP17_MUTABLE_RANDOM_ACCESS_ITERATOR(_RanIt);
return _STD partial_sort(_First, _Mid, _Last);
}

Expand Down Expand Up @@ -9054,13 +9066,15 @@ _EXPORT_STD template <class _ExPo, class _RanIt, class _Pr, _Enable_if_execution
void nth_element(_ExPo&&, _RanIt _First, _RanIt _Nth, _RanIt _Last, _Pr _Pred) noexcept /* terminates */ {
// order Nth element
// not parallelized at present, parallelism expected to be feasible in a future release
_REQUIRE_CPP17_MUTABLE_RANDOM_ACCESS_ITERATOR(_RanIt);
_STD nth_element(_First, _Nth, _Last, _Pass_fn(_Pred));
}

_EXPORT_STD template <class _ExPo, class _RanIt, _Enable_if_execution_policy_t<_ExPo> = 0>
void nth_element(_ExPo&&, _RanIt _First, _RanIt _Nth, _RanIt _Last) noexcept /* terminates */ {
// order Nth element
// not parallelized at present, parallelism expected to be feasible in a future release
_REQUIRE_CPP17_MUTABLE_RANDOM_ACCESS_ITERATOR(_RanIt);
_STD nth_element(_First, _Nth, _Last);
}

Expand Down Expand Up @@ -9894,13 +9908,15 @@ _NODISCARD pair<_FwdIt, _FwdIt> minmax_element(_ExPo&&, _FwdIt _First, _FwdIt _L
/* terminates */ {
// find smallest and largest elements
// not parallelized at present, parallelism expected to be feasible in a future release
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
return _STD minmax_element(_First, _Last, _Pass_fn(_Pred));
}

_EXPORT_STD template <class _ExPo, class _FwdIt, _Enable_if_execution_policy_t<_ExPo> = 0>
_NODISCARD pair<_FwdIt, _FwdIt> minmax_element(_ExPo&&, _FwdIt _First, _FwdIt _Last) noexcept /* terminates */ {
// find smallest and largest elements
// not parallelized at present, parallelism expected to be feasible in a future release
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
return _STD minmax_element(_First, _Last);
}

Expand Down
6 changes: 6 additions & 0 deletions stl/inc/execution
Original file line number Diff line number Diff line change
Expand Up @@ -1653,6 +1653,7 @@ struct _Static_partitioned_adjacent_find3 {
_EXPORT_STD template <class _ExPo, class _FwdIt, class _Pr, _Enable_if_execution_policy_t<_ExPo> /* = 0 */>
_NODISCARD _FwdIt adjacent_find(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Pr _Pred) noexcept /* terminates */ {
// find first satisfying _Pred with successor
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
Expand Down Expand Up @@ -2247,6 +2248,7 @@ _EXPORT_STD template <class _ExPo, class _FwdIt, class _Diff, class _Ty, class _
_NODISCARD _FwdIt search_n(_ExPo&&, const _FwdIt _First, _FwdIt _Last, const _Diff _Count_raw, const _Ty& _Val,
_Pr _Pred) noexcept /* terminates */ {
// find first _Count * _Val satisfying _Pred
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
const _Algorithm_int_t<_Diff> _Count = _Count_raw;
if (_Count <= 0) {
_Last = _First;
Expand Down Expand Up @@ -2584,6 +2586,7 @@ _EXPORT_STD template <class _ExPo, class _FwdIt, class _Pr, _Enable_if_execution
_NODISCARD_REMOVE_ALG _FwdIt remove_if(_ExPo&&, _FwdIt _First, const _FwdIt _Last, _Pr _Pred) noexcept
/* terminates */ {
// remove each satisfying _Pred
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt);
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
Expand Down Expand Up @@ -2722,6 +2725,7 @@ struct _Sort_operation { // context for background threads
_EXPORT_STD template <class _ExPo, class _RanIt, class _Pr, _Enable_if_execution_policy_t<_ExPo> /* = 0 */>
void sort(_ExPo&&, const _RanIt _First, const _RanIt _Last, _Pr _Pred) noexcept /* terminates */ {
// order [_First, _Last)
_REQUIRE_CPP17_MUTABLE_RANDOM_ACCESS_ITERATOR(_RanIt);
_Adl_verify_range(_First, _Last);
const auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
Expand Down Expand Up @@ -2979,6 +2983,7 @@ struct _Static_partitioned_stable_sort3 {
_EXPORT_STD template <class _ExPo, class _BidIt, class _Pr, _Enable_if_execution_policy_t<_ExPo> /* = 0 */>
void stable_sort(_ExPo&&, const _BidIt _First, const _BidIt _Last, _Pr _Pred) noexcept /* terminates */ {
// sort preserving order of equivalents
_REQUIRE_CPP17_MUTABLE_BIDIRECTIONAL_ITERATOR(_BidIt);
_Adl_verify_range(_First, _Last);
const auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
Expand Down Expand Up @@ -3541,6 +3546,7 @@ struct _Static_partitioned_partition2 {
_EXPORT_STD template <class _ExPo, class _FwdIt, class _Pr, _Enable_if_execution_policy_t<_ExPo> /* = 0 */>
_FwdIt partition(_ExPo&&, _FwdIt _First, const _FwdIt _Last, _Pr _Pred) noexcept /* terminates */ {
// move elements satisfying _Pred to beginning of sequence
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt);
_Adl_verify_range(_First, _Last);
const auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
Expand Down
4 changes: 0 additions & 4 deletions stl/inc/numeric
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ _NODISCARD _Ty reduce(_ExPo&& _Exec, _FwdIt _First, _FwdIt _Last, _Ty _Val, _Bin
_EXPORT_STD template <class _ExPo, class _FwdIt, class _Ty, _Enable_if_execution_policy_t<_ExPo> = 0>
_NODISCARD _Ty reduce(_ExPo&& _Exec, const _FwdIt _First, const _FwdIt _Last, _Ty _Val) noexcept /* terminates */ {
// return commutative and associative reduction of _Val and [_First, _Last)
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
return _STD reduce(_STD forward<_ExPo>(_Exec), _First, _Last, _STD move(_Val), plus{});
}

Expand All @@ -121,7 +120,6 @@ _NODISCARD _Iter_value_t<_FwdIt> reduce(_ExPo&& _Exec, const _FwdIt _First, cons
/* terminates */ {
// return commutative and associative reduction of
// iterator_traits<_FwdIt>::value_type{} and [_First, _Last)
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
return _STD reduce(_STD forward<_ExPo>(_Exec), _First, _Last, _Iter_value_t<_FwdIt>{}, plus{});
}
#endif // _HAS_CXX17
Expand Down Expand Up @@ -232,8 +230,6 @@ _EXPORT_STD template <class _ExPo, class _FwdIt1, class _FwdIt2, class _Ty, _Ena
_NODISCARD _Ty transform_reduce(_ExPo&& _Exec, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _Ty _Val) noexcept
/* terminates */ {
// return commutative and associative transform-reduction of sequences
_REQUIRE_PARALLEL_ITERATOR(_FwdIt1);
_REQUIRE_PARALLEL_ITERATOR(_FwdIt2);
return _STD transform_reduce(
_STD forward<_ExPo>(_Exec), _First1, _Last1, _First2, _STD move(_Val), plus{}, multiplies{});
}
Expand Down
10 changes: 10 additions & 0 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,10 @@ _INLINE_VAR constexpr bool _Is_ranges_random_iter_v =
static_assert(_Is_cpp17_fwd_iter_v<_Iter>, \
"Non-ranges algorithms require that mutable iterators be Cpp17ForwardIterators or stronger.")

#define _REQUIRE_CPP17_MUTABLE_BIDIRECTIONAL_ITERATOR(_Iter) \
static_assert(_Is_cpp17_bidi_iter_v<_Iter>, \
"This algorithm requires that mutable iterators be Cpp17BidirectionalIterators or stronger.")

template <class, class = void>
struct _Is_checked_helper {}; // default definition, no longer used, retained due to pseudo-documentation

Expand Down Expand Up @@ -6211,6 +6215,7 @@ _EXPORT_STD template <class _ExPo, class _BidIt, _Enable_if_execution_policy_t<_
void reverse(_ExPo&&, _BidIt _First, _BidIt _Last) noexcept /* terminates */ {
// reverse elements in [_First, _Last)
// not parallelized as benchmarks show it isn't worth it
_REQUIRE_CPP17_MUTABLE_BIDIRECTIONAL_ITERATOR(_BidIt);
return _STD reverse(_First, _Last);
}
#endif // _HAS_CXX17
Expand Down Expand Up @@ -6287,6 +6292,7 @@ _EXPORT_STD template <class _ExPo, class _FwdIt, _Enable_if_execution_policy_t<_
_FwdIt rotate(_ExPo&&, _FwdIt _First, _FwdIt _Mid, _FwdIt _Last) noexcept /* terminates */ {
// rotate [_First, _Last) left by distance(_First, _Mid) positions
// not parallelized as benchmarks show it isn't worth it
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt);
return _STD rotate(_First, _Mid, _Last);
}
#endif // _HAS_CXX17
Expand Down Expand Up @@ -6674,13 +6680,15 @@ _EXPORT_STD template <class _ExPo, class _FwdIt, class _Pr, _Enable_if_execution
_NODISCARD _FwdIt max_element(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Pr _Pred) noexcept /* terminates */ {
// find largest element
// not parallelized at present, parallelism expected to be feasible in a future release
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
return _STD max_element(_First, _Last, _Pass_fn(_Pred));
}

_EXPORT_STD template <class _ExPo, class _FwdIt, _Enable_if_execution_policy_t<_ExPo> = 0>
_NODISCARD _FwdIt max_element(_ExPo&&, _FwdIt _First, _FwdIt _Last) noexcept /* terminates */ {
// find largest element
// not parallelized at present, parallelism expected to be feasible in a future release
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
return _STD max_element(_First, _Last);
}

Expand Down Expand Up @@ -6868,13 +6876,15 @@ _EXPORT_STD template <class _ExPo, class _FwdIt, class _Pr, _Enable_if_execution
_NODISCARD _FwdIt min_element(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Pr _Pred) noexcept /* terminates */ {
// find smallest element
// not parallelized at present, parallelism expected to be feasible in a future release
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
return _STD min_element(_First, _Last, _Pass_fn(_Pred));
}

_EXPORT_STD template <class _ExPo, class _FwdIt, _Enable_if_execution_policy_t<_ExPo> = 0>
_NODISCARD _FwdIt min_element(_ExPo&&, _FwdIt _First, _FwdIt _Last) noexcept /* terminates */ {
// find smallest element
// not parallelized at present, parallelism expected to be feasible in a future release
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
return _STD min_element(_First, _Last);
}

Expand Down