ADL-proof implementation of algorithms in [alg.nonmodifying] (#4138)

Co-authored-by: Michael Schellenberger Costa <mschellenbergercosta@googlemail.com>
Co-authored-by: Stephan T. Lavavej <stl@microsoft.com>
This commit is contained in:
A. Jiang 2023-11-11 02:36:32 +08:00 коммит произвёл GitHub
Родитель bc5a5c3496
Коммит 1e46514fbb
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 1078 добавлений и 647 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1000,7 +1000,7 @@ struct _Atomic_storage<_Ty, 4> { // lock-free using 4-byte intrinsics
}
_NODISCARD _TVal load(const memory_order _Order) const noexcept { // load with given memory order
const auto _Mem = _Atomic_address_as<int>(_Storage);
const auto _Mem = _STD _Atomic_address_as<int>(_Storage);
int _As_bytes;
#if _STD_ATOMIC_USE_ARM64_LDAR_STLR == 1
_ATOMIC_LOAD_ARM64(_As_bytes, 32, _Mem, static_cast<unsigned int>(_Order))
@ -1021,16 +1021,17 @@ struct _Atomic_storage<_Ty, 4> { // lock-free using 4-byte intrinsics
bool compare_exchange_strong(_TVal& _Expected, const _TVal _Desired,
const memory_order _Order = memory_order_seq_cst) noexcept { // CAS with given memory order
long _Expected_bytes = _Atomic_reinterpret_as<long>(_Expected); // read before atomic operation
long _Expected_bytes = _STD _Atomic_reinterpret_as<long>(_Expected); // read before atomic operation
long _Prev_bytes;
#if _CMPXCHG_MASK_OUT_PADDING_BITS
if constexpr (_Might_have_non_value_bits<_TVal>) {
_Storage_for<_TVal> _Mask{_Form_mask};
const long _Mask_val = _Atomic_reinterpret_as<long>(_Mask);
const long _Mask_val = _STD _Atomic_reinterpret_as<long>(_Mask);
for (;;) {
_ATOMIC_CHOOSE_INTRINSIC(static_cast<unsigned int>(_Order), _Prev_bytes, _InterlockedCompareExchange,
_Atomic_address_as<long>(_Storage), _Atomic_reinterpret_as<long>(_Desired), _Expected_bytes);
_STD _Atomic_address_as<long>(_Storage), _STD _Atomic_reinterpret_as<long>(_Desired),
_Expected_bytes);
if (_Prev_bytes == _Expected_bytes) {
return true;
}
@ -1044,7 +1045,7 @@ struct _Atomic_storage<_Ty, 4> { // lock-free using 4-byte intrinsics
}
#endif // _CMPXCHG_MASK_OUT_PADDING_BITS
_ATOMIC_CHOOSE_INTRINSIC(static_cast<unsigned int>(_Order), _Prev_bytes, _InterlockedCompareExchange,
_Atomic_address_as<long>(_Storage), _Atomic_reinterpret_as<long>(_Desired), _Expected_bytes);
_STD _Atomic_address_as<long>(_Storage), _STD _Atomic_reinterpret_as<long>(_Desired), _Expected_bytes);
if (_Prev_bytes == _Expected_bytes) {
return true;
}
@ -1111,7 +1112,7 @@ struct _Atomic_storage<_Ty, 8> { // lock-free using 8-byte intrinsics
}
_NODISCARD _TVal load(const memory_order _Order) const noexcept { // load with given memory order
const auto _Mem = _Atomic_address_as<long long>(_Storage);
const auto _Mem = _STD _Atomic_address_as<long long>(_Storage);
long long _As_bytes;
#if _STD_ATOMIC_USE_ARM64_LDAR_STLR == 1
_ATOMIC_LOAD_ARM64(_As_bytes, 64, _Mem, static_cast<unsigned int>(_Order))
@ -1149,17 +1150,17 @@ struct _Atomic_storage<_Ty, 8> { // lock-free using 8-byte intrinsics
bool compare_exchange_strong(_TVal& _Expected, const _TVal _Desired,
const memory_order _Order = memory_order_seq_cst) noexcept { // CAS with given memory order
long long _Expected_bytes = _Atomic_reinterpret_as<long long>(_Expected); // read before atomic operation
long long _Expected_bytes = _STD _Atomic_reinterpret_as<long long>(_Expected); // read before atomic operation
long long _Prev_bytes;
#if _CMPXCHG_MASK_OUT_PADDING_BITS
if constexpr (_Might_have_non_value_bits<_TVal>) {
_Storage_for<_TVal> _Mask{_Form_mask};
const long long _Mask_val = _Atomic_reinterpret_as<long long>(_Mask);
const long long _Mask_val = _STD _Atomic_reinterpret_as<long long>(_Mask);
for (;;) {
_ATOMIC_CHOOSE_INTRINSIC(static_cast<unsigned int>(_Order), _Prev_bytes, _InterlockedCompareExchange64,
_Atomic_address_as<long long>(_Storage), _Atomic_reinterpret_as<long long>(_Desired),
_STD _Atomic_address_as<long long>(_Storage), _STD _Atomic_reinterpret_as<long long>(_Desired),
_Expected_bytes);
if (_Prev_bytes == _Expected_bytes) {
return true;
@ -1174,7 +1175,8 @@ struct _Atomic_storage<_Ty, 8> { // lock-free using 8-byte intrinsics
}
#endif // _CMPXCHG_MASK_OUT_PADDING_BITS
_ATOMIC_CHOOSE_INTRINSIC(static_cast<unsigned int>(_Order), _Prev_bytes, _InterlockedCompareExchange64,
_Atomic_address_as<long long>(_Storage), _Atomic_reinterpret_as<long long>(_Desired), _Expected_bytes);
_STD _Atomic_address_as<long long>(_Storage), _STD _Atomic_reinterpret_as<long long>(_Desired),
_Expected_bytes);
if (_Prev_bytes == _Expected_bytes) {
return true;
}

Просмотреть файл

@ -181,7 +181,7 @@ class _Work_ptr {
public:
template <class _Work, enable_if_t<!is_same_v<remove_cv_t<_Work>, _Work_ptr>, int> = 0>
explicit _Work_ptr(_Work& _Operation)
: _Ptp_work(__std_create_threadpool_work(&_Work::_Threadpool_callback, _STD addressof(_Operation), nullptr)) {
: _Ptp_work(::__std_create_threadpool_work(&_Work::_Threadpool_callback, _STD addressof(_Operation), nullptr)) {
// register work with the thread pool
// usually, after _Work_ptr is constructed, a parallel algorithm runs to completion or terminates
static_assert(noexcept(_Work::_Threadpool_callback(_STD declval<__std_PTP_CALLBACK_INSTANCE>(),
@ -229,7 +229,7 @@ void _Run_chunked_parallel_work(const size_t _Hw_threads, _Work& _Operation) {
const _Work_ptr _Work_op{_Operation};
// setup complete, hereafter nothrow or terminate
_Work_op._Submit_for_chunks(_Hw_threads, _Operation._Team._Chunks);
_Run_available_chunked_work(_Operation);
_STD _Run_available_chunked_work(_Operation);
}
// The parallel algorithms library below assumes that distance(first, last) fits into a size_t;
@ -840,15 +840,15 @@ struct _Static_partition_range<_RanIt, _Diff, true> {
// statically partition a random-access iterator range and return next(_First, _Team._Count)
// pre: _Populate hasn't yet been called on this instance
auto _Result = _First + static_cast<_Target_diff>(_Team._Count); // does verification
_Start_at = _Get_unwrapped(_First);
_Start_at = _STD _Get_unwrapped(_First);
return _Result;
}
bool _Populate(const _Static_partition_team<_Diff>& _Team, _RanIt _First, _RanIt _Last) {
// statically partition a random-access iterator range and check if the range ends at _Last
// pre: _Populate hasn't yet been called on this instance
_Adl_verify_range(_First, _Last);
_Start_at = _Get_unwrapped(_First);
_STD _Adl_verify_range(_First, _Last);
_Start_at = _STD _Get_unwrapped(_First);
return _Team._Count == _Last - _First;
}
@ -883,16 +883,16 @@ struct _Static_partition_range<_FwdIt, _Diff, false> {
const auto _Chunk_size = static_cast<_Target_diff>(_Team._Chunk_size);
const auto _Unchunked_items = _Team._Unchunked_items;
auto _Result = _Division_points.begin();
*_Result = _Get_unwrapped(_First);
*_Result = _STD _Get_unwrapped(_First);
for (_Diff _Idx{}; _Idx < _Unchunked_items; ++_Idx) { // record bounds of chunks with an extra item
_STD advance(_First, static_cast<_Target_diff>(_Chunk_size + 1));
*++_Result = _Get_unwrapped(_First);
*++_Result = _STD _Get_unwrapped(_First);
}
const auto _Diff_chunks = static_cast<_Diff>(_Chunks);
for (_Diff _Idx = _Unchunked_items; _Idx < _Diff_chunks; ++_Idx) { // record bounds of chunks with no extra item
_STD advance(_First, _Chunk_size);
*++_Result = _Get_unwrapped(_First);
*++_Result = _STD _Get_unwrapped(_First);
}
return _First;
@ -906,7 +906,7 @@ struct _Static_partition_range<_FwdIt, _Diff, false> {
const auto _Chunk_size = _Team._Chunk_size;
const auto _Unchunked_items = _Team._Unchunked_items;
auto _Result = _Division_points.begin();
*_Result = _Get_unwrapped(_First);
*_Result = _STD _Get_unwrapped(_First);
for (_Diff _Idx{}; _Idx < _Unchunked_items; ++_Idx) { // record bounds of chunks with an extra item
for (_Diff _This_chunk_size = _Chunk_size + 1; 0 < _This_chunk_size--;) {
if (_First == _Last) {
@ -916,7 +916,7 @@ struct _Static_partition_range<_FwdIt, _Diff, false> {
++_First;
}
*++_Result = _Get_unwrapped(_First);
*++_Result = _STD _Get_unwrapped(_First);
}
const auto _Diff_chunks = static_cast<_Diff>(_Chunks);
@ -929,7 +929,7 @@ struct _Static_partition_range<_FwdIt, _Diff, false> {
++_First;
}
*++_Result = _Get_unwrapped(_First);
*++_Result = _STD _Get_unwrapped(_First);
}
return _First == _Last;
@ -960,7 +960,7 @@ struct _Static_partition_range_backward<_RanIt, _Diff, true> {
void _Populate(const _Static_partition_team<_Diff>& _Team, _RanIt _Last) {
// statically partition a random-access iterator range ending at _Last
// pre: _Populate hasn't yet been called on this instance
_Start_at = _Get_unwrapped_n(_Last, -static_cast<_Target_diff>(_Team._Count));
_Start_at = _STD _Get_unwrapped_n(_Last, -static_cast<_Target_diff>(_Team._Count));
}
_Chunk_type _Get_chunk(const _Static_partition_key<_Diff> _Key) const {
@ -986,10 +986,10 @@ struct _Static_partition_range_backward<_BidIt, _Diff, false> {
const auto _Neg_chunk_size = static_cast<_Target_diff>(-_Team._Chunk_size);
const auto _Unchunked_items = _Team._Unchunked_items;
auto _Result = _Division_points.begin(); // does range checking by incrementing in the checked domain
*_Result = _Get_unwrapped(_Last);
*_Result = _STD _Get_unwrapped(_Last);
for (_Diff _Idx{}; _Idx < _Unchunked_items; ++_Idx) {
_STD advance(_Last, static_cast<_Target_diff>(_Neg_chunk_size - 1));
*++_Result = _Get_unwrapped(_Last);
*++_Result = _STD _Get_unwrapped(_Last);
}
const auto _Diff_chunks = static_cast<_Diff>(_Chunks);
@ -1085,7 +1085,7 @@ struct _Static_partitioned_all_of_family2 { // all_of/any_of/none_of task schedu
static void __stdcall _Threadpool_callback(
__std_PTP_CALLBACK_INSTANCE, void* const _Context, __std_PTP_WORK) noexcept /* terminates */ {
_Run_available_chunked_work(*static_cast<_Static_partitioned_all_of_family2*>(_Context));
_STD _Run_available_chunked_work(*static_cast<_Static_partitioned_all_of_family2*>(_Context));
}
};
@ -1098,7 +1098,7 @@ bool _All_of_family_parallel(_FwdIt _First, const _FwdIt _Last, _Pr _Pred) {
if (_Count >= 2) { // ... with at least 2 elements
_TRY_BEGIN
_Static_partitioned_all_of_family2<_Invert, _FwdIt, _Pr> _Operation{_First, _Hw_threads, _Count, _Pred};
_Run_chunked_parallel_work(_Hw_threads, _Operation);
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
return !_Operation._Cancel_token._Is_canceled_relaxed();
_CATCH(const _Parallelism_resources_exhausted&)
// fall through to serial case below
@ -1119,13 +1119,13 @@ _EXPORT_STD template <class _ExPo, class _FwdIt, class _Pr, _Enable_if_execution
_NODISCARD bool all_of(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Pr _Pred) noexcept /* terminates */ {
// test if all elements in [_First, _Last) satisfy _Pred with the indicated execution policy
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
if constexpr (remove_reference_t<_ExPo>::_Parallelize) {
return _All_of_family_parallel<false>(_UFirst, _ULast, _Pass_fn(_Pred));
return _STD _All_of_family_parallel<false>(_UFirst, _ULast, _STD _Pass_fn(_Pred));
} else {
return _STD all_of(_UFirst, _ULast, _Pass_fn(_Pred));
return _STD all_of(_UFirst, _ULast, _STD _Pass_fn(_Pred));
}
}
@ -1133,13 +1133,13 @@ _EXPORT_STD template <class _ExPo, class _FwdIt, class _Pr, _Enable_if_execution
_NODISCARD bool any_of(_ExPo&&, const _FwdIt _First, const _FwdIt _Last, _Pr _Pred) noexcept /* terminates */ {
// test if any element in [_First, _Last) satisfies _Pred with the indicated execution policy
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
if constexpr (remove_reference_t<_ExPo>::_Parallelize) {
return !_All_of_family_parallel<true>(_UFirst, _ULast, _Pass_fn(_Pred));
return !_STD _All_of_family_parallel<true>(_UFirst, _ULast, _STD _Pass_fn(_Pred));
} else {
return _STD any_of(_UFirst, _ULast, _Pass_fn(_Pred));
return _STD any_of(_UFirst, _ULast, _STD _Pass_fn(_Pred));
}
}
@ -1147,13 +1147,13 @@ _EXPORT_STD template <class _ExPo, class _FwdIt, class _Pr, _Enable_if_execution
_NODISCARD bool none_of(_ExPo&&, const _FwdIt _First, const _FwdIt _Last, _Pr _Pred) noexcept /* terminates */ {
// test if no element in [_First, _Last) satisfies _Pred with the indicated execution policy
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
if constexpr (remove_reference_t<_ExPo>::_Parallelize) {
return _All_of_family_parallel<true>(_UFirst, _ULast, _Pass_fn(_Pred));
return _STD _All_of_family_parallel<true>(_UFirst, _ULast, _STD _Pass_fn(_Pred));
} else {
return _STD none_of(_UFirst, _ULast, _Pass_fn(_Pred));
return _STD none_of(_UFirst, _ULast, _STD _Pass_fn(_Pred));
}
}
@ -1179,7 +1179,7 @@ struct _Static_partitioned_for_each2 { // for_each task scheduled on the system
const auto _Key = _Team._Get_next_key();
if (_Key) {
const auto _Chunk = _Basis._Get_chunk(_Key);
_For_each_ivdep(_Chunk._First, _Chunk._Last, _Func);
_STD _For_each_ivdep(_Chunk._First, _Chunk._Last, _Func);
return _Cancellation_status::_Running;
}
@ -1188,7 +1188,7 @@ struct _Static_partitioned_for_each2 { // for_each task scheduled on the system
static void __stdcall _Threadpool_callback(
__std_PTP_CALLBACK_INSTANCE, void* const _Context, __std_PTP_WORK) noexcept /* terminates */ {
_Run_available_chunked_work(*static_cast<_Static_partitioned_for_each2*>(_Context));
_STD _Run_available_chunked_work(*static_cast<_Static_partitioned_for_each2*>(_Context));
}
};
@ -1196,20 +1196,20 @@ _EXPORT_STD template <class _ExPo, class _FwdIt, class _Fn, _Enable_if_execution
void for_each(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Fn _Func) noexcept /* terminates */ {
// perform function for each element [_First, _Last) with the indicated execution policy
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
if constexpr (remove_reference_t<_ExPo>::_Parallelize) {
const size_t _Hw_threads = __std_parallel_algorithms_hw_threads();
if (_Hw_threads > 1) { // parallelize on multiprocessor machines...
auto _Count = _STD distance(_UFirst, _ULast);
if (_Count >= 2) { // ... with at least 2 elements
_TRY_BEGIN
auto _Passed_fn = _Pass_fn(_Func);
auto _Passed_fn = _STD _Pass_fn(_Func);
_Static_partitioned_for_each2<decltype(_UFirst), decltype(_Count), decltype(_Passed_fn)> _Operation{
_Hw_threads, _Count, _Passed_fn};
_Operation._Basis._Populate(_Operation._Team, _UFirst);
_Run_chunked_parallel_work(_Hw_threads, _Operation);
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
return;
_CATCH(const _Parallelism_resources_exhausted&)
// fall through to serial case below
@ -1217,9 +1217,9 @@ void for_each(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Fn _Func) noexcept /* termi
}
}
_For_each_ivdep(_UFirst, _ULast, _Pass_fn(_Func));
_STD _For_each_ivdep(_UFirst, _ULast, _STD _Pass_fn(_Func));
} else if constexpr (remove_reference_t<_ExPo>::_Ivdep) {
_For_each_ivdep(_UFirst, _ULast, _Pass_fn(_Func));
_STD _For_each_ivdep(_UFirst, _ULast, _STD _Pass_fn(_Func));
} else {
for (; _UFirst != _ULast; ++_UFirst) {
_Func(*_UFirst);
@ -1244,31 +1244,31 @@ _FwdIt for_each_n(_ExPo&&, _FwdIt _First, const _Diff _Count_raw, _Fn _Func) noe
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
_Algorithm_int_t<_Diff> _Count = _Count_raw;
if (0 < _Count) {
auto _UFirst = _Get_unwrapped_n(_First, _Count);
auto _UFirst = _STD _Get_unwrapped_n(_First, _Count);
if constexpr (remove_reference_t<_ExPo>::_Parallelize) {
const size_t _Hw_threads = __std_parallel_algorithms_hw_threads();
if (_Hw_threads > 1 && _Count >= 2) { // parallelize on multiprocessor machines with at least 2 elements
_TRY_BEGIN
auto _Passed_fn = _Pass_fn(_Func);
auto _Passed_fn = _STD _Pass_fn(_Func);
_Static_partitioned_for_each2<decltype(_UFirst), decltype(_Count), decltype(_Passed_fn)> _Operation{
_Hw_threads, _Count, _Passed_fn};
_Seek_wrapped(_First, _Operation._Basis._Populate(_Operation._Team, _UFirst));
_Run_chunked_parallel_work(_Hw_threads, _Operation);
_STD _Seek_wrapped(_First, _Operation._Basis._Populate(_Operation._Team, _UFirst));
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
return _First;
_CATCH(const _Parallelism_resources_exhausted&)
// fall through to serial case below
_CATCH_END
}
_Seek_wrapped(_First, _For_each_n_ivdep(_UFirst, _Count, _Pass_fn(_Func)));
_STD _Seek_wrapped(_First, _STD _For_each_n_ivdep(_UFirst, _Count, _STD _Pass_fn(_Func)));
} else if constexpr (remove_reference_t<_ExPo>::_Ivdep) {
_Seek_wrapped(_First, _For_each_n_ivdep(_UFirst, _Count, _Pass_fn(_Func)));
_STD _Seek_wrapped(_First, _STD _For_each_n_ivdep(_UFirst, _Count, _STD _Pass_fn(_Func)));
} else {
for (; 0 < _Count; --_Count, (void) ++_UFirst) {
_Func(*_UFirst);
}
_Seek_wrapped(_First, _UFirst);
_STD _Seek_wrapped(_First, _UFirst);
}
}
@ -1313,7 +1313,7 @@ struct _Static_partitioned_find3 {
static void __stdcall _Threadpool_callback(
__std_PTP_CALLBACK_INSTANCE, void* const _Context, __std_PTP_WORK) noexcept /* terminates */ {
_Run_available_chunked_work(*static_cast<_Static_partitioned_find3*>(_Context));
_STD _Run_available_chunked_work(*static_cast<_Static_partitioned_find3*>(_Context));
}
};
@ -1328,7 +1328,7 @@ _FwdIt _Find_parallel_unchecked(_ExPo&&, const _FwdIt _First, const _FwdIt _Last
_TRY_BEGIN
_Static_partitioned_find3 _Operation{_Hw_threads, _Count, _Last, _Fx};
_Operation._Basis._Populate(_Operation._Team, _First);
_Run_chunked_parallel_work(_Hw_threads, _Operation);
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
return _Operation._Results._Get_result();
_CATCH(const _Parallelism_resources_exhausted&)
// fall through to _Fx below
@ -1345,10 +1345,11 @@ _NODISCARD _FwdIt find(_ExPo&& _Exec, _FwdIt _First, const _FwdIt _Last, const _
// find first matching _Val
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
using _UFwdIt = _Unwrapped_t<const _FwdIt&>;
_Adl_verify_range(_First, _Last);
_Seek_wrapped(_First,
_Find_parallel_unchecked(_STD forward<_ExPo>(_Exec), _Get_unwrapped(_First), _Get_unwrapped(_Last),
[&](const _UFwdIt _LFirst, const _UFwdIt _LLast) { return _STD _Find_unchecked(_LFirst, _LLast, _Val); }));
_STD _Adl_verify_range(_First, _Last);
_STD _Seek_wrapped(_First, _STD _Find_parallel_unchecked(_STD forward<_ExPo>(_Exec), _STD _Get_unwrapped(_First),
_STD _Get_unwrapped(_Last), [&](const _UFwdIt _LFirst, const _UFwdIt _LLast) {
return _STD _Find_unchecked(_LFirst, _LLast, _Val);
}));
return _First;
}
@ -1357,11 +1358,12 @@ _NODISCARD _FwdIt find_if(_ExPo&& _Exec, _FwdIt _First, const _FwdIt _Last, _Pr
// find first satisfying _Pred
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
using _UFwdIt = _Unwrapped_t<const _FwdIt&>;
_Adl_verify_range(_First, _Last);
auto _Pass_pred = _Pass_fn(_Pred);
_Seek_wrapped(_First,
_Find_parallel_unchecked(_STD forward<_ExPo>(_Exec), _Get_unwrapped(_First), _Get_unwrapped(_Last),
[=](const _UFwdIt _LFirst, const _UFwdIt _LLast) { return _STD find_if(_LFirst, _LLast, _Pass_pred); }));
_STD _Adl_verify_range(_First, _Last);
auto _Pass_pred = _STD _Pass_fn(_Pred);
_STD _Seek_wrapped(_First, _STD _Find_parallel_unchecked(_STD forward<_ExPo>(_Exec), _STD _Get_unwrapped(_First),
_STD _Get_unwrapped(_Last), [=](const _UFwdIt _LFirst, const _UFwdIt _LLast) {
return _STD find_if(_LFirst, _LLast, _Pass_pred);
}));
return _First;
}
@ -1370,12 +1372,12 @@ _NODISCARD _FwdIt find_if_not(_ExPo&& _Exec, _FwdIt _First, const _FwdIt _Last,
// find first satisfying !_Pred
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
using _UFwdIt = _Unwrapped_t<const _FwdIt&>;
_Adl_verify_range(_First, _Last);
auto _Pass_pred = _Pass_fn(_Pred);
_Seek_wrapped(_First, _Find_parallel_unchecked(_STD forward<_ExPo>(_Exec), _Get_unwrapped(_First),
_Get_unwrapped(_Last), [=](const _UFwdIt _LFirst, const _UFwdIt _LLast) {
return _STD find_if_not(_LFirst, _LLast, _Pass_pred);
}));
_STD _Adl_verify_range(_First, _Last);
auto _Pass_pred = _STD _Pass_fn(_Pred);
_STD _Seek_wrapped(_First, _STD _Find_parallel_unchecked(_STD forward<_ExPo>(_Exec), _STD _Get_unwrapped(_First),
_STD _Get_unwrapped(_Last), [=](const _UFwdIt _LFirst, const _UFwdIt _LLast) {
return _STD find_if_not(_LFirst, _LLast, _Pass_pred);
}));
return _First;
}
@ -1508,7 +1510,7 @@ struct _Static_partitioned_find_end_backward3 {
auto _Last1 = _Range._Last;
do {
--_Last1;
if (_Equal_rev_pred_unchecked(_Last1, _Range2._First, _Range2._Last, _Pred)) {
if (_STD _Equal_rev_pred_unchecked(_Last1, _Range2._First, _Range2._Last, _Pred)) {
_Results._Imbue(_Chunk_number, _Last1);
return _Cancellation_status::_Canceled;
}
@ -1518,7 +1520,7 @@ struct _Static_partitioned_find_end_backward3 {
static void __stdcall _Threadpool_callback(
__std_PTP_CALLBACK_INSTANCE, void* const _Context, __std_PTP_WORK) noexcept /* terminates */ {
_Run_available_chunked_work(*static_cast<_Static_partitioned_find_end_backward3*>(_Context));
_STD _Run_available_chunked_work(*static_cast<_Static_partitioned_find_end_backward3*>(_Context));
}
};
@ -1529,20 +1531,20 @@ _NODISCARD _FwdIt1 find_end(_ExPo&&, _FwdIt1 _First1, const _FwdIt1 _Last1, cons
// find last [_First2, _Last2) satisfying _Pred
_REQUIRE_PARALLEL_ITERATOR(_FwdIt1);
_REQUIRE_PARALLEL_ITERATOR(_FwdIt2);
_Adl_verify_range(_First1, _Last1);
_Adl_verify_range(_First2, _Last2);
const auto _UFirst1 = _Get_unwrapped(_First1);
const auto _ULast1 = _Get_unwrapped(_Last1);
const auto _UFirst2 = _Get_unwrapped(_First2);
const auto _ULast2 = _Get_unwrapped(_Last2);
_STD _Adl_verify_range(_First1, _Last1);
_STD _Adl_verify_range(_First2, _Last2);
const auto _UFirst1 = _STD _Get_unwrapped(_First1);
const auto _ULast1 = _STD _Get_unwrapped(_Last1);
const auto _UFirst2 = _STD _Get_unwrapped(_First2);
const auto _ULast2 = _STD _Get_unwrapped(_Last2);
if constexpr (remove_reference_t<_ExPo>::_Parallelize) {
const size_t _Hw_threads = __std_parallel_algorithms_hw_threads();
if (_Hw_threads > 1) {
if constexpr (_Is_ranges_bidi_iter_v<_FwdIt1>) {
const auto _Partition_start =
_Get_find_end_backward_partition_start(_UFirst1, _ULast1, _UFirst2, _ULast2);
_STD _Get_find_end_backward_partition_start(_UFirst1, _ULast1, _UFirst2, _ULast2);
if (_UFirst1 == _Partition_start) {
_Seek_wrapped(_First1, _ULast1);
_STD _Seek_wrapped(_First1, _ULast1);
return _First1;
}
@ -1550,24 +1552,24 @@ _NODISCARD _FwdIt1 find_end(_ExPo&&, _FwdIt1 _First1, const _FwdIt1 _Last1, cons
if (_Count >= 2) {
_TRY_BEGIN
_Static_partitioned_find_end_backward3 _Operation{
_Hw_threads, _Count, _ULast1, _UFirst2, _ULast2, _Pass_fn(_Pred)};
_Hw_threads, _Count, _ULast1, _UFirst2, _ULast2, _STD _Pass_fn(_Pred)};
_Operation._Basis._Populate(_Operation._Team, _Partition_start);
_Run_chunked_parallel_work(_Hw_threads, _Operation);
_Seek_wrapped(_First1, _Operation._Results._Get_result());
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
_STD _Seek_wrapped(_First1, _Operation._Results._Get_result());
return _First1;
_CATCH(const _Parallelism_resources_exhausted&)
// fall through to serial case below
_CATCH_END
}
} else {
const auto _Count = _Get_find_end_forward_partition_size(_UFirst1, _ULast1, _UFirst2, _ULast2);
const auto _Count = _STD _Get_find_end_forward_partition_size(_UFirst1, _ULast1, _UFirst2, _ULast2);
if (_Count >= 2) {
_TRY_BEGIN
_Static_partitioned_find_end_forward2 _Operation{
_Hw_threads, _Count, _ULast1, _UFirst2, _ULast2, _Pass_fn(_Pred)};
_Hw_threads, _Count, _ULast1, _UFirst2, _ULast2, _STD _Pass_fn(_Pred)};
_Operation._Basis._Populate(_Operation._Team, _UFirst1);
_Run_chunked_parallel_work(_Hw_threads, _Operation);
_Seek_wrapped(_First1, _Operation._Results._Get_result());
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
_STD _Seek_wrapped(_First1, _Operation._Results._Get_result());
return _First1;
_CATCH(const _Parallelism_resources_exhausted&)
// fall through to serial case below
@ -1577,7 +1579,7 @@ _NODISCARD _FwdIt1 find_end(_ExPo&&, _FwdIt1 _First1, const _FwdIt1 _Last1, cons
}
}
_Seek_wrapped(_First1, _STD find_end(_UFirst1, _ULast1, _UFirst2, _ULast2, _Pass_fn(_Pred)));
_STD _Seek_wrapped(_First1, _STD find_end(_UFirst1, _ULast1, _UFirst2, _ULast2, _STD _Pass_fn(_Pred)));
return _First1;
}
@ -1589,19 +1591,19 @@ _NODISCARD _FwdIt1 find_first_of(_ExPo&& _Exec, const _FwdIt1 _First1, _FwdIt1 _
_REQUIRE_PARALLEL_ITERATOR(_FwdIt1);
_REQUIRE_PARALLEL_ITERATOR(_FwdIt2);
using _UFwdIt1 = _Unwrapped_t<const _FwdIt1&>;
_Adl_verify_range(_First1, _Last1);
_Adl_verify_range(_First2, _Last2);
const auto _UFirst2 = _Get_unwrapped(_First2);
const auto _ULast2 = _Get_unwrapped(_Last2);
_STD _Adl_verify_range(_First1, _Last1);
_STD _Adl_verify_range(_First2, _Last2);
const auto _UFirst2 = _STD _Get_unwrapped(_First2);
const auto _ULast2 = _STD _Get_unwrapped(_Last2);
if (_UFirst2 == _ULast2) {
return _Last1;
}
auto _Pass_pred = _Pass_fn(_Pred);
_Seek_wrapped(_Last1, _Find_parallel_unchecked(_STD forward<_ExPo>(_Exec), _Get_unwrapped(_First1),
_Get_unwrapped(_Last1), [=](const _UFwdIt1 _LFirst1, const _UFwdIt1 _LLast1) {
return _STD find_first_of(_LFirst1, _LLast1, _UFirst2, _ULast2, _Pass_pred);
}));
auto _Pass_pred = _STD _Pass_fn(_Pred);
_STD _Seek_wrapped(_Last1, _STD _Find_parallel_unchecked(_STD forward<_ExPo>(_Exec), _STD _Get_unwrapped(_First1),
_STD _Get_unwrapped(_Last1), [=](const _UFwdIt1 _LFirst1, const _UFwdIt1 _LLast1) {
return _STD find_first_of(_LFirst1, _LLast1, _UFirst2, _ULast2, _Pass_pred);
}));
return _Last1;
}
@ -1645,7 +1647,7 @@ struct _Static_partitioned_adjacent_find3 {
static void __stdcall _Threadpool_callback(
__std_PTP_CALLBACK_INSTANCE, void* const _Context, __std_PTP_WORK) noexcept /* terminates */ {
_Run_available_chunked_work(*static_cast<_Static_partitioned_adjacent_find3*>(_Context));
_STD _Run_available_chunked_work(*static_cast<_Static_partitioned_adjacent_find3*>(_Context));
}
};
@ -1653,19 +1655,19 @@ _EXPORT_STD template <class _ExPo, class _FwdIt, class _Pr, _Enable_if_execution
_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);
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
if constexpr (remove_reference_t<_ExPo>::_Parallelize) {
const size_t _Hw_threads = __std_parallel_algorithms_hw_threads();
if (_Hw_threads > 1) {
const auto _Count = static_cast<_Iter_diff_t<_FwdIt>>(_STD distance(_UFirst, _ULast) - 1);
if (_Count >= 2) {
_TRY_BEGIN
_Static_partitioned_adjacent_find3 _Operation{_Hw_threads, _Count, _ULast, _Pass_fn(_Pred)};
_Static_partitioned_adjacent_find3 _Operation{_Hw_threads, _Count, _ULast, _STD _Pass_fn(_Pred)};
_Operation._Basis._Populate(_Operation._Team, _UFirst);
_Run_chunked_parallel_work(_Hw_threads, _Operation);
_Seek_wrapped(_Last, _Operation._Results._Get_result());
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
_STD _Seek_wrapped(_Last, _Operation._Results._Get_result());
return _Last;
_CATCH(const _Parallelism_resources_exhausted&)
// fall through to adjacent_find below
@ -1674,7 +1676,7 @@ _NODISCARD _FwdIt adjacent_find(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Pr _Pred)
}
}
_Seek_wrapped(_Last, _STD adjacent_find(_UFirst, _ULast, _Pass_fn(_Pred)));
_STD _Seek_wrapped(_Last, _STD adjacent_find(_UFirst, _ULast, _STD _Pass_fn(_Pred)));
return _Last;
}
@ -1713,9 +1715,9 @@ _NODISCARD _Iter_diff_t<_FwdIt> count_if(_ExPo&&, const _FwdIt _First, const _Fw
/* terminates */ {
// count elements satisfying _Pred
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
if constexpr (remove_reference_t<_ExPo>::_Parallelize) {
const size_t _Hw_threads = __std_parallel_algorithms_hw_threads();
if (_Hw_threads > 1) {
@ -1723,7 +1725,7 @@ _NODISCARD _Iter_diff_t<_FwdIt> count_if(_ExPo&&, const _FwdIt _First, const _Fw
if (_Count >= 2) {
const auto _Chunks = _Get_chunked_work_chunk_count(_Hw_threads, _Count);
_TRY_BEGIN
_Static_partitioned_count_if2 _Operation{_Count, _Chunks, _UFirst, _Pass_fn(_Pred)};
_Static_partitioned_count_if2 _Operation{_Count, _Chunks, _UFirst, _STD _Pass_fn(_Pred)};
_Iter_diff_t<_FwdIt> _Foreground_count;
{
const _Work_ptr _Work{_Operation};
@ -1740,7 +1742,7 @@ _NODISCARD _Iter_diff_t<_FwdIt> count_if(_ExPo&&, const _FwdIt _First, const _Fw
}
}
return _STD count_if(_UFirst, _ULast, _Pass_fn(_Pred));
return _STD count_if(_UFirst, _ULast, _STD _Pass_fn(_Pred));
}
_EXPORT_STD template <class _ExPo, class _FwdIt, class _Ty, _Enable_if_execution_policy_t<_ExPo> /* = 0 */>
@ -1748,8 +1750,8 @@ _NODISCARD _Iter_diff_t<_FwdIt> count(_ExPo&& _Exec, const _FwdIt _First, const
/* terminates */ {
// count elements that match _Val
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
_Adl_verify_range(_First, _Last);
return _STD count_if(_STD forward<_ExPo>(_Exec), _Get_unwrapped(_First), _Get_unwrapped(_Last),
_STD _Adl_verify_range(_First, _Last);
return _STD count_if(_STD forward<_ExPo>(_Exec), _STD _Get_unwrapped(_First), _STD _Get_unwrapped(_Last),
[&_Val](auto&& _Iter_val) { return _STD forward<decltype(_Iter_val)>(_Iter_val) == _Val; });
}
@ -1809,8 +1811,8 @@ struct _Static_partitioned_mismatch_results<_FwdIt1, _FwdIt2, false, false> {
pair<_FwdIt1, _FwdIt2> _Get_result(_FwdIt1 _First1, _FwdIt2 _First2) const {
const auto _Result = _Storage._Get_result();
_Seek_wrapped(_First2, _Result.second);
_Seek_wrapped(_First1, _Result.first);
_STD _Seek_wrapped(_First2, _Result.second);
_STD _Seek_wrapped(_First1, _Result.first);
return {_First1, _First2};
}
};
@ -1827,8 +1829,8 @@ struct _Static_partitioned_mismatch3 {
_Static_partitioned_mismatch3(
const size_t _Hw_threads, const _Diff _Count, const _FwdIt1 _First1, const _FwdIt2 _First2, const _Pr _Pred_)
: _Team{_Count, _Get_chunked_work_chunk_count(_Hw_threads, _Count)}, _Basis1{}, _Basis2{},
_Results(
_Get_unwrapped(_Basis1._Populate(_Team, _First1)), _Get_unwrapped(_Basis2._Populate(_Team, _First2))),
_Results(_STD _Get_unwrapped(_Basis1._Populate(_Team, _First1)),
_STD _Get_unwrapped(_Basis2._Populate(_Team, _First2))),
_Pred(_Pred_) {}
_Cancellation_status _Process_chunk() {
@ -1863,7 +1865,7 @@ struct _Static_partitioned_mismatch3 {
static void __stdcall _Threadpool_callback(
__std_PTP_CALLBACK_INSTANCE, void* const _Context, __std_PTP_WORK) noexcept /* terminates */ {
_Run_available_chunked_work(*static_cast<_Static_partitioned_mismatch3*>(_Context));
_STD _Run_available_chunked_work(*static_cast<_Static_partitioned_mismatch3*>(_Context));
}
};
@ -1874,38 +1876,38 @@ _NODISCARD pair<_FwdIt1, _FwdIt2> mismatch(
// return [_First1, _Last1)/[_First2, ...) mismatch
_REQUIRE_PARALLEL_ITERATOR(_FwdIt1);
_REQUIRE_PARALLEL_ITERATOR(_FwdIt2);
_Adl_verify_range(_First1, _Last1);
const auto _UFirst1 = _Get_unwrapped(_First1);
const auto _ULast1 = _Get_unwrapped(_Last1);
_STD _Adl_verify_range(_First1, _Last1);
const auto _UFirst1 = _STD _Get_unwrapped(_First1);
const auto _ULast1 = _STD _Get_unwrapped(_Last1);
if constexpr (remove_reference_t<_ExPo>::_Parallelize) {
const size_t _Hw_threads = __std_parallel_algorithms_hw_threads();
if (_Hw_threads > 1) {
const auto _Count = _STD distance(_UFirst1, _ULast1);
const auto _UFirst2 = _Get_unwrapped_n(_First2, _Count);
const auto _UFirst2 = _STD _Get_unwrapped_n(_First2, _Count);
if (_Count >= 2) {
_TRY_BEGIN
_Static_partitioned_mismatch3 _Operation{_Hw_threads, _Count, _UFirst1, _UFirst2, _Pass_fn(_Pred)};
_Run_chunked_parallel_work(_Hw_threads, _Operation);
_Static_partitioned_mismatch3 _Operation{_Hw_threads, _Count, _UFirst1, _UFirst2, _STD _Pass_fn(_Pred)};
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
const auto _Result = _Operation._Results._Get_result(_UFirst1, _UFirst2);
_Seek_wrapped(_First2, _Result.second);
_Seek_wrapped(_First1, _Result.first);
_STD _Seek_wrapped(_First2, _Result.second);
_STD _Seek_wrapped(_First1, _Result.first);
return {_First1, _First2};
_CATCH(const _Parallelism_resources_exhausted&)
// fall through to serial case below
_CATCH_END
}
const auto _Result = _STD mismatch(_UFirst1, _ULast1, _UFirst2, _Pass_fn(_Pred));
_Seek_wrapped(_First2, _Result.second);
_Seek_wrapped(_First1, _Result.first);
const auto _Result = _STD mismatch(_UFirst1, _ULast1, _UFirst2, _STD _Pass_fn(_Pred));
_STD _Seek_wrapped(_First2, _Result.second);
_STD _Seek_wrapped(_First1, _Result.first);
return {_First1, _First2};
}
}
const auto _Result = _STD mismatch(
_UFirst1, _ULast1, _Get_unwrapped_n(_First2, _Idl_distance<_FwdIt1>(_UFirst1, _ULast1)), _Pass_fn(_Pred));
_Seek_wrapped(_First2, _Result.second);
_Seek_wrapped(_First1, _Result.first);
const auto _Result = _STD mismatch(_UFirst1, _ULast1,
_STD _Get_unwrapped_n(_First2, _STD _Idl_distance<_FwdIt1>(_UFirst1, _ULast1)), _STD _Pass_fn(_Pred));
_STD _Seek_wrapped(_First2, _Result.second);
_STD _Seek_wrapped(_First1, _Result.first);
return {_First1, _First2};
}
@ -1916,23 +1918,24 @@ _NODISCARD pair<_FwdIt1, _FwdIt2> mismatch(
// return [_First1, _Last1)/[_First2, _Last2) mismatch
_REQUIRE_PARALLEL_ITERATOR(_FwdIt1);
_REQUIRE_PARALLEL_ITERATOR(_FwdIt2);
_Adl_verify_range(_First1, _Last1);
_Adl_verify_range(_First2, _Last2);
const auto _UFirst1 = _Get_unwrapped(_First1);
const auto _ULast1 = _Get_unwrapped(_Last1);
const auto _UFirst2 = _Get_unwrapped(_First2);
const auto _ULast2 = _Get_unwrapped(_Last2);
_STD _Adl_verify_range(_First1, _Last1);
_STD _Adl_verify_range(_First2, _Last2);
const auto _UFirst1 = _STD _Get_unwrapped(_First1);
const auto _ULast1 = _STD _Get_unwrapped(_Last1);
const auto _UFirst2 = _STD _Get_unwrapped(_First2);
const auto _ULast2 = _STD _Get_unwrapped(_Last2);
if constexpr (remove_reference_t<_ExPo>::_Parallelize) {
const size_t _Hw_threads = __std_parallel_algorithms_hw_threads();
if (_Hw_threads > 1) {
const auto _Count = static_cast<_Iter_diff_t<_FwdIt1>>(_Distance_min(_UFirst1, _ULast1, _UFirst2, _ULast2));
const auto _Count =
static_cast<_Iter_diff_t<_FwdIt1>>(_STD _Distance_min(_UFirst1, _ULast1, _UFirst2, _ULast2));
if (_Count >= 2) {
_TRY_BEGIN
_Static_partitioned_mismatch3 _Operation{_Hw_threads, _Count, _UFirst1, _UFirst2, _Pass_fn(_Pred)};
_Run_chunked_parallel_work(_Hw_threads, _Operation);
_Static_partitioned_mismatch3 _Operation{_Hw_threads, _Count, _UFirst1, _UFirst2, _STD _Pass_fn(_Pred)};
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
const auto _Result = _Operation._Results._Get_result(_UFirst1, _UFirst2);
_Seek_wrapped(_First2, _Result.second);
_Seek_wrapped(_First1, _Result.first);
_STD _Seek_wrapped(_First2, _Result.second);
_STD _Seek_wrapped(_First1, _Result.first);
return {_First1, _First2};
_CATCH(const _Parallelism_resources_exhausted&)
// fall through to serial below
@ -1941,9 +1944,9 @@ _NODISCARD pair<_FwdIt1, _FwdIt2> mismatch(
}
}
const auto _Result = _STD mismatch(_UFirst1, _ULast1, _UFirst2, _ULast2, _Pass_fn(_Pred));
_Seek_wrapped(_First2, _Result.second);
_Seek_wrapped(_First1, _Result.first);
const auto _Result = _STD mismatch(_UFirst1, _ULast1, _UFirst2, _ULast2, _STD _Pass_fn(_Pred));
_STD _Seek_wrapped(_First2, _Result.second);
_STD _Seek_wrapped(_First1, _Result.first);
return {_First1, _First2};
}
@ -1983,7 +1986,7 @@ struct _Static_partitioned_equal2 {
static void __stdcall _Threadpool_callback(
__std_PTP_CALLBACK_INSTANCE, void* const _Context, __std_PTP_WORK) noexcept /* terminates */ {
_Run_available_chunked_work(*static_cast<_Static_partitioned_equal2*>(_Context));
_STD _Run_available_chunked_work(*static_cast<_Static_partitioned_equal2*>(_Context));
}
};
@ -1994,31 +1997,31 @@ _NODISCARD bool equal(_ExPo&&, const _FwdIt1 _First1, const _FwdIt1 _Last1, cons
// compare [_First1, _Last1) to [_First2, ...)
_REQUIRE_PARALLEL_ITERATOR(_FwdIt1);
_REQUIRE_PARALLEL_ITERATOR(_FwdIt2);
_Adl_verify_range(_First1, _Last1);
const auto _UFirst1 = _Get_unwrapped(_First1);
const auto _ULast1 = _Get_unwrapped(_Last1);
_STD _Adl_verify_range(_First1, _Last1);
const auto _UFirst1 = _STD _Get_unwrapped(_First1);
const auto _ULast1 = _STD _Get_unwrapped(_Last1);
if constexpr (remove_reference_t<_ExPo>::_Parallelize) {
const size_t _Hw_threads = __std_parallel_algorithms_hw_threads();
if (_Hw_threads > 1) {
const auto _Count = _STD distance(_UFirst1, _ULast1);
const auto _UFirst2 = _Get_unwrapped_n(_First2, _Count);
const auto _UFirst2 = _STD _Get_unwrapped_n(_First2, _Count);
if (_Count >= 2) {
_TRY_BEGIN
_Static_partitioned_equal2 _Operation{_Hw_threads, _Count, _Pass_fn(_Pred), _UFirst1, _UFirst2};
_Static_partitioned_equal2 _Operation{_Hw_threads, _Count, _STD _Pass_fn(_Pred), _UFirst1, _UFirst2};
_Operation._Basis1._Populate(_Operation._Team, _UFirst1);
_Operation._Basis2._Populate(_Operation._Team, _UFirst2);
_Run_chunked_parallel_work(_Hw_threads, _Operation);
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
return !_Operation._Cancel_token._Is_canceled_relaxed();
_CATCH(const _Parallelism_resources_exhausted&)
// fall through to serial case below
_CATCH_END
}
return _STD equal(_UFirst1, _ULast1, _UFirst2, _Pass_fn(_Pred));
return _STD equal(_UFirst1, _ULast1, _UFirst2, _STD _Pass_fn(_Pred));
}
}
return _STD equal(_UFirst1, _ULast1, _First2, _Pass_fn(_Pred));
return _STD equal(_UFirst1, _ULast1, _First2, _STD _Pass_fn(_Pred));
}
_EXPORT_STD template <class _ExPo, class _FwdIt1, class _FwdIt2, class _Pr,
@ -2028,19 +2031,19 @@ _NODISCARD bool equal(_ExPo&&, const _FwdIt1 _First1, const _FwdIt1 _Last1, cons
// compare [_First1, _Last1) to [_First2, _Last2)
_REQUIRE_PARALLEL_ITERATOR(_FwdIt1);
_REQUIRE_PARALLEL_ITERATOR(_FwdIt2);
_Adl_verify_range(_First1, _Last1);
_Adl_verify_range(_First2, _Last2);
const auto _UFirst1 = _Get_unwrapped(_First1);
const auto _ULast1 = _Get_unwrapped(_Last1);
const auto _UFirst2 = _Get_unwrapped(_First2);
const auto _ULast2 = _Get_unwrapped(_Last2);
_STD _Adl_verify_range(_First1, _Last1);
_STD _Adl_verify_range(_First2, _Last2);
const auto _UFirst1 = _STD _Get_unwrapped(_First1);
const auto _ULast1 = _STD _Get_unwrapped(_Last1);
const auto _UFirst2 = _STD _Get_unwrapped(_First2);
const auto _ULast2 = _STD _Get_unwrapped(_Last2);
if constexpr (remove_reference_t<_ExPo>::_Parallelize) {
const size_t _Hw_threads = __std_parallel_algorithms_hw_threads();
if (_Hw_threads > 1) {
const auto _Count = _Distance_any(_UFirst1, _ULast1, _UFirst2, _ULast2);
const auto _Count = _STD _Distance_any(_UFirst1, _ULast1, _UFirst2, _ULast2);
if (_Count >= 2) {
_TRY_BEGIN
_Static_partitioned_equal2 _Operation{_Hw_threads, _Count, _Pass_fn(_Pred), _UFirst1, _UFirst2};
_Static_partitioned_equal2 _Operation{_Hw_threads, _Count, _STD _Pass_fn(_Pred), _UFirst1, _UFirst2};
if (!_Operation._Basis1._Populate(_Operation._Team, _UFirst1, _ULast1)) {
// left sequence didn't have length _Count
return false;
@ -2051,7 +2054,7 @@ _NODISCARD bool equal(_ExPo&&, const _FwdIt1 _First1, const _FwdIt1 _Last1, cons
return false;
}
_Run_chunked_parallel_work(_Hw_threads, _Operation);
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
return !_Operation._Cancel_token._Is_canceled_relaxed();
_CATCH(const _Parallelism_resources_exhausted&)
// fall through to equal below
@ -2060,7 +2063,7 @@ _NODISCARD bool equal(_ExPo&&, const _FwdIt1 _First1, const _FwdIt1 _Last1, cons
}
}
return _STD equal(_UFirst1, _ULast1, _UFirst2, _ULast2, _Pass_fn(_Pred));
return _STD equal(_UFirst1, _ULast1, _UFirst2, _ULast2, _STD _Pass_fn(_Pred));
}
template <class _FwdItHaystack, class _FwdItPat, class _Pr>
@ -2093,7 +2096,7 @@ struct _Static_partitioned_search3 {
const auto _Range = _Basis._Get_chunk(_Key);
for (auto _Candidate = _Range._First; _Candidate != _Range._Last; ++_Candidate) {
if (_Equal_rev_pred_unchecked(_Candidate, _First2, _Last2, _Pred)) {
if (_STD _Equal_rev_pred_unchecked(_Candidate, _First2, _Last2, _Pred)) {
_Results._Imbue(_Key._Chunk_number, _Candidate);
return _Cancellation_status::_Canceled;
}
@ -2104,7 +2107,7 @@ struct _Static_partitioned_search3 {
static void __stdcall _Threadpool_callback(
__std_PTP_CALLBACK_INSTANCE, void* const _Context, __std_PTP_WORK) noexcept /* terminates */ {
_Run_available_chunked_work(*static_cast<_Static_partitioned_search3*>(_Context));
_STD _Run_available_chunked_work(*static_cast<_Static_partitioned_search3*>(_Context));
}
};
@ -2115,16 +2118,16 @@ _NODISCARD _FwdItHaystack search(_ExPo&&, const _FwdItHaystack _First1, _FwdItHa
// find first [_First2, _Last2) match
_REQUIRE_PARALLEL_ITERATOR(_FwdItHaystack);
_REQUIRE_PARALLEL_ITERATOR(_FwdItPat);
_Adl_verify_range(_First2, _Last2);
const auto _UFirst2 = _Get_unwrapped(_First2);
const auto _ULast2 = _Get_unwrapped(_Last2);
_STD _Adl_verify_range(_First2, _Last2);
const auto _UFirst2 = _STD _Get_unwrapped(_First2);
const auto _ULast2 = _STD _Get_unwrapped(_Last2);
if (_UFirst2 == _ULast2) {
return _First1;
}
_Adl_verify_range(_First1, _Last1);
const auto _UFirst1 = _Get_unwrapped(_First1);
const auto _ULast1 = _Get_unwrapped(_Last1);
_STD _Adl_verify_range(_First1, _Last1);
const auto _UFirst1 = _STD _Get_unwrapped(_First1);
const auto _ULast1 = _STD _Get_unwrapped(_Last1);
if constexpr (remove_reference_t<_ExPo>::_Parallelize) {
const size_t _Hw_threads = __std_parallel_algorithms_hw_threads();
@ -2162,7 +2165,7 @@ _NODISCARD _FwdItHaystack search(_ExPo&&, const _FwdItHaystack _First1, _FwdItHa
if (_Count == 1) {
// 1 match possible == ranges are of equal length -- do better than serial search because we've done the
// work to calculate distance() of the inputs
if (_Equal_rev_pred_unchecked(_UFirst1, _UFirst2, _ULast2, _Pass_fn(_Pred))) {
if (_STD _Equal_rev_pred_unchecked(_UFirst1, _UFirst2, _ULast2, _STD _Pass_fn(_Pred))) {
return _First1;
}
@ -2171,9 +2174,9 @@ _NODISCARD _FwdItHaystack search(_ExPo&&, const _FwdItHaystack _First1, _FwdItHa
_TRY_BEGIN
_Static_partitioned_search3 _Operation{
_Hw_threads, _Count, _UFirst1, _ULast1, _UFirst2, _ULast2, _Pass_fn(_Pred)};
_Run_chunked_parallel_work(_Hw_threads, _Operation);
_Seek_wrapped(_Last1, _Operation._Results._Get_result());
_Hw_threads, _Count, _UFirst1, _ULast1, _UFirst2, _ULast2, _STD _Pass_fn(_Pred)};
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
_STD _Seek_wrapped(_Last1, _Operation._Results._Get_result());
return _Last1;
_CATCH(const _Parallelism_resources_exhausted&)
// fall through to search, below
@ -2181,7 +2184,7 @@ _NODISCARD _FwdItHaystack search(_ExPo&&, const _FwdItHaystack _First1, _FwdItHa
}
}
_Seek_wrapped(_Last1, _STD search(_UFirst1, _ULast1, _UFirst2, _ULast2, _Pass_fn(_Pred)));
_STD _Seek_wrapped(_Last1, _STD search(_UFirst1, _ULast1, _UFirst2, _ULast2, _STD _Pass_fn(_Pred)));
return _Last1;
}
@ -2234,7 +2237,7 @@ struct _Static_partitioned_search_n3 {
static void __stdcall _Threadpool_callback(
__std_PTP_CALLBACK_INSTANCE, void* const _Context, __std_PTP_WORK) noexcept /* terminates */ {
_Run_available_chunked_work(*static_cast<_Static_partitioned_search_n3*>(_Context));
_STD _Run_available_chunked_work(*static_cast<_Static_partitioned_search_n3*>(_Context));
}
};
@ -2255,9 +2258,9 @@ _NODISCARD _FwdIt search_n(_ExPo&&, const _FwdIt _First, _FwdIt _Last, const _Di
return _Last;
}
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
if constexpr (remove_reference_t<_ExPo>::_Parallelize) {
const size_t _Hw_threads = __std_parallel_algorithms_hw_threads();
if (_Hw_threads > 1) {
@ -2270,9 +2273,9 @@ _NODISCARD _FwdIt search_n(_ExPo&&, const _FwdIt _First, _FwdIt _Last, const _Di
const auto _Candidates = static_cast<_Iter_diff_t<_FwdIt>>(_Haystack_count - _Count + 1);
_TRY_BEGIN
_Static_partitioned_search_n3 _Operation{_Hw_threads, _Candidates, _UFirst, _ULast,
static_cast<_Iter_diff_t<_FwdIt>>(_Count), _Val, _Pass_fn(_Pred)};
_Run_chunked_parallel_work(_Hw_threads, _Operation);
_Seek_wrapped(_Last, _Operation._Results._Get_result());
static_cast<_Iter_diff_t<_FwdIt>>(_Count), _Val, _STD _Pass_fn(_Pred)};
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
_STD _Seek_wrapped(_Last, _Operation._Results._Get_result());
return _Last;
_CATCH(const _Parallelism_resources_exhausted&)
// fall through to search_n, below
@ -2280,7 +2283,7 @@ _NODISCARD _FwdIt search_n(_ExPo&&, const _FwdIt _First, _FwdIt _Last, const _Di
}
}
_Seek_wrapped(_Last, _STD search_n(_UFirst, _ULast, _Count, _Val, _Pass_fn(_Pred)));
_STD _Seek_wrapped(_Last, _STD search_n(_UFirst, _ULast, _Count, _Val, _STD _Pass_fn(_Pred)));
return _Last;
}

Просмотреть файл

@ -98,15 +98,15 @@ _STD_BEGIN
template <class _Ty, class _TVal>
__declspec(noalias) size_t __std_count_trivial(_Ty* _First, _Ty* _Last, const _TVal _Val) noexcept {
if constexpr (_STD is_pointer_v<_TVal> || _STD is_null_pointer_v<_TVal>) {
return __std_count_trivial(_First, _Last, reinterpret_cast<uintptr_t>(_Val));
return _STD __std_count_trivial(_First, _Last, reinterpret_cast<uintptr_t>(_Val));
} else if constexpr (sizeof(_Ty) == 1) {
return __std_count_trivial_1(_First, _Last, static_cast<uint8_t>(_Val));
return ::__std_count_trivial_1(_First, _Last, static_cast<uint8_t>(_Val));
} else if constexpr (sizeof(_Ty) == 2) {
return __std_count_trivial_2(_First, _Last, static_cast<uint16_t>(_Val));
return ::__std_count_trivial_2(_First, _Last, static_cast<uint16_t>(_Val));
} else if constexpr (sizeof(_Ty) == 4) {
return __std_count_trivial_4(_First, _Last, static_cast<uint32_t>(_Val));
return ::__std_count_trivial_4(_First, _Last, static_cast<uint32_t>(_Val));
} else if constexpr (sizeof(_Ty) == 8) {
return __std_count_trivial_8(_First, _Last, static_cast<uint64_t>(_Val));
return ::__std_count_trivial_8(_First, _Last, static_cast<uint64_t>(_Val));
} else {
static_assert(_STD _Always_false<_Ty>, "Unexpected size");
}
@ -115,19 +115,19 @@ __declspec(noalias) size_t __std_count_trivial(_Ty* _First, _Ty* _Last, const _T
template <class _Ty, class _TVal>
_Ty* __std_find_trivial(_Ty* _First, _Ty* _Last, const _TVal _Val) noexcept {
if constexpr (_STD is_pointer_v<_TVal> || _STD is_null_pointer_v<_TVal>) {
return __std_find_trivial(_First, _Last, reinterpret_cast<uintptr_t>(_Val));
return _STD __std_find_trivial(_First, _Last, reinterpret_cast<uintptr_t>(_Val));
} else if constexpr (sizeof(_Ty) == 1) {
return const_cast<_Ty*>(
static_cast<const _Ty*>(__std_find_trivial_1(_First, _Last, static_cast<uint8_t>(_Val))));
static_cast<const _Ty*>(::__std_find_trivial_1(_First, _Last, static_cast<uint8_t>(_Val))));
} else if constexpr (sizeof(_Ty) == 2) {
return const_cast<_Ty*>(
static_cast<const _Ty*>(__std_find_trivial_2(_First, _Last, static_cast<uint16_t>(_Val))));
static_cast<const _Ty*>(::__std_find_trivial_2(_First, _Last, static_cast<uint16_t>(_Val))));
} else if constexpr (sizeof(_Ty) == 4) {
return const_cast<_Ty*>(
static_cast<const _Ty*>(__std_find_trivial_4(_First, _Last, static_cast<uint32_t>(_Val))));
static_cast<const _Ty*>(::__std_find_trivial_4(_First, _Last, static_cast<uint32_t>(_Val))));
} else if constexpr (sizeof(_Ty) == 8) {
return const_cast<_Ty*>(
static_cast<const _Ty*>(__std_find_trivial_8(_First, _Last, static_cast<uint64_t>(_Val))));
static_cast<const _Ty*>(::__std_find_trivial_8(_First, _Last, static_cast<uint64_t>(_Val))));
} else {
static_assert(_STD _Always_false<_Ty>, "Unexpected size");
}
@ -136,19 +136,19 @@ _Ty* __std_find_trivial(_Ty* _First, _Ty* _Last, const _TVal _Val) noexcept {
template <class _Ty, class _TVal>
_Ty* __std_find_trivial_unsized(_Ty* _First, const _TVal _Val) noexcept {
if constexpr (_STD is_pointer_v<_TVal> || _STD is_null_pointer_v<_TVal>) {
return __std_find_trivial_unsized(_First, reinterpret_cast<uintptr_t>(_Val));
return _STD __std_find_trivial_unsized(_First, reinterpret_cast<uintptr_t>(_Val));
} else if constexpr (sizeof(_Ty) == 1) {
return const_cast<_Ty*>(
static_cast<const _Ty*>(__std_find_trivial_unsized_1(_First, static_cast<uint8_t>(_Val))));
static_cast<const _Ty*>(::__std_find_trivial_unsized_1(_First, static_cast<uint8_t>(_Val))));
} else if constexpr (sizeof(_Ty) == 2) {
return const_cast<_Ty*>(
static_cast<const _Ty*>(__std_find_trivial_unsized_2(_First, static_cast<uint16_t>(_Val))));
static_cast<const _Ty*>(::__std_find_trivial_unsized_2(_First, static_cast<uint16_t>(_Val))));
} else if constexpr (sizeof(_Ty) == 4) {
return const_cast<_Ty*>(
static_cast<const _Ty*>(__std_find_trivial_unsized_4(_First, static_cast<uint32_t>(_Val))));
static_cast<const _Ty*>(::__std_find_trivial_unsized_4(_First, static_cast<uint32_t>(_Val))));
} else if constexpr (sizeof(_Ty) == 8) {
return const_cast<_Ty*>(
static_cast<const _Ty*>(__std_find_trivial_unsized_8(_First, static_cast<uint64_t>(_Val))));
static_cast<const _Ty*>(::__std_find_trivial_unsized_8(_First, static_cast<uint64_t>(_Val))));
} else {
static_assert(_STD _Always_false<_Ty>, "Unexpected size");
}
@ -1163,7 +1163,11 @@ _INLINE_VAR constexpr bool _Range_verifiable_v<_Iter, _Sentinel,
template <class _Iter, class _Sentinel>
constexpr void _Adl_verify_range(const _Iter& _First, const _Sentinel& _Last) {
// check that [_First, _Last) forms an iterator range
if constexpr (_Range_verifiable_v<_Iter, _Sentinel>) {
if constexpr (is_pointer_v<_Iter> && is_pointer_v<_Sentinel>) {
#if _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(_First <= _Last, "transposed pointer range");
#endif // _ITERATOR_DEBUG_LEVEL != 0
} else if constexpr (_Range_verifiable_v<_Iter, _Sentinel>) {
_Verify_range(_First, _Last);
}
}
@ -1196,7 +1200,7 @@ _NODISCARD constexpr decltype(auto) _Get_unwrapped(_Iter&& _It) noexcept(
}
template <class _Iter>
using _Unwrapped_t = _Remove_cvref_t<decltype(_Get_unwrapped(_STD declval<_Iter>()))>;
using _Unwrapped_t = _Remove_cvref_t<decltype(_STD _Get_unwrapped(_STD declval<_Iter>()))>;
template <class _Iter, class = bool>
_INLINE_VAR constexpr bool _Do_unwrap_when_unverified_v = false;
@ -2536,22 +2540,22 @@ namespace ranges {
template <range _Rng, class _Iter>
_NODISCARD constexpr decltype(auto) _Unwrap_range_iter(_Iter&& _It) noexcept(
noexcept(_Unwrap_iter<sentinel_t<_Rng>>(static_cast<_Iter&&>(_It)))) {
noexcept(_RANGES _Unwrap_iter<sentinel_t<_Rng>>(static_cast<_Iter&&>(_It)))) {
_STL_INTERNAL_STATIC_ASSERT(same_as<remove_cvref_t<_Iter>, iterator_t<_Rng>>);
return _Unwrap_iter<sentinel_t<_Rng>>(static_cast<_Iter&&>(_It));
return _RANGES _Unwrap_iter<sentinel_t<_Rng>>(static_cast<_Iter&&>(_It));
}
template <range _Rng, class _Sent>
_NODISCARD constexpr decltype(auto) _Unwrap_range_sent(_Sent&& _Se) noexcept(
noexcept(_Unwrap_sent<iterator_t<_Rng>>(static_cast<_Sent&&>(_Se)))) {
noexcept(_RANGES _Unwrap_sent<iterator_t<_Rng>>(static_cast<_Sent&&>(_Se)))) {
_STL_INTERNAL_STATIC_ASSERT(same_as<remove_cvref_t<_Sent>, sentinel_t<_Rng>>);
return _Unwrap_sent<iterator_t<_Rng>>(static_cast<_Sent&&>(_Se));
return _RANGES _Unwrap_sent<iterator_t<_Rng>>(static_cast<_Sent&&>(_Se));
}
template <class _Iter, class _Sent>
using _Unwrap_iter_t = remove_cvref_t<decltype(_Unwrap_iter<_Sent>(_STD declval<_Iter>()))>;
using _Unwrap_iter_t = remove_cvref_t<decltype(_RANGES _Unwrap_iter<_Sent>(_STD declval<_Iter>()))>;
template <class _Sent, class _Iter>
using _Unwrap_sent_t = remove_cvref_t<decltype(_Unwrap_sent<_Iter>(_STD declval<_Sent>()))>;
using _Unwrap_sent_t = remove_cvref_t<decltype(_RANGES _Unwrap_sent<_Iter>(_STD declval<_Sent>()))>;
template <range _Rng>
using _Unwrapped_iterator_t = _Unwrap_iter_t<iterator_t<_Rng>, sentinel_t<_Rng>>;
@ -2565,7 +2569,7 @@ namespace ranges {
};
template <class _Ty>
concept _Can_begin = requires(_Ty& __t) { _Unwrap_range_iter<_Ty>(_RANGES begin(__t)); };
concept _Can_begin = requires(_Ty& __t) { _RANGES _Unwrap_range_iter<_Ty>(_RANGES begin(__t)); };
class _Cpo {
private:
@ -2577,10 +2581,10 @@ namespace ranges {
if constexpr (_Has_member<_Ty>) {
_STL_INTERNAL_STATIC_ASSERT(
same_as<decltype(_STD declval<_Ty>()._Unchecked_begin()), _Unwrapped_iterator_t<_Ty>>);
return {_St::_Member, noexcept(_Fake_copy_init(_STD declval<_Ty>()._Unchecked_begin()))};
return {_St::_Member, noexcept(_STD _Fake_copy_init(_STD declval<_Ty>()._Unchecked_begin()))};
} else if constexpr (_Can_begin<_Ty>) {
return {_St::_Unwrap,
noexcept(_Fake_copy_init(_Unwrap_range_iter<_Ty>(_RANGES begin(_STD declval<_Ty>()))))};
return {_St::_Unwrap, noexcept(_STD _Fake_copy_init(
_RANGES _Unwrap_range_iter<_Ty>(_RANGES begin(_STD declval<_Ty>()))))};
} else {
return {_St::_None};
}
@ -2598,7 +2602,7 @@ namespace ranges {
if constexpr (_Strat == _St::_Member) {
return _Val._Unchecked_begin();
} else if constexpr (_Strat == _St::_Unwrap) {
return _Unwrap_range_iter<_Ty>(_RANGES begin(_Val));
return _RANGES _Unwrap_range_iter<_Ty>(_RANGES begin(_Val));
} else {
static_assert(_Always_false<_Ty>, "Should be unreachable");
}
@ -2618,7 +2622,7 @@ namespace ranges {
};
template <class _Ty>
concept _Can_end = requires(_Ty& __t) { _Unwrap_range_sent<_Ty>(_RANGES end(__t)); };
concept _Can_end = requires(_Ty& __t) { _RANGES _Unwrap_range_sent<_Ty>(_RANGES end(__t)); };
class _Cpo {
private:
@ -2630,7 +2634,7 @@ namespace ranges {
if constexpr (_Has_member<_Ty>) {
return {_St::_Member, noexcept(_STD declval<_Ty>()._Unchecked_end())};
} else if constexpr (_Can_end<_Ty>) {
return {_St::_Unwrap, noexcept(_Unwrap_range_sent<_Ty>(_RANGES end(_STD declval<_Ty>())))};
return {_St::_Unwrap, noexcept(_RANGES _Unwrap_range_sent<_Ty>(_RANGES end(_STD declval<_Ty>())))};
} else {
return {_St::_None};
}
@ -2648,7 +2652,7 @@ namespace ranges {
if constexpr (_Strat == _St::_Member) {
return _Val._Unchecked_end();
} else if constexpr (_Strat == _St::_Unwrap) {
return _Unwrap_range_sent<_Ty>(_RANGES end(_Val));
return _RANGES _Unwrap_range_sent<_Ty>(_RANGES end(_Val));
} else {
static_assert(_Always_false<_Ty>, "Should be unreachable");
}
@ -4631,9 +4635,9 @@ namespace ranges {
// find the iterator in [_UFirst, _Unwrap_sent<_It>(_Last)) which equals _Unwrap_sent<_It>(_Last)
// [possibly O(N)]
if constexpr (is_same_v<_Unwrap_iter_t<_It, _Se>, _Unwrap_sent_t<_Se, _It>>) {
return _Unwrap_sent<_It>(_STD forward<_Se>(_Last));
return _RANGES _Unwrap_sent<_It>(_STD forward<_Se>(_Last));
} else {
return _RANGES next(_UFirst, _Unwrap_sent<_It>(_STD forward<_Se>(_Last)));
return _RANGES next(_UFirst, _RANGES _Unwrap_sent<_It>(_STD forward<_Se>(_Last)));
}
}
@ -4644,7 +4648,7 @@ namespace ranges {
if constexpr (same_as<decltype(_Uend(_Range)), _Unwrapped_iterator_t<_Rng>>) {
return _Uend(_Range);
} else {
return _Unwrap_range_sent<_Rng>(_RANGES end(_Range));
return _RANGES _Unwrap_range_sent<_Rng>(_RANGES end(_Range));
}
} else if constexpr (sized_range<_Rng>) {
return _RANGES next(_Ubegin(_Range), _RANGES distance(_Range));
@ -5210,33 +5214,33 @@ _INLINE_VAR constexpr bool _Equal_memcmp_is_safe =
template <class _CtgIt1, class _CtgIt2>
_NODISCARD int _Memcmp_ranges(_CtgIt1 _First1, _CtgIt1 _Last1, _CtgIt2 _First2) {
_STL_INTERNAL_STATIC_ASSERT(sizeof(_Iter_value_t<_CtgIt1>) == sizeof(_Iter_value_t<_CtgIt2>));
const auto _First1_ch = reinterpret_cast<const char*>(_To_address(_First1));
const auto _Last1_ch = reinterpret_cast<const char*>(_To_address(_Last1));
const auto _First2_ch = reinterpret_cast<const char*>(_To_address(_First2));
const auto _First1_ch = reinterpret_cast<const char*>(_STD _To_address(_First1));
const auto _Last1_ch = reinterpret_cast<const char*>(_STD _To_address(_Last1));
const auto _First2_ch = reinterpret_cast<const char*>(_STD _To_address(_First2));
return _CSTD memcmp(_First1_ch, _First2_ch, static_cast<size_t>(_Last1_ch - _First1_ch));
}
template <class _CtgIt1, class _CtgIt2>
_NODISCARD int _Memcmp_count(_CtgIt1 _First1, _CtgIt2 _First2, const size_t _Count) {
_STL_INTERNAL_STATIC_ASSERT(sizeof(_Iter_value_t<_CtgIt1>) == sizeof(_Iter_value_t<_CtgIt2>));
const auto _First1_ch = reinterpret_cast<const char*>(_To_address(_First1));
const auto _First2_ch = reinterpret_cast<const char*>(_To_address(_First2));
const auto _First1_ch = reinterpret_cast<const char*>(_STD _To_address(_First1));
const auto _First2_ch = reinterpret_cast<const char*>(_STD _To_address(_First2));
return _CSTD memcmp(_First1_ch, _First2_ch, _Count * sizeof(_Iter_value_t<_CtgIt1>));
}
_EXPORT_STD template <class _InIt1, class _InIt2, class _Pr>
_NODISCARD _CONSTEXPR20 bool equal(const _InIt1 _First1, const _InIt1 _Last1, const _InIt2 _First2, _Pr _Pred) {
// compare [_First1, _Last1) to [_First2, ...)
_Adl_verify_range(_First1, _Last1);
auto _UFirst1 = _Get_unwrapped(_First1);
const auto _ULast1 = _Get_unwrapped(_Last1);
auto _UFirst2 = _Get_unwrapped_n(_First2, _Idl_distance<_InIt1>(_UFirst1, _ULast1));
_STD _Adl_verify_range(_First1, _Last1);
auto _UFirst1 = _STD _Get_unwrapped(_First1);
const auto _ULast1 = _STD _Get_unwrapped(_Last1);
auto _UFirst2 = _STD _Get_unwrapped_n(_First2, _STD _Idl_distance<_InIt1>(_UFirst1, _ULast1));
if constexpr (_Equal_memcmp_is_safe<decltype(_UFirst1), decltype(_UFirst2), _Pr>) {
#if _HAS_CXX20
if (!_STD is_constant_evaluated())
#endif // _HAS_CXX20
{
return _Memcmp_ranges(_UFirst1, _ULast1, _UFirst2) == 0;
return _STD _Memcmp_ranges(_UFirst1, _ULast1, _UFirst2) == 0;
}
}
@ -5274,18 +5278,18 @@ _EXPORT_STD template <class _InIt1, class _InIt2, class _Pr>
_NODISCARD _CONSTEXPR20 bool equal(
const _InIt1 _First1, const _InIt1 _Last1, const _InIt2 _First2, const _InIt2 _Last2, _Pr _Pred) {
// compare [_First1, _Last1) to [_First2, _Last2)
_Adl_verify_range(_First1, _Last1);
_Adl_verify_range(_First2, _Last2);
auto _UFirst1 = _Get_unwrapped(_First1);
const auto _ULast1 = _Get_unwrapped(_Last1);
auto _UFirst2 = _Get_unwrapped(_First2);
const auto _ULast2 = _Get_unwrapped(_Last2);
_STD _Adl_verify_range(_First1, _Last1);
_STD _Adl_verify_range(_First2, _Last2);
auto _UFirst1 = _STD _Get_unwrapped(_First1);
const auto _ULast1 = _STD _Get_unwrapped(_Last1);
auto _UFirst2 = _STD _Get_unwrapped(_First2);
const auto _ULast2 = _STD _Get_unwrapped(_Last2);
if constexpr (_Is_ranges_random_iter_v<_InIt1> && _Is_ranges_random_iter_v<_InIt2>) {
if (_ULast1 - _UFirst1 != _ULast2 - _UFirst2) {
return false;
}
return _STD equal(_UFirst1, _ULast1, _UFirst2, _Pass_fn(_Pred));
return _STD equal(_UFirst1, _ULast1, _UFirst2, _STD _Pass_fn(_Pred));
} else {
for (;;) {
if (_UFirst1 == _ULast1) {
@ -5402,8 +5406,8 @@ namespace ranges {
_NODISCARD constexpr mismatch_result<_It1, _It2> operator()(_It1 _First1, _Se1 _Last1,
_It2 _First2, _Se2 _Last2, _Pr _Pred = {}, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const {
// clang-format on
_Adl_verify_range(_First1, _Last1);
_Adl_verify_range(_First2, _Last2);
_STD _Adl_verify_range(_First1, _Last1);
_STD _Adl_verify_range(_First2, _Last2);
if constexpr (sized_sentinel_for<_Se1, _It1> && sized_sentinel_for<_Se2, _It2>) {
iter_difference_t<_It1> _Count1 = _Last1 - _First1;
@ -5412,17 +5416,19 @@ namespace ranges {
_Count1 = static_cast<decltype(_Count1)>(_Count2);
}
auto _Result = _RANGES _Mismatch_n(_Get_unwrapped(_STD move(_First1)),
_Get_unwrapped(_STD move(_First2)), _Count1, _Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2));
_Seek_wrapped(_First1, _STD move(_Result.in1));
_Seek_wrapped(_First2, _STD move(_Result.in2));
auto _Result = _RANGES _Mismatch_n(_STD _Get_unwrapped(_STD move(_First1)),
_STD _Get_unwrapped(_STD move(_First2)), _Count1, _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1),
_STD _Pass_fn(_Proj2));
_STD _Seek_wrapped(_First1, _STD move(_Result.in1));
_STD _Seek_wrapped(_First2, _STD move(_Result.in2));
return {_STD move(_First1), _STD move(_First2)};
} else {
auto _Result = _RANGES _Mismatch_4(_Unwrap_iter<_Se1>(_STD move(_First1)),
_Unwrap_sent<_It1>(_STD move(_Last1)), _Unwrap_iter<_Se2>(_STD move(_First2)),
_Unwrap_sent<_It2>(_STD move(_Last2)), _Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2));
_Seek_wrapped(_First1, _STD move(_Result.in1));
_Seek_wrapped(_First2, _STD move(_Result.in2));
auto _Result = _RANGES _Mismatch_4(_RANGES _Unwrap_iter<_Se1>(_STD move(_First1)),
_RANGES _Unwrap_sent<_It1>(_STD move(_Last1)), _RANGES _Unwrap_iter<_Se2>(_STD move(_First2)),
_RANGES _Unwrap_sent<_It2>(_STD move(_Last2)), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1),
_STD _Pass_fn(_Proj2));
_STD _Seek_wrapped(_First1, _STD move(_Result.in1));
_STD _Seek_wrapped(_First2, _STD move(_Result.in2));
return {_STD move(_First1), _STD move(_First2)};
}
}
@ -5441,19 +5447,20 @@ namespace ranges {
auto _First1 = _RANGES begin(_Range1);
auto _First2 = _RANGES begin(_Range2);
auto _Result = _RANGES _Mismatch_n(_Get_unwrapped(_STD move(_First1)),
_Get_unwrapped(_STD move(_First2)), _Count1, _Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2));
_Seek_wrapped(_First1, _STD move(_Result.in1));
_Seek_wrapped(_First2, _STD move(_Result.in2));
auto _Result = _RANGES _Mismatch_n(_STD _Get_unwrapped(_STD move(_First1)),
_STD _Get_unwrapped(_STD move(_First2)), _Count1, _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1),
_STD _Pass_fn(_Proj2));
_STD _Seek_wrapped(_First1, _STD move(_Result.in1));
_STD _Seek_wrapped(_First2, _STD move(_Result.in2));
return {_STD move(_First1), _STD move(_First2)};
} else {
auto _First1 = _RANGES begin(_Range1);
auto _First2 = _RANGES begin(_Range2);
auto _Result = _RANGES _Mismatch_4(_Unwrap_range_iter<_Rng1>(_STD move(_First1)), _Uend(_Range1),
_Unwrap_range_iter<_Rng2>(_STD move(_First2)), _Uend(_Range2), _Pass_fn(_Pred), _Pass_fn(_Proj1),
_Pass_fn(_Proj2));
_Seek_wrapped(_First1, _STD move(_Result.in1));
_Seek_wrapped(_First2, _STD move(_Result.in2));
auto _Result = _RANGES _Mismatch_4(_RANGES _Unwrap_range_iter<_Rng1>(_STD move(_First1)),
_Uend(_Range1), _RANGES _Unwrap_range_iter<_Rng2>(_STD move(_First2)), _Uend(_Range2),
_STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), _STD _Pass_fn(_Proj2));
_STD _Seek_wrapped(_First1, _STD move(_Result.in1));
_STD _Seek_wrapped(_First2, _STD move(_Result.in2));
return {_STD move(_First1), _STD move(_First2)};
}
}
@ -5778,8 +5785,8 @@ _NODISCARD _CONSTEXPR20 _InIt _Find_unchecked(_InIt _First, const _InIt _Last, c
return _Last;
}
#if _USE_STD_VECTOR_ALGORITHMS
const auto _First_ptr = _To_address(_First);
const auto _Result = __std_find_trivial(_First_ptr, _To_address(_Last), _Val);
const auto _First_ptr = _STD _To_address(_First);
const auto _Result = _STD __std_find_trivial(_First_ptr, _STD _To_address(_Last), _Val);
if constexpr (is_pointer_v<_InIt>) {
return _Result;
} else {
@ -5787,7 +5794,7 @@ _NODISCARD _CONSTEXPR20 _InIt _Find_unchecked(_InIt _First, const _InIt _Last, c
}
#else // ^^^ _USE_STD_VECTOR_ALGORITHMS / !_USE_STD_VECTOR_ALGORITHMS vvv
if constexpr (sizeof(_Iter_value_t<_InIt>) == 1) {
const auto _First_ptr = _To_address(_First);
const auto _First_ptr = _STD _To_address(_First);
const auto _Result = static_cast<remove_reference_t<_Iter_ref_t<_InIt>>*>(
_CSTD memchr(_First_ptr, static_cast<unsigned char>(_Val), static_cast<size_t>(_Last - _First)));
if constexpr (is_pointer_v<_InIt>) {
@ -5812,11 +5819,11 @@ _NODISCARD _CONSTEXPR20 _InIt _Find_unchecked(_InIt _First, const _InIt _Last, c
_EXPORT_STD template <class _InIt, class _Ty>
_NODISCARD _CONSTEXPR20 _InIt find(_InIt _First, const _InIt _Last, const _Ty& _Val) { // find first matching _Val
_Adl_verify_range(_First, _Last);
_STD _Adl_verify_range(_First, _Last);
if constexpr (_Is_vb_iterator<_InIt> && is_same_v<_Ty, bool>) {
return _Find_vbool(_First, _Last, _Val);
} else {
_Seek_wrapped(_First, _STD _Find_unchecked(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Val));
_STD _Seek_wrapped(_First, _STD _Find_unchecked(_STD _Get_unwrapped(_First), _STD _Get_unwrapped(_Last), _Val));
return _First;
}
}
@ -5854,16 +5861,16 @@ namespace ranges {
using _Ptr_t = remove_reference_t<_Iter_ref_t<_It>>*;
#if _USE_STD_VECTOR_ALGORITHMS
const auto _First_ptr = _To_address(_First);
const auto _First_ptr = _STD _To_address(_First);
_Ptr_t _Result;
if constexpr (_Is_sized) {
const auto _Last_ptr = _First_ptr + (_Last - _First);
_Result = __std_find_trivial(_First_ptr, _Last_ptr, _Val);
_Result = _STD __std_find_trivial(_First_ptr, _Last_ptr, _Val);
} else {
_Result = __std_find_trivial_unsized(_First_ptr, _Val);
_Result = _STD __std_find_trivial_unsized(_First_ptr, _Val);
}
if constexpr (is_pointer_v<_It>) {
@ -5914,11 +5921,11 @@ namespace ranges {
requires indirect_binary_predicate<ranges::equal_to, projected<_It, _Pj>, const _Ty*>
_NODISCARD constexpr _It operator()(_It _First, _Se _Last, const _Ty& _Val, _Pj _Proj = {}) const {
// clang-format on
_Adl_verify_range(_First, _Last);
auto _UResult = _RANGES _Find_unchecked(
_Unwrap_iter<_Se>(_STD move(_First)), _Unwrap_sent<_It>(_STD move(_Last)), _Val, _Pass_fn(_Proj));
_STD _Adl_verify_range(_First, _Last);
auto _UResult = _RANGES _Find_unchecked(_RANGES _Unwrap_iter<_Se>(_STD move(_First)),
_RANGES _Unwrap_sent<_It>(_STD move(_Last)), _Val, _STD _Pass_fn(_Proj));
_Seek_wrapped(_First, _STD move(_UResult));
_STD _Seek_wrapped(_First, _STD move(_UResult));
return _First;
}
@ -5928,9 +5935,9 @@ namespace ranges {
_Rng&& _Range, const _Ty& _Val, _Pj _Proj = {}) const {
auto _First = _RANGES begin(_Range);
auto _UResult = _RANGES _Find_unchecked(
_Unwrap_range_iter<_Rng>(_STD move(_First)), _Uend(_Range), _Val, _Pass_fn(_Proj));
_RANGES _Unwrap_range_iter<_Rng>(_STD move(_First)), _Uend(_Range), _Val, _STD _Pass_fn(_Proj));
_Seek_wrapped(_First, _STD move(_UResult));
_STD _Seek_wrapped(_First, _STD move(_UResult));
return _First;
}
};
@ -5942,12 +5949,12 @@ namespace ranges {
_EXPORT_STD template <class _InIt, class _Ty>
_NODISCARD _CONSTEXPR20 _Iter_diff_t<_InIt> count(const _InIt _First, const _InIt _Last, const _Ty& _Val) {
// count elements that match _Val
_Adl_verify_range(_First, _Last);
_STD _Adl_verify_range(_First, _Last);
if constexpr (_Is_vb_iterator<_InIt> && is_same_v<_Ty, bool>) {
return _Count_vbool(_First, _Last, _Val);
} else {
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
#if _USE_STD_VECTOR_ALGORITHMS
if constexpr (_Vector_alg_in_find_is_safe<decltype(_UFirst), _Ty>) {
@ -5960,7 +5967,7 @@ _NODISCARD _CONSTEXPR20 _Iter_diff_t<_InIt> count(const _InIt _First, const _InI
}
return static_cast<_Iter_diff_t<_InIt>>(
__std_count_trivial(_To_address(_UFirst), _To_address(_ULast), _Val));
_STD __std_count_trivial(_STD _To_address(_UFirst), _STD _To_address(_ULast), _Val));
}
}
#endif // _USE_STD_VECTOR_ALGORITHMS
@ -6095,9 +6102,9 @@ _NODISCARD _CONSTEXPR20 _TrimResult _Trim_completely(
for (bool _Check_reversed = true; _Res == _TrimResult::_KeepTrimming; _Check_reversed = !_Check_reversed) {
if (_Check_reversed) {
_Res = _Trim_reversed(_First1, _Back1, _First2, _Back2, _Pred);
_Res = _STD _Trim_reversed(_First1, _Back1, _First2, _Back2, _Pred);
} else {
_Res = _Trim_equal(_First1, _Back1, _First2, _Back2, _Pred);
_Res = _STD _Trim_equal(_First1, _Back1, _First2, _Back2, _Pred);
}
}
@ -6120,7 +6127,7 @@ _NODISCARD _CONSTEXPR20 bool _Check_match_counts(
return false;
}
const _TrimResult _Res = _Trim_completely(_First1, _Last1, _First2, _Last2, _Pred);
const _TrimResult _Res = _STD _Trim_completely(_First1, _Last1, _First2, _Last2, _Pred);
if (_Res != _TrimResult::_HaveWorkAfterTrimming) {
return _Res == _TrimResult::_ReturnTrue;
@ -6131,14 +6138,14 @@ _NODISCARD _CONSTEXPR20 bool _Check_match_counts(
}
for (_FwdIt1 _Next1 = _First1; _Next1 != _Last1; ++_Next1) {
if (_Next1 == _Find_pr(_First1, _Next1, *_Next1, _Pred)) { // new value, compare match counts
_Iter_diff_t<_FwdIt2> _Count2 = _Count_pr(_First2, _Last2, *_Next1, _Pred);
if (_Next1 == _STD _Find_pr(_First1, _Next1, *_Next1, _Pred)) { // new value, compare match counts
_Iter_diff_t<_FwdIt2> _Count2 = _STD _Count_pr(_First2, _Last2, *_Next1, _Pred);
if (_Count2 == 0) {
return false; // second range lacks value, not a permutation
}
_FwdIt1 _Skip1 = _Next_iter(_Next1);
_Iter_diff_t<_FwdIt1> _Count1 = _Count_pr(_Skip1, _Last1, *_Next1, _Pred) + 1;
_FwdIt1 _Skip1 = _STD _Next_iter(_Next1);
_Iter_diff_t<_FwdIt1> _Count1 = _STD _Count_pr(_Skip1, _Last1, *_Next1, _Pred) + 1;
if (_Count2 != _Count1) {
return false; // match counts differ, not a permutation
}
@ -6273,16 +6280,16 @@ _FwdIt rotate(_ExPo&&, _FwdIt _First, _FwdIt _Mid, _FwdIt _Last) noexcept /* ter
_EXPORT_STD template <class _InIt, class _Pr>
_NODISCARD _CONSTEXPR20 _InIt find_if(_InIt _First, const _InIt _Last, _Pr _Pred) { // find first satisfying _Pred
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
for (; _UFirst != _ULast; ++_UFirst) {
if (_Pred(*_UFirst)) {
break;
}
}
_Seek_wrapped(_First, _UFirst);
_STD _Seek_wrapped(_First, _UFirst);
return _First;
}
@ -6333,11 +6340,11 @@ namespace ranges {
template <input_iterator _It, sentinel_for<_It> _Se, class _Pj = identity,
indirect_unary_predicate<projected<_It, _Pj>> _Pr>
_NODISCARD constexpr _It operator()(_It _First, _Se _Last, _Pr _Pred, _Pj _Proj = {}) const {
_Adl_verify_range(_First, _Last);
auto _UResult = _RANGES _Find_if_unchecked(_Unwrap_iter<_Se>(_STD move(_First)),
_Unwrap_sent<_It>(_STD move(_Last)), _Pass_fn(_Pred), _Pass_fn(_Proj));
_STD _Adl_verify_range(_First, _Last);
auto _UResult = _RANGES _Find_if_unchecked(_RANGES _Unwrap_iter<_Se>(_STD move(_First)),
_RANGES _Unwrap_sent<_It>(_STD move(_Last)), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj));
_Seek_wrapped(_First, _STD move(_UResult));
_STD _Seek_wrapped(_First, _STD move(_UResult));
return _First;
}
@ -6345,10 +6352,10 @@ namespace ranges {
indirect_unary_predicate<projected<iterator_t<_Rng>, _Pj>> _Pr>
_NODISCARD constexpr borrowed_iterator_t<_Rng> operator()(_Rng&& _Range, _Pr _Pred, _Pj _Proj = {}) const {
auto _First = _RANGES begin(_Range);
auto _UResult = _RANGES _Find_if_unchecked(
_Unwrap_range_iter<_Rng>(_STD move(_First)), _Uend(_Range), _Pass_fn(_Pred), _Pass_fn(_Proj));
auto _UResult = _RANGES _Find_if_unchecked(_RANGES _Unwrap_range_iter<_Rng>(_STD move(_First)),
_Uend(_Range), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj));
_Seek_wrapped(_First, _STD move(_UResult));
_STD _Seek_wrapped(_First, _STD move(_UResult));
return _First;
}
};
@ -6360,12 +6367,12 @@ namespace ranges {
template <input_iterator _It, sentinel_for<_It> _Se, class _Pj = identity,
indirect_unary_predicate<projected<_It, _Pj>> _Pr>
_NODISCARD constexpr _It operator()(_It _First, _Se _Last, _Pr _Pred, _Pj _Proj = {}) const {
_Adl_verify_range(_First, _Last);
_STD _Adl_verify_range(_First, _Last);
auto _UResult = _Find_if_not_unchecked(_Unwrap_iter<_Se>(_STD move(_First)),
_Unwrap_sent<_It>(_STD move(_Last)), _Pass_fn(_Pred), _Pass_fn(_Proj));
auto _UResult = _Find_if_not_unchecked(_RANGES _Unwrap_iter<_Se>(_STD move(_First)),
_RANGES _Unwrap_sent<_It>(_STD move(_Last)), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj));
_Seek_wrapped(_First, _STD move(_UResult));
_STD _Seek_wrapped(_First, _STD move(_UResult));
return _First;
}
@ -6374,10 +6381,10 @@ namespace ranges {
_NODISCARD constexpr borrowed_iterator_t<_Rng> operator()(_Rng&& _Range, _Pr _Pred, _Pj _Proj = {}) const {
auto _First = _RANGES begin(_Range);
auto _UResult = _Find_if_not_unchecked(
_Unwrap_range_iter<_Rng>(_STD move(_First)), _Uend(_Range), _Pass_fn(_Pred), _Pass_fn(_Proj));
auto _UResult = _Find_if_not_unchecked(_RANGES _Unwrap_range_iter<_Rng>(_STD move(_First)), _Uend(_Range),
_STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj));
_Seek_wrapped(_First, _STD move(_UResult));
_STD _Seek_wrapped(_First, _STD move(_UResult));
return _First;
}
@ -6405,12 +6412,12 @@ namespace ranges {
template <forward_iterator _It, sentinel_for<_It> _Se, class _Pj = identity,
indirect_binary_predicate<projected<_It, _Pj>, projected<_It, _Pj>> _Pr = ranges::equal_to>
_NODISCARD constexpr _It operator()(_It _First, _Se _Last, _Pr _Pred = {}, _Pj _Proj = {}) const {
_Adl_verify_range(_First, _Last);
_STD _Adl_verify_range(_First, _Last);
auto _UResult = _Adjacent_find_unchecked(_Unwrap_iter<_Se>(_STD move(_First)),
_Unwrap_sent<_It>(_STD move(_Last)), _Pass_fn(_Pred), _Pass_fn(_Proj));
auto _UResult = _Adjacent_find_unchecked(_RANGES _Unwrap_iter<_Se>(_STD move(_First)),
_RANGES _Unwrap_sent<_It>(_STD move(_Last)), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj));
_Seek_wrapped(_First, _STD move(_UResult));
_STD _Seek_wrapped(_First, _STD move(_UResult));
return _First;
}
@ -6418,9 +6425,10 @@ namespace ranges {
indirect_binary_predicate<projected<iterator_t<_Rng>, _Pj>, projected<iterator_t<_Rng>, _Pj>> _Pr =
ranges::equal_to>
_NODISCARD constexpr borrowed_iterator_t<_Rng> operator()(_Rng&& _Range, _Pr _Pred = {}, _Pj _Proj = {}) const {
auto _UResult = _Adjacent_find_unchecked(_Ubegin(_Range), _Uend(_Range), _Pass_fn(_Pred), _Pass_fn(_Proj));
auto _UResult =
_Adjacent_find_unchecked(_Ubegin(_Range), _Uend(_Range), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj));
return _Rewrap_iterator(_Range, _STD move(_UResult));
return _RANGES _Rewrap_iterator(_Range, _STD move(_UResult));
}
private:
@ -6466,9 +6474,9 @@ namespace ranges {
if (!_STD is_constant_evaluated()) {
bool _Ans;
if constexpr (same_as<_It2, _Se2>) {
_Ans = _Memcmp_ranges(_First2, _Last2, _First1) == 0;
_Ans = _STD _Memcmp_ranges(_First2, _Last2, _First1) == 0;
} else {
_Ans = _Memcmp_count(_First1, _First2, static_cast<size_t>(_Last2 - _First2)) == 0;
_Ans = _STD _Memcmp_count(_First1, _First2, static_cast<size_t>(_Last2 - _First2)) == 0;
}
if (_Ans) {
@ -6496,23 +6504,23 @@ namespace ranges {
requires indirectly_comparable<_It1, _It2, _Pr, _Pj1, _Pj2>
_NODISCARD constexpr subrange<_It1> operator()(_It1 _First1, _Se1 _Last1, _It2 _First2, _Se2 _Last2,
_Pr _Pred = {}, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const {
_Adl_verify_range(_First1, _Last1);
_Adl_verify_range(_First2, _Last2);
auto _UFirst1 = _Unwrap_iter<_Se1>(_STD move(_First1));
auto _ULast1 = _Unwrap_sent<_It1>(_STD move(_Last1));
auto _UFirst2 = _Unwrap_iter<_Se2>(_STD move(_First2));
auto _ULast2 = _Unwrap_sent<_It2>(_STD move(_Last2));
_STD _Adl_verify_range(_First1, _Last1);
_STD _Adl_verify_range(_First2, _Last2);
auto _UFirst1 = _RANGES _Unwrap_iter<_Se1>(_STD move(_First1));
auto _ULast1 = _RANGES _Unwrap_sent<_It1>(_STD move(_Last1));
auto _UFirst2 = _RANGES _Unwrap_iter<_Se2>(_STD move(_First2));
auto _ULast2 = _RANGES _Unwrap_sent<_It2>(_STD move(_Last2));
if constexpr (sized_sentinel_for<_Se1, _It1> && sized_sentinel_for<_Se2, _It2>) {
const auto _Count1 = _ULast1 - _UFirst1;
const auto _Count2 = _ULast2 - _UFirst2;
auto _UResult = _Search_sized(_STD move(_UFirst1), _STD move(_ULast1), _Count1, _STD move(_UFirst2),
_STD move(_ULast2), _Count2, _Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2));
return _Rewrap_subrange<subrange<_It1>>(_First1, _STD move(_UResult));
_STD move(_ULast2), _Count2, _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), _STD _Pass_fn(_Proj2));
return _RANGES _Rewrap_subrange<subrange<_It1>>(_First1, _STD move(_UResult));
} else {
auto _UResult = _Search_unsized(_STD move(_UFirst1), _STD move(_ULast1), _STD move(_UFirst2),
_STD move(_ULast2), _Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2));
return _Rewrap_subrange<subrange<_It1>>(_First1, _STD move(_UResult));
_STD move(_ULast2), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), _STD _Pass_fn(_Proj2));
return _RANGES _Rewrap_subrange<subrange<_It1>>(_First1, _STD move(_UResult));
}
}
@ -6525,12 +6533,12 @@ namespace ranges {
const auto _Count1 = _RANGES distance(_Range1);
const auto _Count2 = _RANGES distance(_Range2);
auto _UResult = _Search_sized(_Ubegin(_Range1), _Uend(_Range1), _Count1, _Ubegin(_Range2),
_Uend(_Range2), _Count2, _Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2));
return _Rewrap_subrange<borrowed_subrange_t<_Rng1>>(_Range1, _STD move(_UResult));
_Uend(_Range2), _Count2, _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), _STD _Pass_fn(_Proj2));
return _RANGES _Rewrap_subrange<borrowed_subrange_t<_Rng1>>(_Range1, _STD move(_UResult));
} else {
auto _UResult = _Search_unsized(_Ubegin(_Range1), _Uend(_Range1), _Ubegin(_Range2), _Uend(_Range2),
_Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2));
return _Rewrap_subrange<borrowed_subrange_t<_Rng1>>(_Range1, _STD move(_UResult));
_STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), _STD _Pass_fn(_Proj2));
return _RANGES _Rewrap_subrange<borrowed_subrange_t<_Rng1>>(_Range1, _STD move(_UResult));
}
}
@ -6548,13 +6556,13 @@ namespace ranges {
_STL_INTERNAL_CHECK(_RANGES distance(_First2, _Last2) == _Count2);
for (; _Count1 >= _Count2; ++_First1, (void) --_Count1) {
auto [_Match, _Mid1] = _RANGES _Equal_rev_pred(_First1, _First2, _Last2, _Pred, _Proj1, _Proj2);
if (_Match) {
return {_STD move(_First1), _STD move(_Mid1)};
auto _Match_and_mid1 = _RANGES _Equal_rev_pred(_First1, _First2, _Last2, _Pred, _Proj1, _Proj2);
if (_Match_and_mid1.first) {
return {_STD move(_First1), _STD move(_Match_and_mid1.second)};
}
}
_First1 = _Find_last_iterator(_First1, _Last1, _Count1);
_First1 = _RANGES _Find_last_iterator(_First1, _Last1, _Count1);
return {_First1, _First1};
}
@ -6607,7 +6615,7 @@ constexpr _FwdIt _Max_element_unchecked(_FwdIt _First, _FwdIt _Last, _Pr _Pred)
if constexpr (_Is_min_max_optimization_safe<_FwdIt, _Pr>) {
if (!_Is_constant_evaluated()) {
const auto _First_ptr = _To_address(_First);
const auto _Result = __std_max_element(_First_ptr, _To_address(_Last));
const auto _Result = _STD __std_max_element(_First_ptr, _To_address(_Last));
if constexpr (is_pointer_v<_FwdIt>) {
return _Result;
} else {
@ -6672,7 +6680,7 @@ namespace ranges {
if (!_STD is_constant_evaluated()) {
const auto _First_ptr = _STD to_address(_First);
const auto _Last_ptr = _First_ptr + (_Last - _First);
const auto _Result = __std_max_element(_First_ptr, _Last_ptr);
const auto _Result = _STD __std_max_element(_First_ptr, _Last_ptr);
if constexpr (is_pointer_v<_It>) {
return _Result;
} else {
@ -6799,7 +6807,7 @@ constexpr _FwdIt _Min_element_unchecked(_FwdIt _First, _FwdIt _Last, _Pr _Pred)
if constexpr (_Is_min_max_optimization_safe<_FwdIt, _Pr>) {
if (!_Is_constant_evaluated()) {
const auto _First_ptr = _To_address(_First);
const auto _Result = __std_min_element(_First_ptr, _To_address(_Last));
const auto _Result = _STD __std_min_element(_First_ptr, _To_address(_Last));
if constexpr (is_pointer_v<_FwdIt>) {
return _Result;
} else {
@ -6864,7 +6872,7 @@ namespace ranges {
if (!_STD is_constant_evaluated()) {
const auto _First_ptr = _STD to_address(_First);
const auto _Last_ptr = _First_ptr + (_Last - _First);
const auto _Result = __std_min_element(_First_ptr, _Last_ptr);
const auto _Result = _STD __std_min_element(_First_ptr, _Last_ptr);
if constexpr (is_pointer_v<_It>) {
return _Result;
} else {

Просмотреть файл

@ -189,6 +189,7 @@ tests\GH_001277_num_get_bad_grouping
tests\GH_001411_core_headers
tests\GH_001530_binomial_accuracy
tests\GH_001541_case_sensitive_boolalpha
tests\GH_001596_adl_proof_algorithms
tests\GH_001638_dllexport_derived_classes
tests\GH_001850_clog_tied_to_cout
tests\GH_001858_iostream_exception

Просмотреть файл

@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
RUNALL_INCLUDE ..\usual_matrix.lst

Просмотреть файл

@ -0,0 +1,238 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef _M_CEE // TRANSITION, VSO-1659496
#include <algorithm>
#include <cstddef>
#if _HAS_CXX17
#include <execution>
#endif // _HAS_CXX17
#include <type_traits>
#include <utility>
template <class Tag>
struct tagged_truth {
template <class T>
constexpr bool operator()(T&&) const noexcept {
return true;
}
};
template <class Tag>
struct tagged_equal {
template <class T, class U>
constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) == std::forward<U>(u)) {
return std::forward<T>(t) == std::forward<U>(u);
}
};
template <class T>
struct holder {
T t;
};
#if _HAS_CXX23 && defined(__cpp_lib_concepts) // TRANSITION, GH-395
template <class Tag>
struct tagged_left_selector {
template <class T>
constexpr T operator()(T lhs, T) const noexcept {
return lhs;
}
};
#endif // _HAS_CXX23 && defined(__cpp_lib_concepts)
struct incomplete;
using simple_truth = tagged_truth<void>;
using validator = holder<incomplete>*;
using validating_truth = tagged_truth<holder<incomplete>>;
using validating_equal = tagged_equal<holder<incomplete>>;
#if _HAS_CXX23 && defined(__cpp_lib_concepts) // TRANSITION, GH-395
using simple_left_selector = tagged_left_selector<void>;
using validating_left_selector = tagged_left_selector<holder<incomplete>>;
#endif // _HAS_CXX23 && defined(__cpp_lib_concepts)
void test_algorithms() {
int iarr[1]{};
validator varr[1]{};
(void) std::all_of(varr, varr, simple_truth{});
(void) std::all_of(iarr, iarr, validating_truth{});
(void) std::any_of(varr, varr, simple_truth{});
(void) std::any_of(iarr, iarr, validating_truth{});
(void) std::none_of(varr, varr, simple_truth{});
(void) std::none_of(iarr, iarr, validating_truth{});
(void) std::for_each(varr, varr, simple_truth{});
(void) std::for_each(varr, varr, validating_truth{});
(void) std::for_each(iarr, iarr, validating_truth{});
#if _HAS_CXX17
(void) std::for_each_n(varr, 0, simple_truth{});
(void) std::for_each_n(varr, 0, validating_truth{});
(void) std::for_each_n(iarr, 0, validating_truth{});
#endif // _HAS_CXX17
(void) std::find(varr, varr, validator{});
(void) std::find_if(varr, varr, simple_truth{});
(void) std::find_if(iarr, iarr, validating_truth{});
(void) std::find_if_not(varr, varr, simple_truth{});
(void) std::find_if_not(iarr, iarr, validating_truth{});
(void) std::find_end(varr, varr, varr, varr);
(void) std::find_end(varr, varr, varr, varr, validating_equal{});
(void) std::find_end(iarr, iarr, iarr, iarr, validating_equal{});
(void) std::find_first_of(varr, varr, varr, varr);
(void) std::find_first_of(varr, varr, varr, varr, validating_equal{});
(void) std::find_first_of(iarr, iarr, iarr, iarr, validating_equal{});
(void) std::adjacent_find(varr, varr);
(void) std::adjacent_find(iarr, iarr, validating_equal{});
(void) std::count(varr, varr, validator{});
(void) std::count_if(varr, varr, simple_truth{});
(void) std::count_if(iarr, iarr, validating_truth{});
(void) std::mismatch(varr, varr, varr);
(void) std::mismatch(varr, varr, varr, varr);
(void) std::mismatch(iarr, iarr, iarr, validating_equal{});
(void) std::mismatch(iarr, iarr, iarr, iarr, validating_equal{});
(void) std::equal(varr, varr, varr);
(void) std::equal(varr, varr, varr, varr);
(void) std::equal(iarr, iarr, iarr, validating_equal{});
(void) std::equal(iarr, iarr, iarr, iarr, validating_equal{});
(void) std::is_permutation(varr, varr, varr);
(void) std::is_permutation(varr, varr, varr, validating_equal{});
(void) std::is_permutation(varr, varr, varr, varr);
(void) std::is_permutation(varr, varr, varr, varr, validating_equal{});
(void) std::is_permutation(iarr, iarr, iarr, validating_equal{});
(void) std::is_permutation(iarr, iarr, iarr, iarr, validating_equal{});
(void) std::search(varr, varr, varr, varr);
(void) std::search(iarr, iarr, iarr, iarr, validating_equal{});
}
#if _HAS_CXX17
template <auto& ExecutionPolicy>
void test_per_execution_policy() {
int iarr[1]{};
validator varr[1]{};
(void) std::all_of(ExecutionPolicy, varr, varr, simple_truth{});
(void) std::all_of(ExecutionPolicy, iarr, iarr, validating_truth{});
(void) std::any_of(ExecutionPolicy, varr, varr, simple_truth{});
(void) std::any_of(ExecutionPolicy, iarr, iarr, validating_truth{});
(void) std::none_of(ExecutionPolicy, varr, varr, simple_truth{});
(void) std::none_of(ExecutionPolicy, iarr, iarr, validating_truth{});
std::for_each(ExecutionPolicy, varr, varr, simple_truth{});
std::for_each(ExecutionPolicy, varr, varr, validating_truth{});
std::for_each(ExecutionPolicy, iarr, iarr, validating_truth{});
(void) std::for_each_n(ExecutionPolicy, varr, 0, simple_truth{});
(void) std::for_each_n(ExecutionPolicy, varr, 0, validating_truth{});
(void) std::for_each_n(ExecutionPolicy, iarr, 0, validating_truth{});
(void) std::find(ExecutionPolicy, varr, varr, validator{});
(void) std::find_if(ExecutionPolicy, varr, varr, simple_truth{});
(void) std::find_if(ExecutionPolicy, iarr, iarr, validating_truth{});
(void) std::find_if_not(ExecutionPolicy, varr, varr, simple_truth{});
(void) std::find_if_not(ExecutionPolicy, iarr, iarr, validating_truth{});
(void) std::find_end(ExecutionPolicy, varr, varr, varr, varr);
(void) std::find_end(ExecutionPolicy, varr, varr, varr, varr, validating_equal{});
(void) std::find_end(ExecutionPolicy, iarr, iarr, iarr, iarr, validating_equal{});
(void) std::find_first_of(ExecutionPolicy, varr, varr, varr, varr);
(void) std::find_first_of(ExecutionPolicy, varr, varr, varr, varr, validating_equal{});
(void) std::find_first_of(ExecutionPolicy, iarr, iarr, iarr, iarr, validating_equal{});
(void) std::adjacent_find(ExecutionPolicy, varr, varr);
(void) std::adjacent_find(ExecutionPolicy, iarr, iarr, validating_equal{});
(void) std::count(ExecutionPolicy, varr, varr, validator{});
(void) std::count_if(ExecutionPolicy, varr, varr, simple_truth{});
(void) std::count_if(ExecutionPolicy, iarr, iarr, validating_truth{});
(void) std::mismatch(ExecutionPolicy, varr, varr, varr);
(void) std::mismatch(ExecutionPolicy, varr, varr, varr, varr);
(void) std::mismatch(ExecutionPolicy, iarr, iarr, iarr, validating_equal{});
(void) std::mismatch(ExecutionPolicy, iarr, iarr, iarr, iarr, validating_equal{});
(void) std::equal(ExecutionPolicy, varr, varr, varr);
(void) std::equal(ExecutionPolicy, varr, varr, varr, varr);
(void) std::equal(ExecutionPolicy, iarr, iarr, iarr, validating_equal{});
(void) std::equal(ExecutionPolicy, iarr, iarr, iarr, iarr, validating_equal{});
(void) std::search(ExecutionPolicy, varr, varr, varr, varr);
(void) std::search(ExecutionPolicy, iarr, iarr, iarr, iarr, validating_equal{});
(void) std::search_n(ExecutionPolicy, varr, varr, 0, validator{});
(void) std::search_n(ExecutionPolicy, iarr, iarr, 0, 0, validating_equal{});
}
void test_parallel_algorithms() {
test_per_execution_policy<std::execution::seq>();
test_per_execution_policy<std::execution::par>();
test_per_execution_policy<std::execution::par_unseq>();
#if _HAS_CXX20
test_per_execution_policy<std::execution::unseq>();
#endif // _HAS_CXX20
}
#endif // _HAS_CXX17
#if _HAS_CXX23 && defined(__cpp_lib_concepts) // TRANSITION, GH-395
void test_ranges_non_projected_algorithms() {
using namespace std::ranges;
int iarr[1]{};
validator varr[1]{};
(void) fold_left(varr, varr, validator{}, simple_left_selector{});
(void) fold_left(varr, validator{}, simple_left_selector{});
(void) fold_left(iarr, iarr, 0, validating_left_selector{});
(void) fold_left(iarr, 0, validating_left_selector{});
(void) fold_left_first(varr, varr + 1, simple_left_selector{});
(void) fold_left_first(varr, simple_left_selector{});
(void) fold_left_first(iarr, iarr + 1, validating_left_selector{});
(void) fold_left_first(iarr, validating_left_selector{});
(void) fold_right(varr, varr, validator{}, simple_left_selector{});
(void) fold_right(varr, validator{}, simple_left_selector{});
(void) fold_right(iarr, iarr, 0, validating_left_selector{});
(void) fold_right(iarr, 0, validating_left_selector{});
(void) fold_right_last(varr, varr + 1, simple_left_selector{});
(void) fold_right_last(varr, simple_left_selector{});
(void) fold_right_last(iarr, iarr + 1, validating_left_selector{});
(void) fold_right_last(iarr, validating_left_selector{});
(void) fold_left_with_iter(varr, varr, validator{}, simple_left_selector{});
(void) fold_left_with_iter(varr, validator{}, simple_left_selector{});
(void) fold_left_with_iter(iarr, iarr, 0, validating_left_selector{});
(void) fold_left_with_iter(iarr, 0, validating_left_selector{});
(void) fold_left_first_with_iter(varr, varr, simple_left_selector{});
(void) fold_left_first_with_iter(varr, simple_left_selector{});
(void) fold_left_first_with_iter(iarr, iarr, validating_left_selector{});
(void) fold_left_first_with_iter(iarr, validating_left_selector{});
}
#endif // _HAS_CXX23 && defined(__cpp_lib_concepts)
#endif // _M_CEE

Просмотреть файл

@ -2,53 +2,218 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef _M_CEE // TRANSITION, VSO-1659496
#include <algorithm>
#include <cassert>
#include <functional>
#include <iterator>
#include <ranges>
#include <utility>
using namespace std;
// TRANSITION, GH-1596, should use ranges::count
struct my_count_fn {
template <input_iterator I, sentinel_for<I> S, class T, class Proj = identity>
requires indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
constexpr iter_difference_t<I> operator()(I first, S last, const T& value, Proj proj = {}) const {
iter_difference_t<I> counter = 0;
for (; first != last; ++first) {
if (std::invoke(proj, *first) == value) { // intentionally qualified to avoid ADL
++counter;
}
}
return counter;
}
template <ranges::input_range R, class T, class Proj = identity>
requires indirect_binary_predicate<ranges::equal_to, projected<ranges::iterator_t<R>, Proj>, const T*>
constexpr ranges::range_difference_t<R> operator()(R&& r, const T& value, Proj proj = {}) const {
return (*this)(ranges::begin(r), ranges::end(r), value, ref(proj));
template <class Tag>
struct tagged_truth {
template <class T>
constexpr bool operator()(T&&) const noexcept {
return true;
}
};
inline constexpr my_count_fn my_count;
template <class Tag>
struct tagged_equal {
template <class T, class U>
constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) == std::forward<U>(u)) {
return std::forward<T>(t) == std::forward<U>(u);
}
};
template <class Tag>
struct tagged_identity {
template <class T>
constexpr T&& operator()(T&& t) const noexcept {
return std::forward<T>(t);
}
};
template <class Tag>
struct tagged_left_selector {
template <class T>
constexpr T operator()(T lhs, T) const noexcept {
return lhs;
}
};
template <class T>
struct Holder {
struct holder {
T t;
};
struct Incomplete;
static_assert(equality_comparable<Holder<Incomplete>*>);
static_assert(indirectly_comparable<Holder<Incomplete>**, Holder<Incomplete>**, equal_to<>>);
static_assert(sortable<Holder<Incomplete>**>);
struct incomplete;
constexpr bool test() {
Holder<Incomplete>* a[10] = {};
assert(my_count(a, a + 10, nullptr) == 10);
assert(my_count(a, nullptr) == 10);
return true;
using simple_truth = tagged_truth<void>;
using simple_identity = tagged_identity<void>;
using validator = holder<incomplete>*;
using validating_truth = tagged_truth<holder<incomplete>>;
using validating_equal = tagged_equal<holder<incomplete>>;
using validating_identity = tagged_identity<holder<incomplete>>;
void test_ranges_algorithms() {
using namespace std::ranges;
int iarr[1]{};
validator varr[1]{};
(void) all_of(varr, varr, simple_truth{});
(void) all_of(varr, simple_truth{});
(void) all_of(iarr, iarr, validating_truth{});
(void) all_of(iarr, validating_truth{});
(void) any_of(varr, varr, simple_truth{});
(void) any_of(varr, simple_truth{});
(void) any_of(iarr, iarr, validating_truth{});
(void) any_of(iarr, validating_truth{});
(void) none_of(varr, varr, simple_truth{});
(void) none_of(varr, simple_truth{});
(void) none_of(iarr, iarr, validating_truth{});
(void) none_of(iarr, validating_truth{});
#if _HAS_CXX23
(void) contains(varr, varr, validator{});
(void) contains(varr, validator{});
(void) contains(iarr, iarr, 0, validating_identity{});
(void) contains(iarr, 0, validating_identity{});
(void) contains_subrange(varr, varr, varr, varr);
(void) contains_subrange(varr, varr);
(void) contains_subrange(iarr, iarr, iarr, iarr, validating_equal{});
// (void) contains_subrange(iarr, iarr, validating_equal{}); // needs to check ADL-found operator*
(void) contains_subrange(iarr, iarr, {}, validating_identity{});
#endif // _HAS_CXX23
(void) for_each(varr, varr, simple_truth{});
(void) for_each(varr, simple_truth{});
(void) for_each(varr, varr, validating_truth{});
(void) for_each(varr, validating_truth{});
(void) for_each(iarr, iarr, validating_truth{});
(void) for_each(iarr, validating_truth{});
(void) for_each_n(varr, 0, simple_truth{});
(void) for_each_n(varr, 0, validating_truth{});
(void) for_each_n(iarr, 0, validating_truth{});
(void) find(varr, varr, validator{});
(void) find(varr, validator{});
(void) find_if(varr, varr, simple_truth{});
(void) find_if(varr, simple_truth{});
(void) find_if(iarr, iarr, validating_truth{});
(void) find_if(iarr, validating_truth{});
(void) find_if_not(varr, varr, simple_truth{});
(void) find_if_not(varr, simple_truth{});
(void) find_if_not(iarr, iarr, validating_truth{});
(void) find_if_not(iarr, validating_truth{});
#if _HAS_CXX23
(void) find_last(varr, varr, validator{});
(void) find_last(varr, validator{});
(void) find_last_if(varr, varr, simple_truth{});
(void) find_last_if(varr, simple_truth{});
(void) find_last_if(iarr, iarr, validating_truth{});
(void) find_last_if(iarr, validating_truth{});
(void) find_last_if_not(varr, varr, simple_truth{});
(void) find_last_if_not(varr, simple_truth{});
(void) find_last_if_not(iarr, iarr, validating_truth{});
(void) find_last_if_not(iarr, validating_truth{});
#endif // _HAS_CXX23
(void) find_end(varr, varr, varr, varr);
(void) find_end(varr, varr);
(void) find_end(varr, varr, varr, varr, validating_equal{});
(void) find_end(varr, varr, validating_equal{});
(void) find_end(iarr, iarr, iarr, iarr, validating_equal{});
(void) find_end(iarr, iarr, validating_equal{});
(void) find_first_of(varr, varr, varr, varr);
(void) find_first_of(varr, varr);
(void) find_first_of(varr, varr, varr, varr, validating_equal{});
(void) find_first_of(varr, varr, validating_equal{});
(void) find_first_of(iarr, iarr, iarr, iarr, validating_equal{});
(void) find_first_of(iarr, iarr, validating_equal{});
(void) adjacent_find(varr, varr);
(void) adjacent_find(varr);
(void) adjacent_find(iarr, iarr, validating_equal{});
(void) adjacent_find(iarr, iarr, {}, validating_identity{});
// (void) adjacent_find(iarr, validating_equal{}); // needs to check ADL-found swap
(void) adjacent_find(iarr, {}, validating_identity{});
(void) count(varr, varr, validator{});
(void) count(varr, validator{});
(void) count(iarr, iarr, 0, validating_identity{});
(void) count(iarr, 0, validating_identity{});
(void) count_if(varr, varr, simple_truth{});
(void) count_if(varr, simple_truth{});
(void) count_if(iarr, iarr, validating_truth{});
(void) count_if(iarr, validating_truth{});
(void) mismatch(varr, varr, varr, varr);
(void) mismatch(varr, varr);
(void) mismatch(iarr, iarr, iarr, iarr, validating_equal{});
(void) mismatch(iarr, iarr, validating_equal{});
(void) equal(varr, varr, varr, varr);
(void) equal(varr, varr);
(void) equal(iarr, iarr, iarr, iarr, validating_equal{});
(void) equal(iarr, iarr, validating_equal{});
(void) is_permutation(varr, varr, varr, varr);
(void) is_permutation(varr, varr);
(void) is_permutation(varr, varr, varr, varr, validating_equal{});
(void) is_permutation(varr, varr, validating_equal{});
(void) is_permutation(iarr, iarr, iarr, iarr, validating_equal{});
(void) is_permutation(iarr, iarr, validating_equal{});
(void) is_permutation(iarr, iarr, iarr, iarr, {}, validating_identity{});
(void) is_permutation(iarr, iarr, {}, validating_identity{});
(void) search(varr, varr, varr, varr);
(void) search(varr, varr);
(void) search(iarr, iarr, iarr, iarr, validating_equal{});
(void) search(iarr, iarr, validating_equal{});
(void) search_n(varr, varr, 0, validator{});
(void) search_n(varr, 0, validator{});
(void) search_n(iarr, iarr, 0, 0, validating_equal{});
(void) search_n(iarr, 0, 0, validating_equal{});
#if _HAS_CXX23
(void) starts_with(varr, varr, varr, varr);
(void) starts_with(varr, varr);
(void) starts_with(iarr, iarr, iarr, iarr, validating_equal{});
(void) starts_with(iarr, iarr, validating_equal{});
(void) ends_with(varr, varr, varr, varr);
(void) ends_with(varr, varr);
(void) ends_with(iarr, iarr, iarr, iarr, validating_equal{});
(void) ends_with(iarr, iarr, validating_equal{});
#endif // _HAS_CXX23
}
static_assert(test());
// Separated test for ranges::count and equality
static_assert(std::equality_comparable<validator>);
static_assert(std::indirectly_comparable<validator*, validator*, std::equal_to<>>);
static_assert(std::sortable<validator*>);
constexpr bool test_ranges_count() {
using namespace std::ranges;
validator a[10]{};
assert(count(a, a + 10, nullptr) == 10);
assert(count(a, nullptr) == 10);
return true;
}
static_assert(test_ranges_count());
#endif // _M_CEE