зеркало из https://github.com/microsoft/STL.git
ADL-proof implementation of [alg.modifying.operations] (#4256)
Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
This commit is contained in:
Родитель
ea783f8028
Коммит
378f61b5ec
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -2315,7 +2315,7 @@ struct _Static_partitioned_unary_transform2 {
|
|||
|
||||
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_unary_transform2*>(_Context));
|
||||
_STD _Run_available_chunked_work(*static_cast<_Static_partitioned_unary_transform2*>(_Context));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2326,36 +2326,38 @@ _FwdIt2 transform(_ExPo&&, const _FwdIt1 _First, const _FwdIt1 _Last, _FwdIt2 _D
|
|||
// transform [_First, _Last) with _Func
|
||||
_REQUIRE_PARALLEL_ITERATOR(_FwdIt1);
|
||||
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt2);
|
||||
_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...
|
||||
const auto _Count = _STD distance(_UFirst, _ULast);
|
||||
const auto _UDest = _Get_unwrapped_n(_Dest, _Count);
|
||||
const auto _UDest = _STD _Get_unwrapped_n(_Dest, _Count);
|
||||
if (_Count >= 2) { // ... with at least 2 elements
|
||||
_TRY_BEGIN
|
||||
_Static_partitioned_unary_transform2 _Operation{_Hw_threads, _Count, _UFirst, _Pass_fn(_Func), _UDest};
|
||||
_Seek_wrapped(_Dest, _Operation._Dest_basis._Populate(_Operation._Team, _UDest));
|
||||
_Run_chunked_parallel_work(_Hw_threads, _Operation);
|
||||
_Static_partitioned_unary_transform2 _Operation{
|
||||
_Hw_threads, _Count, _UFirst, _STD _Pass_fn(_Func), _UDest};
|
||||
_STD _Seek_wrapped(_Dest, _Operation._Dest_basis._Populate(_Operation._Team, _UDest));
|
||||
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
|
||||
return _Dest;
|
||||
_CATCH(const _Parallelism_resources_exhausted&)
|
||||
// fall through to serial case below
|
||||
_CATCH_END
|
||||
}
|
||||
|
||||
_Seek_wrapped(_Dest, _STD transform(_UFirst, _ULast, _UDest, _Pass_fn(_Func)));
|
||||
_STD _Seek_wrapped(_Dest, _STD transform(_UFirst, _ULast, _UDest, _STD _Pass_fn(_Func)));
|
||||
return _Dest;
|
||||
} else {
|
||||
_Seek_wrapped(
|
||||
_Dest, _STD transform(_UFirst, _ULast, _Get_unwrapped_n(_Dest, _Idl_distance<_FwdIt1>(_UFirst, _ULast)),
|
||||
_Pass_fn(_Func)));
|
||||
_STD _Seek_wrapped(_Dest,
|
||||
_STD transform(_UFirst, _ULast,
|
||||
_STD _Get_unwrapped_n(_Dest, _STD _Idl_distance<_FwdIt1>(_UFirst, _ULast)), _STD _Pass_fn(_Func)));
|
||||
return _Dest;
|
||||
}
|
||||
} else {
|
||||
_Seek_wrapped(_Dest, _STD transform(_UFirst, _ULast,
|
||||
_Get_unwrapped_n(_Dest, _Idl_distance<_FwdIt1>(_UFirst, _ULast)), _Pass_fn(_Func)));
|
||||
_STD _Seek_wrapped(_Dest,
|
||||
_STD transform(_UFirst, _ULast, _STD _Get_unwrapped_n(_Dest, _STD _Idl_distance<_FwdIt1>(_UFirst, _ULast)),
|
||||
_STD _Pass_fn(_Func)));
|
||||
return _Dest;
|
||||
}
|
||||
}
|
||||
|
@ -2391,7 +2393,7 @@ struct _Static_partitioned_binary_transform2 {
|
|||
|
||||
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_binary_transform2*>(_Context));
|
||||
_STD _Run_available_chunked_work(*static_cast<_Static_partitioned_binary_transform2*>(_Context));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2403,39 +2405,39 @@ _FwdIt3 transform(_ExPo&&, const _FwdIt1 _First1, const _FwdIt1 _Last1, const _F
|
|||
_REQUIRE_PARALLEL_ITERATOR(_FwdIt1);
|
||||
_REQUIRE_PARALLEL_ITERATOR(_FwdIt2);
|
||||
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt3);
|
||||
_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) { // parallelize on multiprocessor machines...
|
||||
const auto _Count = _STD distance(_UFirst1, _ULast1);
|
||||
const auto _UFirst2 = _Get_unwrapped_n(_First2, _Count);
|
||||
const auto _UDest = _Get_unwrapped_n(_Dest, _Count);
|
||||
const auto _UFirst2 = _STD _Get_unwrapped_n(_First2, _Count);
|
||||
const auto _UDest = _STD _Get_unwrapped_n(_Dest, _Count);
|
||||
if (_Count >= 2) { // ... with at least 2 elements
|
||||
_TRY_BEGIN
|
||||
_Static_partitioned_binary_transform2 _Operation{
|
||||
_Hw_threads, _Count, _UFirst1, _UFirst2, _Pass_fn(_Func), _UDest};
|
||||
_Seek_wrapped(_Dest, _Operation._Dest_basis._Populate(_Operation._Team, _UDest));
|
||||
_Run_chunked_parallel_work(_Hw_threads, _Operation);
|
||||
_Hw_threads, _Count, _UFirst1, _UFirst2, _STD _Pass_fn(_Func), _UDest};
|
||||
_STD _Seek_wrapped(_Dest, _Operation._Dest_basis._Populate(_Operation._Team, _UDest));
|
||||
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
|
||||
return _Dest;
|
||||
_CATCH(const _Parallelism_resources_exhausted&)
|
||||
// fall through to serial case below
|
||||
_CATCH_END
|
||||
}
|
||||
|
||||
_Seek_wrapped(_Dest, _STD transform(_UFirst1, _ULast1, _UFirst2, _UDest, _Pass_fn(_Func)));
|
||||
_STD _Seek_wrapped(_Dest, _STD transform(_UFirst1, _ULast1, _UFirst2, _UDest, _STD _Pass_fn(_Func)));
|
||||
return _Dest;
|
||||
} else {
|
||||
const auto _Count = _Idl_distance<_FwdIt1>(_UFirst1, _ULast1);
|
||||
_Seek_wrapped(_Dest, _STD transform(_UFirst1, _ULast1, _Get_unwrapped_n(_First2, _Count),
|
||||
_Get_unwrapped_n(_Dest, _Count), _Pass_fn(_Func)));
|
||||
const auto _Count = _STD _Idl_distance<_FwdIt1>(_UFirst1, _ULast1);
|
||||
_STD _Seek_wrapped(_Dest, _STD transform(_UFirst1, _ULast1, _STD _Get_unwrapped_n(_First2, _Count),
|
||||
_STD _Get_unwrapped_n(_Dest, _Count), _STD _Pass_fn(_Func)));
|
||||
return _Dest;
|
||||
}
|
||||
} else {
|
||||
const auto _Count = _Idl_distance<_FwdIt1>(_UFirst1, _ULast1);
|
||||
_Seek_wrapped(_Dest, _STD transform(_UFirst1, _ULast1, _Get_unwrapped_n(_First2, _Count),
|
||||
_Get_unwrapped_n(_Dest, _Count), _Pass_fn(_Func)));
|
||||
const auto _Count = _STD _Idl_distance<_FwdIt1>(_UFirst1, _ULast1);
|
||||
_STD _Seek_wrapped(_Dest, _STD transform(_UFirst1, _ULast1, _STD _Get_unwrapped_n(_First2, _Count),
|
||||
_STD _Get_unwrapped_n(_Dest, _Count), _STD _Pass_fn(_Func)));
|
||||
return _Dest;
|
||||
}
|
||||
}
|
||||
|
@ -2457,12 +2459,12 @@ void replace_if(_ExPo&& _Exec, const _FwdIt _First, const _FwdIt _Last, _Pr _Pre
|
|||
/* terminates */ {
|
||||
// replace each satisfying _Pred with _Val
|
||||
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt);
|
||||
_STD for_each(
|
||||
_STD forward<_ExPo>(_Exec), _First, _Last, [&_Val, _Lambda_pred = _Pass_fn(_Pred)](auto&& _Value) mutable {
|
||||
if (_Lambda_pred(_STD forward<decltype(_Value)>(_Value))) {
|
||||
_STD forward<decltype(_Value)>(_Value) = _Val;
|
||||
}
|
||||
});
|
||||
auto _Lambda_pred = _STD _Pass_fn(_Pred); // TRANSITION, DevCom-10456445
|
||||
_STD for_each(_STD forward<_ExPo>(_Exec), _First, _Last, [&_Val, _Lambda_pred](auto&& _Value) mutable {
|
||||
if (_Lambda_pred(_STD forward<decltype(_Value)>(_Value))) {
|
||||
_STD forward<decltype(_Value)>(_Value) = _Val;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
template <class _FwdIt, class _Pr>
|
||||
|
@ -2530,7 +2532,7 @@ struct _Static_partitioned_remove_if2 {
|
|||
if (_Merge_index == 0 || _Results == _Range._First) {
|
||||
_Results = _STD remove_if(_Range._First, _Range._Last, _Pred);
|
||||
} else {
|
||||
_Results = _Remove_move_if_unchecked(_Range._First, _Range._Last, _Results, _Pred);
|
||||
_Results = _STD _Remove_move_if_unchecked(_Range._First, _Range._Last, _Results, _Pred);
|
||||
}
|
||||
|
||||
_Chunk_data._State.store(_Chunk_state::_Done);
|
||||
|
@ -2572,7 +2574,7 @@ struct _Static_partitioned_remove_if2 {
|
|||
|
||||
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_remove_if2*>(_Context));
|
||||
_STD _Run_available_chunked_work(*static_cast<_Static_partitioned_remove_if2*>(_Context));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2581,18 +2583,18 @@ _NODISCARD_REMOVE_ALG _FwdIt remove_if(_ExPo&&, _FwdIt _First, const _FwdIt _Las
|
|||
/* terminates */ {
|
||||
// remove each satisfying _Pred
|
||||
_REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt);
|
||||
_Adl_verify_range(_First, _Last);
|
||||
auto _UFirst = _Get_unwrapped(_First);
|
||||
const auto _ULast = _Get_unwrapped(_Last);
|
||||
_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 = _STD distance(_UFirst, _ULast);
|
||||
if (_Count >= 2) {
|
||||
_TRY_BEGIN
|
||||
_Static_partitioned_remove_if2 _Operation{_Hw_threads, _Count, _UFirst, _Pass_fn(_Pred)};
|
||||
_Run_chunked_parallel_work(_Hw_threads, _Operation);
|
||||
_Seek_wrapped(_First, _Operation._Results);
|
||||
_Static_partitioned_remove_if2 _Operation{_Hw_threads, _Count, _UFirst, _STD _Pass_fn(_Pred)};
|
||||
_STD _Run_chunked_parallel_work(_Hw_threads, _Operation);
|
||||
_STD _Seek_wrapped(_First, _Operation._Results);
|
||||
return _First;
|
||||
_CATCH(const _Parallelism_resources_exhausted&)
|
||||
// fall through to serial case below
|
||||
|
@ -2601,7 +2603,7 @@ _NODISCARD_REMOVE_ALG _FwdIt remove_if(_ExPo&&, _FwdIt _First, const _FwdIt _Las
|
|||
}
|
||||
}
|
||||
|
||||
_Seek_wrapped(_First, _STD remove_if(_UFirst, _ULast, _Pass_fn(_Pred)));
|
||||
_STD _Seek_wrapped(_First, _STD remove_if(_UFirst, _ULast, _STD _Pass_fn(_Pred)));
|
||||
return _First;
|
||||
}
|
||||
|
||||
|
|
184
stl/inc/xutility
184
stl/inc/xutility
|
@ -4452,13 +4452,13 @@ _CONSTEXPR20 void _Verify_ranges_do_not_overlap(const _Iter1& _First1, const _Se
|
|||
#endif // _HAS_CXX20
|
||||
|
||||
const auto _Offset = _Last1 - _First1;
|
||||
const auto _Ptr1Offset = _Offset * sizeof(*_To_address(_First1));
|
||||
const auto _Ptr2Offset = _Offset * sizeof(*_To_address(_First2));
|
||||
const auto _Ptr1Offset = _Offset * sizeof(*_STD _To_address(_First1));
|
||||
const auto _Ptr2Offset = _Offset * sizeof(*_STD _To_address(_First2));
|
||||
// This cast to `cv char*` allows us to compare pointers to distinct types,
|
||||
// in case one range provides storage for the other.
|
||||
const auto _PtrFirst1 = reinterpret_cast<const volatile char*>(_To_address(_First1));
|
||||
const auto _PtrFirst1 = reinterpret_cast<const volatile char*>(_STD _To_address(_First1));
|
||||
const auto _PtrLast1 = _PtrFirst1 + _Ptr1Offset;
|
||||
const auto _PtrFirst2 = reinterpret_cast<const volatile char*>(_To_address(_First2));
|
||||
const auto _PtrFirst2 = reinterpret_cast<const volatile char*>(_STD _To_address(_First2));
|
||||
const auto _PtrLast2 = _PtrFirst2 + _Ptr2Offset;
|
||||
_STL_VERIFY(_PtrLast1 <= _PtrFirst2 || _PtrLast2 <= _PtrFirst1, "ranges should not overlap each other");
|
||||
}
|
||||
|
@ -4471,9 +4471,9 @@ _CONSTEXPR20 void _Verify_ranges_do_not_overlap(const _Iter1& _First1, const _Se
|
|||
|
||||
template <class _CtgIt, class _OutCtgIt>
|
||||
_OutCtgIt _Copy_memmove(_CtgIt _First, _CtgIt _Last, _OutCtgIt _Dest) {
|
||||
auto _FirstPtr = _To_address(_First);
|
||||
auto _LastPtr = _To_address(_Last);
|
||||
auto _DestPtr = _To_address(_Dest);
|
||||
auto _FirstPtr = _STD _To_address(_First);
|
||||
auto _LastPtr = _STD _To_address(_Last);
|
||||
auto _DestPtr = _STD _To_address(_Dest);
|
||||
const char* const _First_ch = const_cast<const char*>(reinterpret_cast<const volatile char*>(_FirstPtr));
|
||||
const char* const _Last_ch = const_cast<const char*>(reinterpret_cast<const volatile char*>(_LastPtr));
|
||||
char* const _Dest_ch = const_cast<char*>(reinterpret_cast<const volatile char*>(_DestPtr));
|
||||
|
@ -4488,7 +4488,7 @@ _OutCtgIt _Copy_memmove(_CtgIt _First, _CtgIt _Last, _OutCtgIt _Dest) {
|
|||
|
||||
template <class _CtgIt, class _OutCtgIt>
|
||||
_OutCtgIt _Copy_memmove_n(_CtgIt _First, const size_t _Count, _OutCtgIt _Dest) {
|
||||
const auto _Result = _Copy_memmove(_First, _First + _Count, _Dest);
|
||||
const auto _Result = _STD _Copy_memmove(_First, _First + _Count, _Dest);
|
||||
if constexpr (is_pointer_v<_OutCtgIt>) {
|
||||
return _Result;
|
||||
} else { // _Result is unused so the compiler can optimize it away
|
||||
|
@ -4558,11 +4558,11 @@ _CONSTEXPR20 _OutIt _Copy_unchecked(_InIt _First, _Sent _Last, _OutIt _Dest) {
|
|||
{
|
||||
#ifdef __cpp_lib_concepts
|
||||
if constexpr (!is_same_v<_InIt, _Sent>) {
|
||||
return _Copy_memmove_n(_First, static_cast<size_t>(_Last - _First), _Dest);
|
||||
return _STD _Copy_memmove_n(_First, static_cast<size_t>(_Last - _First), _Dest);
|
||||
} else
|
||||
#endif // defined(__cpp_lib_concepts)
|
||||
{
|
||||
return _Copy_memmove(_First, _Last, _Dest);
|
||||
return _STD _Copy_memmove(_First, _Last, _Dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4577,11 +4577,11 @@ _CONSTEXPR20 _OutIt _Copy_unchecked(_InIt _First, _Sent _Last, _OutIt _Dest) {
|
|||
|
||||
_EXPORT_STD template <class _InIt, class _OutIt>
|
||||
_CONSTEXPR20 _OutIt copy(_InIt _First, _InIt _Last, _OutIt _Dest) { // copy [_First, _Last) to [_Dest, ...)
|
||||
_Adl_verify_range(_First, _Last);
|
||||
const auto _UFirst = _Get_unwrapped(_First);
|
||||
const auto _ULast = _Get_unwrapped(_Last);
|
||||
const auto _UDest = _Get_unwrapped_n(_Dest, _Idl_distance<_InIt>(_UFirst, _ULast));
|
||||
_Seek_wrapped(_Dest, _STD _Copy_unchecked(_UFirst, _ULast, _UDest));
|
||||
_STD _Adl_verify_range(_First, _Last);
|
||||
const auto _UFirst = _STD _Get_unwrapped(_First);
|
||||
const auto _ULast = _STD _Get_unwrapped(_Last);
|
||||
const auto _UDest = _STD _Get_unwrapped_n(_Dest, _STD _Idl_distance<_InIt>(_UFirst, _ULast));
|
||||
_STD _Seek_wrapped(_Dest, _STD _Copy_unchecked(_UFirst, _ULast, _UDest));
|
||||
return _Dest;
|
||||
}
|
||||
|
||||
|
@ -4695,11 +4695,11 @@ namespace ranges {
|
|||
if constexpr (_Sent_copy_cat<_It, _Se, _Out>::_Bitcopy_assignable) {
|
||||
if (!_STD is_constant_evaluated()) {
|
||||
if constexpr (is_same_v<_It, _Se>) {
|
||||
_Result = _Copy_memmove(_STD move(_First), _Last, _STD move(_Result));
|
||||
_Result = _STD _Copy_memmove(_STD move(_First), _Last, _STD move(_Result));
|
||||
return {_STD move(_Last), _STD move(_Result)};
|
||||
} else {
|
||||
const auto _Count = static_cast<size_t>(_Last - _First);
|
||||
_Result = _Copy_memmove_n(_First, _Count, _STD move(_Result));
|
||||
_Result = _STD _Copy_memmove_n(_First, _Count, _STD move(_Result));
|
||||
_First += _Count;
|
||||
return {_STD move(_First), _STD move(_Result)};
|
||||
}
|
||||
|
@ -4718,20 +4718,20 @@ namespace ranges {
|
|||
template <input_iterator _It, sentinel_for<_It> _Se, weakly_incrementable _Out>
|
||||
requires indirectly_copyable<_It, _Out>
|
||||
constexpr copy_result<_It, _Out> operator()(_It _First, _Se _Last, _Out _Result) const {
|
||||
_Adl_verify_range(_First, _Last);
|
||||
auto _UResult = _RANGES _Copy_unchecked(
|
||||
_Unwrap_iter<_Se>(_STD move(_First)), _Unwrap_sent<_It>(_STD move(_Last)), _STD move(_Result));
|
||||
_Seek_wrapped(_First, _STD move(_UResult.in));
|
||||
_STD _Adl_verify_range(_First, _Last);
|
||||
auto _UResult = _RANGES _Copy_unchecked(_RANGES _Unwrap_iter<_Se>(_STD move(_First)),
|
||||
_RANGES _Unwrap_sent<_It>(_STD move(_Last)), _STD move(_Result));
|
||||
_STD _Seek_wrapped(_First, _STD move(_UResult.in));
|
||||
return {_STD move(_First), _STD move(_UResult.out)};
|
||||
}
|
||||
|
||||
template <input_range _Rng, weakly_incrementable _Out>
|
||||
requires indirectly_copyable<iterator_t<_Rng>, _Out>
|
||||
constexpr copy_result<borrowed_iterator_t<_Rng>, _Out> operator()(_Rng&& _Range, _Out _Result) const {
|
||||
auto _First = _RANGES begin(_Range);
|
||||
auto _UResult =
|
||||
_RANGES _Copy_unchecked(_Unwrap_range_iter<_Rng>(_STD move(_First)), _Uend(_Range), _STD move(_Result));
|
||||
_Seek_wrapped(_First, _STD move(_UResult.in));
|
||||
auto _First = _RANGES begin(_Range);
|
||||
auto _UResult = _RANGES _Copy_unchecked(
|
||||
_RANGES _Unwrap_range_iter<_Rng>(_STD move(_First)), _Uend(_Range), _STD move(_Result));
|
||||
_STD _Seek_wrapped(_First, _STD move(_UResult.in));
|
||||
return {_STD move(_First), _STD move(_UResult.out)};
|
||||
}
|
||||
};
|
||||
|
@ -4748,15 +4748,15 @@ _CONSTEXPR20 _OutIt copy_n(_InIt _First, _Diff _Count_raw, _OutIt _Dest) {
|
|||
if constexpr (_Is_vb_iterator<_InIt> && _Is_vb_iterator<_OutIt, true>) {
|
||||
return _STD _Copy_vbool(_First, _First + _Count, _Dest);
|
||||
} else {
|
||||
auto _UFirst = _Get_unwrapped_n(_First, _Count);
|
||||
auto _UDest = _Get_unwrapped_n(_Dest, _Count);
|
||||
auto _UFirst = _STD _Get_unwrapped_n(_First, _Count);
|
||||
auto _UDest = _STD _Get_unwrapped_n(_Dest, _Count);
|
||||
if constexpr (_Iter_copy_cat<decltype(_UFirst), decltype(_UDest)>::_Bitcopy_assignable) {
|
||||
#if _HAS_CXX20
|
||||
if (!_STD is_constant_evaluated())
|
||||
#endif // _HAS_CXX20
|
||||
{
|
||||
_UDest = _Copy_memmove_n(_UFirst, static_cast<size_t>(_Count), _UDest);
|
||||
_Seek_wrapped(_Dest, _UDest);
|
||||
_UDest = _STD _Copy_memmove_n(_UFirst, static_cast<size_t>(_Count), _UDest);
|
||||
_STD _Seek_wrapped(_Dest, _UDest);
|
||||
return _Dest;
|
||||
}
|
||||
}
|
||||
|
@ -4773,7 +4773,7 @@ _CONSTEXPR20 _OutIt copy_n(_InIt _First, _Diff _Count_raw, _OutIt _Dest) {
|
|||
++_UFirst;
|
||||
}
|
||||
|
||||
_Seek_wrapped(_Dest, _UDest);
|
||||
_STD _Seek_wrapped(_Dest, _UDest);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4794,9 +4794,9 @@ _FwdIt2 copy_n(_ExPo&&, _FwdIt1 _First, _Diff _Count_raw, _FwdIt2 _Dest) noexcep
|
|||
template <class _CtgIt1, class _CtgIt2>
|
||||
_CtgIt2 _Copy_backward_memmove(_CtgIt1 _First, _CtgIt1 _Last, _CtgIt2 _Dest) {
|
||||
// implement copy_backward-like function as memmove
|
||||
auto _FirstPtr = _To_address(_First);
|
||||
auto _LastPtr = _To_address(_Last);
|
||||
auto _DestPtr = _To_address(_Dest);
|
||||
auto _FirstPtr = _STD _To_address(_First);
|
||||
auto _LastPtr = _STD _To_address(_Last);
|
||||
auto _DestPtr = _STD _To_address(_Dest);
|
||||
const char* const _First_ch = const_cast<const char*>(reinterpret_cast<const volatile char*>(_FirstPtr));
|
||||
const char* const _Last_ch = const_cast<const char*>(reinterpret_cast<const volatile char*>(_LastPtr));
|
||||
char* const _Dest_ch = const_cast<char*>(reinterpret_cast<const volatile char*>(_DestPtr));
|
||||
|
@ -4811,7 +4811,7 @@ _CtgIt2 _Copy_backward_memmove(_CtgIt1 _First, _CtgIt1 _Last, _CtgIt2 _Dest) {
|
|||
|
||||
template <class _BidIt1, class _BidIt2>
|
||||
_BidIt2 _Copy_backward_memmove(move_iterator<_BidIt1> _First, move_iterator<_BidIt1> _Last, _BidIt2 _Dest) {
|
||||
return _Copy_backward_memmove(_First.base(), _Last.base(), _Dest);
|
||||
return _STD _Copy_backward_memmove(_First.base(), _Last.base(), _Dest);
|
||||
}
|
||||
|
||||
template <class _BidIt1, class _BidIt2>
|
||||
|
@ -4822,7 +4822,7 @@ _NODISCARD _CONSTEXPR20 _BidIt2 _Copy_backward_unchecked(_BidIt1 _First, _BidIt1
|
|||
if (!_STD is_constant_evaluated())
|
||||
#endif // _HAS_CXX20
|
||||
{
|
||||
return _Copy_backward_memmove(_First, _Last, _Dest);
|
||||
return _STD _Copy_backward_memmove(_First, _Last, _Dest);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4836,11 +4836,11 @@ _NODISCARD _CONSTEXPR20 _BidIt2 _Copy_backward_unchecked(_BidIt1 _First, _BidIt1
|
|||
_EXPORT_STD template <class _BidIt1, class _BidIt2>
|
||||
_CONSTEXPR20 _BidIt2 copy_backward(_BidIt1 _First, _BidIt1 _Last, _BidIt2 _Dest) {
|
||||
// copy [_First, _Last) backwards to [..., _Dest)
|
||||
_Adl_verify_range(_First, _Last);
|
||||
const auto _UFirst = _Get_unwrapped(_First);
|
||||
const auto _ULast = _Get_unwrapped(_Last);
|
||||
const auto _UDest = _Get_unwrapped_n(_Dest, -_Idl_distance<_BidIt1>(_UFirst, _ULast));
|
||||
_Seek_wrapped(_Dest, _Copy_backward_unchecked(_UFirst, _ULast, _UDest));
|
||||
_STD _Adl_verify_range(_First, _Last);
|
||||
const auto _UFirst = _STD _Get_unwrapped(_First);
|
||||
const auto _ULast = _STD _Get_unwrapped(_Last);
|
||||
const auto _UDest = _STD _Get_unwrapped_n(_Dest, -_STD _Idl_distance<_BidIt1>(_UFirst, _ULast));
|
||||
_STD _Seek_wrapped(_Dest, _STD _Copy_backward_unchecked(_UFirst, _ULast, _UDest));
|
||||
return _Dest;
|
||||
}
|
||||
|
||||
|
@ -4856,7 +4856,7 @@ _CONSTEXPR20 _OutIt _Move_unchecked(_InIt _First, _InIt _Last, _OutIt _Dest) {
|
|||
if (!_STD is_constant_evaluated())
|
||||
#endif // _HAS_CXX20
|
||||
{
|
||||
return _Copy_memmove(_First, _Last, _Dest);
|
||||
return _STD _Copy_memmove(_First, _Last, _Dest);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4871,11 +4871,11 @@ _CONSTEXPR20 _OutIt _Move_unchecked(_InIt _First, _InIt _Last, _OutIt _Dest) {
|
|||
_EXPORT_STD template <class _InIt, class _OutIt>
|
||||
_CONSTEXPR20 _OutIt move(_InIt _First, _InIt _Last, _OutIt _Dest) {
|
||||
// move [_First, _Last) to [_Dest, ...)
|
||||
_Adl_verify_range(_First, _Last);
|
||||
const auto _UFirst = _Get_unwrapped(_First);
|
||||
const auto _ULast = _Get_unwrapped(_Last);
|
||||
const auto _UDest = _Get_unwrapped_n(_Dest, _Idl_distance<_InIt>(_UFirst, _ULast));
|
||||
_Seek_wrapped(_Dest, _STD _Move_unchecked(_UFirst, _ULast, _UDest));
|
||||
_STD _Adl_verify_range(_First, _Last);
|
||||
const auto _UFirst = _STD _Get_unwrapped(_First);
|
||||
const auto _ULast = _STD _Get_unwrapped(_Last);
|
||||
const auto _UDest = _STD _Get_unwrapped_n(_Dest, _STD _Idl_distance<_InIt>(_UFirst, _ULast));
|
||||
_STD _Seek_wrapped(_Dest, _STD _Move_unchecked(_UFirst, _ULast, _UDest));
|
||||
return _Dest;
|
||||
}
|
||||
|
||||
|
@ -4899,7 +4899,7 @@ _CONSTEXPR20 _BidIt2 _Move_backward_unchecked(_BidIt1 _First, _BidIt1 _Last, _Bi
|
|||
if (!_STD is_constant_evaluated())
|
||||
#endif // _HAS_CXX20
|
||||
{
|
||||
return _Copy_backward_memmove(_First, _Last, _Dest);
|
||||
return _STD _Copy_backward_memmove(_First, _Last, _Dest);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4913,11 +4913,11 @@ _CONSTEXPR20 _BidIt2 _Move_backward_unchecked(_BidIt1 _First, _BidIt1 _Last, _Bi
|
|||
_EXPORT_STD template <class _BidIt1, class _BidIt2>
|
||||
_CONSTEXPR20 _BidIt2 move_backward(_BidIt1 _First, _BidIt1 _Last, _BidIt2 _Dest) {
|
||||
// move [_First, _Last) backwards to [..., _Dest)
|
||||
_Adl_verify_range(_First, _Last);
|
||||
const auto _UFirst = _Get_unwrapped(_First);
|
||||
const auto _ULast = _Get_unwrapped(_Last);
|
||||
const auto _UDest = _Get_unwrapped_n(_Dest, -_Idl_distance<_BidIt1>(_UFirst, _ULast));
|
||||
_Seek_wrapped(_Dest, _Move_backward_unchecked(_UFirst, _ULast, _UDest));
|
||||
_STD _Adl_verify_range(_First, _Last);
|
||||
const auto _UFirst = _STD _Get_unwrapped(_First);
|
||||
const auto _ULast = _STD _Get_unwrapped(_Last);
|
||||
const auto _UDest = _STD _Get_unwrapped_n(_Dest, -_STD _Idl_distance<_BidIt1>(_UFirst, _ULast));
|
||||
_STD _Seek_wrapped(_Dest, _STD _Move_backward_unchecked(_UFirst, _ULast, _UDest));
|
||||
return _Dest;
|
||||
}
|
||||
|
||||
|
@ -4974,12 +4974,12 @@ template <class _CtgIt, class _Ty>
|
|||
void _Fill_memset(_CtgIt _Dest, const _Ty _Val, const size_t _Count) {
|
||||
// implicitly convert (a cast would suppress warnings); also handles _Iter_value_t<_CtgIt> being bool
|
||||
_Iter_value_t<_CtgIt> _Dest_val = _Val;
|
||||
_CSTD memset(_To_address(_Dest), static_cast<unsigned char>(_Dest_val), _Count);
|
||||
_CSTD memset(_STD _To_address(_Dest), static_cast<unsigned char>(_Dest_val), _Count);
|
||||
}
|
||||
|
||||
template <class _CtgIt>
|
||||
void _Fill_zero_memset(_CtgIt _Dest, const size_t _Count) {
|
||||
_CSTD memset(_To_address(_Dest), 0, _Count * sizeof(_Iter_value_t<_CtgIt>));
|
||||
_CSTD memset(_STD _To_address(_Dest), 0, _Count * sizeof(_Iter_value_t<_CtgIt>));
|
||||
}
|
||||
|
||||
template <class _Ty>
|
||||
|
@ -4997,22 +4997,22 @@ _NODISCARD bool _Is_all_bits_zero(const _Ty& _Val) {
|
|||
_EXPORT_STD template <class _FwdIt, class _Ty>
|
||||
_CONSTEXPR20 void fill(const _FwdIt _First, const _FwdIt _Last, const _Ty& _Val) {
|
||||
// copy _Val through [_First, _Last)
|
||||
_Adl_verify_range(_First, _Last);
|
||||
_STD _Adl_verify_range(_First, _Last);
|
||||
if constexpr (_Is_vb_iterator<_FwdIt, true>) {
|
||||
_STD _Fill_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 _HAS_CXX20
|
||||
if (!_STD is_constant_evaluated())
|
||||
#endif // _HAS_CXX20
|
||||
{
|
||||
if constexpr (_Fill_memset_is_safe<decltype(_UFirst), _Ty>) {
|
||||
_Fill_memset(_UFirst, _Val, static_cast<size_t>(_ULast - _UFirst));
|
||||
_STD _Fill_memset(_UFirst, _Val, static_cast<size_t>(_ULast - _UFirst));
|
||||
return;
|
||||
} else if constexpr (_Fill_zero_memset_is_safe<decltype(_UFirst), _Ty>) {
|
||||
if (_Is_all_bits_zero(_Val)) {
|
||||
_Fill_zero_memset(_UFirst, static_cast<size_t>(_ULast - _UFirst));
|
||||
if (_STD _Is_all_bits_zero(_Val)) {
|
||||
_STD _Fill_zero_memset(_UFirst, static_cast<size_t>(_ULast - _UFirst));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -5044,19 +5044,19 @@ _CONSTEXPR20 _OutIt fill_n(_OutIt _Dest, const _Diff _Count_raw, const _Ty& _Val
|
|||
_STD _Fill_vbool(_Dest, _Last, _Val);
|
||||
return _Last;
|
||||
} else {
|
||||
auto _UDest = _Get_unwrapped_n(_Dest, _Count);
|
||||
auto _UDest = _STD _Get_unwrapped_n(_Dest, _Count);
|
||||
#if _HAS_CXX20
|
||||
if (!_STD is_constant_evaluated())
|
||||
#endif // _HAS_CXX20
|
||||
{
|
||||
if constexpr (_Fill_memset_is_safe<decltype(_UDest), _Ty>) {
|
||||
_Fill_memset(_UDest, _Val, static_cast<size_t>(_Count));
|
||||
_Seek_wrapped(_Dest, _UDest + _Count);
|
||||
_STD _Fill_memset(_UDest, _Val, static_cast<size_t>(_Count));
|
||||
_STD _Seek_wrapped(_Dest, _UDest + _Count);
|
||||
return _Dest;
|
||||
} else if constexpr (_Fill_zero_memset_is_safe<decltype(_UDest), _Ty>) {
|
||||
if (_Is_all_bits_zero(_Val)) {
|
||||
_Fill_zero_memset(_UDest, static_cast<size_t>(_Count));
|
||||
_Seek_wrapped(_Dest, _UDest + _Count);
|
||||
if (_STD _Is_all_bits_zero(_Val)) {
|
||||
_STD _Fill_zero_memset(_UDest, static_cast<size_t>(_Count));
|
||||
_STD _Seek_wrapped(_Dest, _UDest + _Count);
|
||||
return _Dest;
|
||||
}
|
||||
}
|
||||
|
@ -5066,7 +5066,7 @@ _CONSTEXPR20 _OutIt fill_n(_OutIt _Dest, const _Diff _Count_raw, const _Ty& _Val
|
|||
*_UDest = _Val;
|
||||
}
|
||||
|
||||
_Seek_wrapped(_Dest, _UDest);
|
||||
_STD _Seek_wrapped(_Dest, _UDest);
|
||||
}
|
||||
}
|
||||
return _Dest;
|
||||
|
@ -5089,16 +5089,16 @@ namespace ranges {
|
|||
template <class _Ty, output_iterator<const _Ty&> _It>
|
||||
constexpr _It operator()(_It _First, iter_difference_t<_It> _Count, const _Ty& _Value) const {
|
||||
if (_Count > 0) {
|
||||
auto _UFirst = _Get_unwrapped_n(_STD move(_First), _Count);
|
||||
auto _UFirst = _STD _Get_unwrapped_n(_STD move(_First), _Count);
|
||||
if (!_STD is_constant_evaluated()) {
|
||||
if constexpr (_Fill_memset_is_safe<decltype(_UFirst), _Ty>) {
|
||||
_Fill_memset(_UFirst, _Value, static_cast<size_t>(_Count));
|
||||
_Seek_wrapped(_First, _UFirst + _Count); // no need to move since _UFirst is a pointer
|
||||
_STD _Fill_memset(_UFirst, _Value, static_cast<size_t>(_Count));
|
||||
_STD _Seek_wrapped(_First, _UFirst + _Count); // no need to move since _UFirst is a pointer
|
||||
return _First;
|
||||
} else if constexpr (_Fill_zero_memset_is_safe<decltype(_UFirst), _Ty>) {
|
||||
if (_Is_all_bits_zero(_Value)) {
|
||||
_Fill_zero_memset(_UFirst, static_cast<size_t>(_Count));
|
||||
_Seek_wrapped(_First, _UFirst + _Count); // no need to move since _UFirst is a pointer
|
||||
if (_STD _Is_all_bits_zero(_Value)) {
|
||||
_STD _Fill_zero_memset(_UFirst, static_cast<size_t>(_Count));
|
||||
_STD _Seek_wrapped(_First, _UFirst + _Count); // no need to move since _UFirst is a pointer
|
||||
return _First;
|
||||
}
|
||||
}
|
||||
|
@ -5108,7 +5108,7 @@ namespace ranges {
|
|||
*_UFirst = _Value;
|
||||
}
|
||||
|
||||
_Seek_wrapped(_First, _STD move(_UFirst));
|
||||
_STD _Seek_wrapped(_First, _STD move(_UFirst));
|
||||
}
|
||||
|
||||
return _First;
|
||||
|
@ -6139,9 +6139,9 @@ _NODISCARD _CONSTEXPR20 bool _Check_match_counts(
|
|||
|
||||
_EXPORT_STD template <class _BidIt>
|
||||
_CONSTEXPR20 void reverse(const _BidIt _First, const _BidIt _Last) { // reverse elements in [_First, _Last)
|
||||
_Adl_verify_range(_First, _Last);
|
||||
auto _UFirst = _Get_unwrapped(_First);
|
||||
auto _ULast = _Get_unwrapped(_Last);
|
||||
_STD _Adl_verify_range(_First, _Last);
|
||||
auto _UFirst = _STD _Get_unwrapped(_First);
|
||||
auto _ULast = _STD _Get_unwrapped(_Last);
|
||||
#if _USE_STD_VECTOR_ALGORITHMS
|
||||
using _Elem = remove_reference_t<_Iter_ref_t<decltype(_UFirst)>>;
|
||||
constexpr bool _Allow_vectorization = conjunction_v<bool_constant<_Iterator_is_contiguous<decltype(_UFirst)>>,
|
||||
|
@ -6154,13 +6154,13 @@ _CONSTEXPR20 void reverse(const _BidIt _First, const _BidIt _Last) { // reverse
|
|||
#endif // _HAS_CXX20
|
||||
{
|
||||
if constexpr (_Nx == 1) {
|
||||
__std_reverse_trivially_swappable_1(_To_address(_UFirst), _To_address(_ULast));
|
||||
::__std_reverse_trivially_swappable_1(_STD _To_address(_UFirst), _STD _To_address(_ULast));
|
||||
} else if constexpr (_Nx == 2) {
|
||||
__std_reverse_trivially_swappable_2(_To_address(_UFirst), _To_address(_ULast));
|
||||
::__std_reverse_trivially_swappable_2(_STD _To_address(_UFirst), _STD _To_address(_ULast));
|
||||
} else if constexpr (_Nx == 4) {
|
||||
__std_reverse_trivially_swappable_4(_To_address(_UFirst), _To_address(_ULast));
|
||||
::__std_reverse_trivially_swappable_4(_STD _To_address(_UFirst), _STD _To_address(_ULast));
|
||||
} else {
|
||||
__std_reverse_trivially_swappable_8(_To_address(_UFirst), _To_address(_ULast));
|
||||
::__std_reverse_trivially_swappable_8(_STD _To_address(_UFirst), _STD _To_address(_ULast));
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -6199,11 +6199,11 @@ _CONSTEXPR20 _FwdIt rotate(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last) {
|
|||
// exchange the ranges [_First, _Mid) and [_Mid, _Last)
|
||||
// that is, rotates [_First, _Last) left by distance(_First, _Mid) positions
|
||||
// returns the iterator pointing at *_First's new home
|
||||
_Adl_verify_range(_First, _Mid);
|
||||
_Adl_verify_range(_Mid, _Last);
|
||||
auto _UFirst = _Get_unwrapped(_First);
|
||||
auto _UMid = _Get_unwrapped(_Mid);
|
||||
const auto _ULast = _Get_unwrapped(_Last);
|
||||
_STD _Adl_verify_range(_First, _Mid);
|
||||
_STD _Adl_verify_range(_Mid, _Last);
|
||||
auto _UFirst = _STD _Get_unwrapped(_First);
|
||||
auto _UMid = _STD _Get_unwrapped(_Mid);
|
||||
const auto _ULast = _STD _Get_unwrapped(_Last);
|
||||
if (_UFirst == _UMid) {
|
||||
return _Last;
|
||||
}
|
||||
|
@ -6216,13 +6216,13 @@ _CONSTEXPR20 _FwdIt rotate(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last) {
|
|||
_STD reverse(_UFirst, _UMid);
|
||||
_STD reverse(_UMid, _ULast);
|
||||
_STD reverse(_UFirst, _ULast);
|
||||
_Seek_wrapped(_First, _UFirst + (_ULast - _UMid));
|
||||
_STD _Seek_wrapped(_First, _UFirst + (_ULast - _UMid));
|
||||
} else if constexpr (_Is_cpp17_bidi_iter_v<_FwdIt>) {
|
||||
_STD reverse(_UFirst, _UMid);
|
||||
_STD reverse(_UMid, _ULast);
|
||||
auto _Tmp = _Reverse_until_sentinel_unchecked(_UFirst, _UMid, _ULast);
|
||||
auto _Tmp = _STD _Reverse_until_sentinel_unchecked(_UFirst, _UMid, _ULast);
|
||||
_STD reverse(_Tmp.first, _Tmp.second);
|
||||
_Seek_wrapped(_First, _UMid != _Tmp.first ? _Tmp.first : _Tmp.second);
|
||||
_STD _Seek_wrapped(_First, _UMid != _Tmp.first ? _Tmp.first : _Tmp.second);
|
||||
} else {
|
||||
auto _UNext = _UMid;
|
||||
do { // rotate the first cycle
|
||||
|
@ -6233,7 +6233,7 @@ _CONSTEXPR20 _FwdIt rotate(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last) {
|
|||
_UMid = _UNext;
|
||||
}
|
||||
} while (_UNext != _ULast);
|
||||
_Seek_wrapped(_First, _UFirst);
|
||||
_STD _Seek_wrapped(_First, _UFirst);
|
||||
while (_UMid != _ULast) { // rotate subsequent cycles
|
||||
_UNext = _UMid;
|
||||
do {
|
||||
|
@ -7040,8 +7040,8 @@ _CONSTEXPR20 _FwdIt2 _Swap_ranges_unchecked(_FwdIt1 _First1, const _FwdIt1 _Last
|
|||
if (!_STD is_constant_evaluated())
|
||||
#endif // _HAS_CXX20
|
||||
{
|
||||
__std_swap_ranges_trivially_swappable_noalias(
|
||||
_To_address(_First1), _To_address(_Last1), _To_address(_First2));
|
||||
::__std_swap_ranges_trivially_swappable_noalias(
|
||||
_STD _To_address(_First1), _STD _To_address(_Last1), _STD _To_address(_First2));
|
||||
return _First2 + (_Last1 - _First1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,12 +44,33 @@ struct tagged_compare_three_way {
|
|||
};
|
||||
#endif // _HAS_CXX20
|
||||
|
||||
template <class T>
|
||||
struct holder {
|
||||
T t;
|
||||
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_urng {
|
||||
using result_type = unsigned int;
|
||||
|
||||
static constexpr result_type max() noexcept {
|
||||
return static_cast<result_type>(-1);
|
||||
}
|
||||
|
||||
static constexpr result_type min() noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
result_type operator()() noexcept {
|
||||
return value_++;
|
||||
}
|
||||
|
||||
result_type value_{};
|
||||
};
|
||||
|
||||
#if _HAS_CXX23 && defined(__cpp_lib_concepts) // TRANSITION, GH-395
|
||||
template <class Tag>
|
||||
struct tagged_left_selector {
|
||||
template <class T>
|
||||
|
@ -57,26 +78,37 @@ struct tagged_left_selector {
|
|||
return lhs;
|
||||
}
|
||||
};
|
||||
#endif // _HAS_CXX23 && defined(__cpp_lib_concepts)
|
||||
|
||||
template <class T>
|
||||
struct holder {
|
||||
T t;
|
||||
};
|
||||
|
||||
struct incomplete;
|
||||
|
||||
using simple_truth = tagged_truth<void>;
|
||||
using simple_truth = tagged_truth<void>;
|
||||
using simple_identity = tagged_identity<void>;
|
||||
using simple_left_selector = tagged_left_selector<void>;
|
||||
using simple_urng = tagged_urng<void>;
|
||||
|
||||
using validator = holder<incomplete>*;
|
||||
using validating_truth = tagged_truth<holder<incomplete>>;
|
||||
using validating_equal = tagged_equal<holder<incomplete>>;
|
||||
using validating_less = tagged_less<holder<incomplete>>;
|
||||
using validator = holder<incomplete>*;
|
||||
using validating_truth = tagged_truth<holder<incomplete>>;
|
||||
using validating_equal = tagged_equal<holder<incomplete>>;
|
||||
using validating_less = tagged_less<holder<incomplete>>;
|
||||
using validating_identity = tagged_identity<holder<incomplete>>;
|
||||
using validating_left_selector = tagged_left_selector<holder<incomplete>>;
|
||||
using validating_urng = tagged_urng<holder<incomplete>>;
|
||||
|
||||
#if _HAS_CXX20
|
||||
using validating_compare_three_way = tagged_compare_three_way<holder<incomplete>>;
|
||||
#endif // _HAS_CXX20
|
||||
|
||||
#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)
|
||||
template <class T>
|
||||
struct value_generator {
|
||||
T operator()() const {
|
||||
return T{};
|
||||
}
|
||||
};
|
||||
|
||||
void test_algorithms() {
|
||||
int iarr[1]{};
|
||||
|
@ -145,11 +177,92 @@ void test_algorithms() {
|
|||
(void) std::search(varr, varr, varr, varr);
|
||||
(void) std::search(iarr, iarr, iarr, iarr, validating_equal{});
|
||||
|
||||
(void) std::search_n(varr, varr, 0, validator{});
|
||||
(void) std::search_n(iarr, iarr, 0, 0, validating_equal{});
|
||||
|
||||
int iarr2[1]{};
|
||||
validator varr2[1]{};
|
||||
|
||||
(void) std::copy(varr, varr + 1, varr2);
|
||||
|
||||
(void) std::copy_n(varr, 1, varr2);
|
||||
|
||||
(void) std::copy_if(varr, varr + 1, varr2, simple_truth{});
|
||||
(void) std::copy_if(iarr, iarr + 1, iarr2, validating_truth{});
|
||||
|
||||
(void) std::copy_backward(varr, varr + 1, varr2 + 1);
|
||||
|
||||
(void) std::move(varr, varr + 1, varr2);
|
||||
|
||||
(void) std::move_backward(varr, varr + 1, varr2 + 1);
|
||||
|
||||
// (void) std::swap_ranges(varr, varr, varr2); // requires Cpp17ValueSwappable
|
||||
|
||||
// std::iter_swap(varr, varr2); // requires Cpp17ValueSwappable
|
||||
|
||||
(void) std::transform(varr, varr, varr2, simple_identity{});
|
||||
(void) std::transform(varr, varr, varr, varr2, simple_left_selector{});
|
||||
(void) std::transform(iarr, iarr, iarr2, validating_identity{});
|
||||
(void) std::transform(iarr, iarr, iarr, iarr2, validating_left_selector{});
|
||||
|
||||
std::replace(varr, varr, validator{}, validator{});
|
||||
|
||||
std::replace_if(varr, varr, simple_truth{}, validator{});
|
||||
std::replace_if(iarr, iarr, validating_truth{}, 0);
|
||||
|
||||
(void) std::replace_copy(varr, varr, varr2, validator{}, validator{});
|
||||
|
||||
(void) std::replace_copy_if(varr, varr, varr2, simple_truth{}, validator{});
|
||||
(void) std::replace_copy_if(iarr, iarr, iarr2, validating_truth{}, 0);
|
||||
|
||||
std::fill(varr, varr, validator{});
|
||||
|
||||
(void) std::fill_n(varr, 0, validator{});
|
||||
|
||||
std::generate(varr, varr, value_generator<validator>{});
|
||||
|
||||
(void) std::generate_n(varr, 0, value_generator<validator>{});
|
||||
|
||||
(void) std::remove(varr, varr, validator{});
|
||||
|
||||
(void) std::remove_if(varr, varr, simple_truth{});
|
||||
(void) std::remove_if(iarr, iarr, validating_truth{});
|
||||
|
||||
(void) std::remove_copy(varr, varr, varr2, validator{});
|
||||
|
||||
(void) std::remove_copy_if(varr, varr, varr2, simple_truth{});
|
||||
(void) std::remove_copy_if(iarr, iarr, iarr2, validating_truth{});
|
||||
|
||||
(void) std::unique(varr, varr);
|
||||
(void) std::unique(iarr, iarr, validating_equal{});
|
||||
|
||||
(void) std::unique_copy(varr, varr, varr2);
|
||||
(void) std::unique_copy(iarr, iarr, iarr2, validating_equal{});
|
||||
|
||||
// (void) std::reverse(varr, varr); // requires Cpp17ValueSwappable
|
||||
|
||||
(void) std::reverse_copy(varr, varr, varr2);
|
||||
|
||||
// (void) std::rotate(varr, varr, varr); // requires Cpp17ValueSwappable
|
||||
|
||||
(void) std::rotate_copy(varr, varr, varr, varr2);
|
||||
|
||||
#if _HAS_CXX17
|
||||
(void) std::sample(varr, varr, varr2, 0, simple_urng{});
|
||||
(void) std::sample(iarr, iarr, iarr2, 0, validating_urng{});
|
||||
#endif // _HAS_CXX17
|
||||
|
||||
// std::shuffle(varr, varr, simple_urng{}); // requires Cpp17ValueSwappable
|
||||
// std::shuffle(iarr, iarr, validating_urng{}); // requires Cpp17ValueSwappable
|
||||
|
||||
// std::random_shuffle (removed in C++17) also requires Cpp17ValueSwappable
|
||||
|
||||
#if _HAS_CXX20
|
||||
(void) std::shift_left(varr, varr, 0);
|
||||
|
||||
// (void) std::shift_right(varr, varr, 0); // requires Cpp17ValueSwappable
|
||||
#endif // _HAS_CXX20
|
||||
|
||||
(void) std::min(+varr, +varr);
|
||||
(void) std::min(+iarr, +iarr, validating_less{});
|
||||
(void) std::min({+varr, +varr});
|
||||
|
@ -251,6 +364,73 @@ void test_per_execution_policy() {
|
|||
(void) std::search_n(ExecutionPolicy, varr, varr, 0, validator{});
|
||||
(void) std::search_n(ExecutionPolicy, iarr, iarr, 0, 0, validating_equal{});
|
||||
|
||||
int iarr2[1]{};
|
||||
validator varr2[1]{};
|
||||
|
||||
(void) std::copy(ExecutionPolicy, varr, varr + 1, varr2);
|
||||
|
||||
(void) std::copy_n(ExecutionPolicy, varr, 1, varr2);
|
||||
|
||||
(void) std::copy_if(ExecutionPolicy, varr, varr + 1, varr2, simple_truth{});
|
||||
(void) std::copy_if(ExecutionPolicy, iarr, iarr + 1, iarr2, validating_truth{});
|
||||
|
||||
(void) std::move(ExecutionPolicy, varr, varr + 1, varr2);
|
||||
|
||||
// (void) std::swap_ranges(ExecutionPolicy, varr, varr, varr2); // requires Cpp17ValueSwappable
|
||||
|
||||
(void) std::transform(ExecutionPolicy, varr, varr, varr2, simple_identity{});
|
||||
(void) std::transform(ExecutionPolicy, varr, varr, varr, varr2, simple_left_selector{});
|
||||
(void) std::transform(ExecutionPolicy, iarr, iarr, iarr2, validating_identity{});
|
||||
(void) std::transform(ExecutionPolicy, iarr, iarr, iarr, iarr2, validating_left_selector{});
|
||||
|
||||
std::replace(ExecutionPolicy, varr, varr, validator{}, validator{});
|
||||
|
||||
std::replace_if(ExecutionPolicy, varr, varr, simple_truth{}, validator{});
|
||||
std::replace_if(ExecutionPolicy, iarr, iarr, validating_truth{}, 0);
|
||||
|
||||
(void) std::replace_copy(ExecutionPolicy, varr, varr, varr2, validator{}, validator{});
|
||||
|
||||
(void) std::replace_copy_if(ExecutionPolicy, varr, varr, varr2, simple_truth{}, validator{});
|
||||
(void) std::replace_copy_if(ExecutionPolicy, iarr, iarr, iarr2, validating_truth{}, 0);
|
||||
|
||||
std::fill(ExecutionPolicy, varr, varr, validator{});
|
||||
|
||||
(void) std::fill_n(ExecutionPolicy, varr, 0, validator{});
|
||||
|
||||
std::generate(ExecutionPolicy, varr, varr, value_generator<validator>{});
|
||||
|
||||
(void) std::generate_n(ExecutionPolicy, varr, 0, value_generator<validator>{});
|
||||
|
||||
(void) std::remove(ExecutionPolicy, varr, varr, validator{});
|
||||
|
||||
(void) std::remove_if(ExecutionPolicy, varr, varr, simple_truth{});
|
||||
(void) std::remove_if(ExecutionPolicy, iarr, iarr, validating_truth{});
|
||||
|
||||
(void) std::remove_copy(ExecutionPolicy, varr, varr, varr2, validator{});
|
||||
|
||||
(void) std::remove_copy_if(ExecutionPolicy, varr, varr, varr2, simple_truth{});
|
||||
(void) std::remove_copy_if(ExecutionPolicy, iarr, iarr, iarr2, validating_truth{});
|
||||
|
||||
(void) std::unique(ExecutionPolicy, varr, varr);
|
||||
(void) std::unique(ExecutionPolicy, iarr, iarr, validating_equal{});
|
||||
|
||||
(void) std::unique_copy(ExecutionPolicy, varr, varr, varr2);
|
||||
(void) std::unique_copy(ExecutionPolicy, iarr, iarr, iarr2, validating_equal{});
|
||||
|
||||
// std::reverse(ExecutionPolicy, varr, varr); // requires Cpp17ValueSwappable
|
||||
|
||||
(void) std::reverse_copy(ExecutionPolicy, varr, varr, varr2);
|
||||
|
||||
// (void) std::rotate(ExecutionPolicy, varr, varr, varr); // requires Cpp17ValueSwappable
|
||||
|
||||
(void) std::rotate_copy(ExecutionPolicy, varr, varr, varr, varr2);
|
||||
|
||||
#if _HAS_CXX20
|
||||
(void) std::shift_left(ExecutionPolicy, varr, varr, 0);
|
||||
|
||||
// (void) std::shift_right(ExecutionPolicy, varr, varr, 0); // requires Cpp17ValueSwappable
|
||||
#endif // _HAS_CXX20
|
||||
|
||||
(void) std::min_element(ExecutionPolicy, varr, varr + 1);
|
||||
(void) std::min_element(ExecutionPolicy, iarr, iarr + 1, validating_less{});
|
||||
|
||||
|
@ -274,13 +454,14 @@ void test_parallel_algorithms() {
|
|||
}
|
||||
#endif // _HAS_CXX17
|
||||
|
||||
#if _HAS_CXX23 && defined(__cpp_lib_concepts) // TRANSITION, GH-395
|
||||
#if _HAS_CXX20 && defined(__cpp_lib_concepts) // TRANSITION, GH-395
|
||||
void test_ranges_non_projected_algorithms() {
|
||||
using namespace std::ranges;
|
||||
|
||||
int iarr[1]{};
|
||||
validator varr[1]{};
|
||||
|
||||
#if _HAS_CXX23
|
||||
(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{});
|
||||
|
@ -310,6 +491,67 @@ void test_ranges_non_projected_algorithms() {
|
|||
(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
|
||||
|
||||
int iarr2[1]{};
|
||||
validator varr2[1]{};
|
||||
|
||||
(void) copy(varr, varr + 1, varr2);
|
||||
(void) copy(varr, varr2);
|
||||
|
||||
(void) copy_n(varr, 1, varr2);
|
||||
|
||||
(void) copy_backward(varr, varr + 1, varr2 + 1);
|
||||
(void) copy_backward(varr, varr2 + 1);
|
||||
|
||||
(void) move(varr, varr + 1, varr2);
|
||||
(void) move(varr, varr2);
|
||||
|
||||
(void) move_backward(varr, varr + 1, varr2 + 1);
|
||||
(void) move_backward(varr, varr2 + 1);
|
||||
|
||||
(void) swap_ranges(varr, varr, varr2, varr2);
|
||||
(void) swap_ranges(varr, varr2);
|
||||
|
||||
(void) fill(varr, varr, validator{});
|
||||
(void) fill(varr, validator{});
|
||||
|
||||
(void) fill_n(varr, 0, validator{});
|
||||
|
||||
(void) generate(varr, varr, value_generator<validator>{});
|
||||
(void) generate(varr, value_generator<validator>{});
|
||||
|
||||
(void) generate_n(varr, 0, value_generator<validator>{});
|
||||
|
||||
(void) reverse(varr, varr);
|
||||
(void) reverse(varr);
|
||||
|
||||
(void) reverse_copy(varr, varr, varr2);
|
||||
(void) reverse_copy(varr, varr2);
|
||||
|
||||
(void) rotate(varr, varr, varr);
|
||||
(void) rotate(varr, varr);
|
||||
|
||||
(void) rotate_copy(varr, varr, varr, varr2);
|
||||
(void) rotate_copy(varr, varr, varr2);
|
||||
|
||||
(void) sample(varr, varr, varr2, 0, simple_urng{});
|
||||
(void) sample(varr, varr2, 0, simple_urng{});
|
||||
(void) sample(iarr, iarr, iarr2, 0, validating_urng{});
|
||||
(void) sample(iarr, iarr2, 0, validating_urng{});
|
||||
|
||||
(void) shuffle(varr, varr, simple_urng{});
|
||||
(void) shuffle(varr, simple_urng{});
|
||||
(void) shuffle(iarr, iarr, validating_urng{});
|
||||
(void) shuffle(iarr, validating_urng{});
|
||||
|
||||
#if _HAS_CXX23
|
||||
(void) shift_left(varr, varr, 0);
|
||||
(void) shift_left(varr, 0);
|
||||
|
||||
(void) shift_right(varr, varr, 0);
|
||||
(void) shift_right(varr, 0);
|
||||
#endif // _HAS_CXX23
|
||||
}
|
||||
#endif // _HAS_CXX23 && defined(__cpp_lib_concepts)
|
||||
#endif // _HAS_CXX20 && defined(__cpp_lib_concepts)
|
||||
#endif // _M_CEE
|
||||
|
|
|
@ -56,14 +56,16 @@ struct holder {
|
|||
|
||||
struct incomplete;
|
||||
|
||||
using simple_truth = tagged_truth<void>;
|
||||
using simple_identity = tagged_identity<void>;
|
||||
using simple_truth = tagged_truth<void>;
|
||||
using simple_identity = tagged_identity<void>;
|
||||
using simple_left_selector = tagged_left_selector<void>;
|
||||
|
||||
using validator = holder<incomplete>*;
|
||||
using validating_truth = tagged_truth<holder<incomplete>>;
|
||||
using validating_equal = tagged_equal<holder<incomplete>>;
|
||||
using validating_less = tagged_less<holder<incomplete>>;
|
||||
using validating_identity = tagged_identity<holder<incomplete>>;
|
||||
using validator = holder<incomplete>*;
|
||||
using validating_truth = tagged_truth<holder<incomplete>>;
|
||||
using validating_equal = tagged_equal<holder<incomplete>>;
|
||||
using validating_less = tagged_less<holder<incomplete>>;
|
||||
using validating_identity = tagged_identity<holder<incomplete>>;
|
||||
using validating_left_selector = tagged_left_selector<holder<incomplete>>;
|
||||
|
||||
void test_ranges_algorithms() {
|
||||
using namespace std::ranges;
|
||||
|
@ -210,6 +212,73 @@ void test_ranges_algorithms() {
|
|||
(void) ends_with(iarr, iarr, validating_equal{});
|
||||
#endif // _HAS_CXX23
|
||||
|
||||
int iarr2[1]{};
|
||||
validator varr2[1]{};
|
||||
|
||||
(void) copy_if(varr, varr + 1, varr2, simple_truth{});
|
||||
(void) copy_if(varr, varr2, simple_truth{});
|
||||
(void) copy_if(iarr, iarr + 1, iarr2, validating_truth{});
|
||||
(void) copy_if(iarr, iarr2, validating_truth{});
|
||||
|
||||
(void) transform(varr, varr, varr2, std::identity{});
|
||||
(void) transform(varr, varr2, std::identity{});
|
||||
(void) transform(varr, varr, varr, varr, varr2, simple_left_selector{});
|
||||
(void) transform(varr, varr, varr2, simple_left_selector{});
|
||||
(void) transform(iarr, iarr, iarr2, validating_identity{});
|
||||
(void) transform(iarr, iarr, iarr, iarr, iarr2, validating_left_selector{});
|
||||
(void) transform(iarr, iarr, iarr2, validating_left_selector{});
|
||||
|
||||
(void) replace(varr, varr, validator{}, validator{});
|
||||
(void) replace(varr, validator{}, validator{});
|
||||
(void) replace(iarr, iarr, 0, 0, validating_identity{});
|
||||
(void) replace(iarr, 0, 0, validating_identity{});
|
||||
|
||||
(void) replace_if(varr, varr, simple_truth{}, validator{});
|
||||
(void) replace_if(varr, simple_truth{}, validator{});
|
||||
(void) replace_if(iarr, iarr, validating_truth{}, 0);
|
||||
(void) replace_if(iarr, validating_truth{}, 0);
|
||||
|
||||
(void) replace_copy(varr, varr, varr2, validator{}, validator{});
|
||||
(void) replace_copy(varr, varr2, validator{}, validator{});
|
||||
(void) replace_copy(iarr, iarr, iarr2, 0, 0, validating_identity{});
|
||||
(void) replace_copy(iarr, iarr2, 0, 0, validating_identity{});
|
||||
|
||||
(void) replace_copy_if(varr, varr, varr2, simple_truth{}, validator{});
|
||||
(void) replace_copy_if(varr, varr2, simple_truth{}, validator{});
|
||||
(void) replace_copy_if(iarr, iarr, iarr2, validating_truth{}, 0);
|
||||
(void) replace_copy_if(iarr, iarr2, validating_truth{}, 0);
|
||||
|
||||
using std::ranges::remove; // avoid ambiguity
|
||||
(void) remove(varr, varr, validator{});
|
||||
(void) remove(varr, validator{});
|
||||
|
||||
(void) remove_if(varr, varr, simple_truth{});
|
||||
(void) remove_if(varr, simple_truth{});
|
||||
(void) remove_if(iarr, iarr, validating_truth{});
|
||||
(void) remove_if(iarr, validating_truth{});
|
||||
|
||||
(void) remove_copy(varr, varr, varr2, validator{});
|
||||
(void) remove_copy(varr, varr2, validator{});
|
||||
|
||||
(void) remove_copy_if(varr, varr, varr2, simple_truth{});
|
||||
(void) remove_copy_if(varr, varr2, simple_truth{});
|
||||
(void) remove_copy_if(iarr, iarr, iarr2, validating_truth{});
|
||||
(void) remove_copy_if(iarr, iarr2, validating_truth{});
|
||||
|
||||
(void) unique(varr, varr);
|
||||
(void) unique(varr);
|
||||
// (void) unique(iarr, iarr, validating_equal{}); // needs to check ADL-found swap
|
||||
// (void) unique(iarr, validating_equal{}); // needs to check ADL-found swap
|
||||
(void) unique(iarr, iarr, {}, validating_identity{});
|
||||
(void) unique(iarr, {}, validating_identity{});
|
||||
|
||||
(void) unique_copy(varr, varr, varr2);
|
||||
(void) unique_copy(varr, varr2);
|
||||
// (void) unique_copy(iarr, iarr, iarr2, validating_equal{}); // needs to check ADL-found swap
|
||||
// (void) unique_copy(iarr, iarr2, validating_equal{}); // needs to check ADL-found swap
|
||||
(void) unique_copy(iarr, iarr, iarr2, {}, validating_identity{});
|
||||
(void) unique_copy(iarr, iarr2, {}, validating_identity{});
|
||||
|
||||
(void) min(+varr, +varr);
|
||||
(void) min({+varr, +varr});
|
||||
(void) min(varr);
|
||||
|
|
Загрузка…
Ссылка в новой задаче