ADL-proof implementation of [alg.modifying.operations] (#4256)

Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
This commit is contained in:
A. Jiang 2024-01-17 19:23:00 +08:00 коммит произвёл GitHub
Родитель ea783f8028
Коммит 378f61b5ec
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
5 изменённых файлов: 844 добавлений и 507 удалений

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

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

@ -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;
}

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

@ -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);