From 9e6e2dd2751d8a935ab0f6c5b3a42405be8e2023 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 23 Feb 2024 07:38:59 +0800 Subject: [PATCH 01/10] Fix improper direct-initialization in numeric algorithms --- stl/inc/execution | 77 ++++++--- stl/inc/numeric | 4 +- tests/std/test.lst | 1 + .../env.lst | 4 + .../test.cpp | 149 ++++++++++++++++++ 5 files changed, 210 insertions(+), 25 deletions(-) create mode 100644 tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/env.lst create mode 100644 tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp diff --git a/stl/inc/execution b/stl/inc/execution index 0d51ba3b540..845158c063d 100644 --- a/stl/inc/execution +++ b/stl/inc/execution @@ -137,6 +137,35 @@ template <> struct is_execution_policy : true_type {}; #endif // _HAS_CXX20 +template +void _Implicit_construct_in_place_by_deref(_Ty& _Val, const _FwdIt& _Iter) { + ::new (static_cast(_STD addressof(_Val))) _Ty([&]() -> _Ty { return *_Iter; }()); +} + +template +void _Implicit_construct_in_place_by_transform_deref(_Ty& _Val, _UnaryOp& _Tranform_op, const _FwdIt& _Iter) { + ::new (static_cast(_STD addressof(_Val))) _Ty([&]() -> _Ty { return _Tranform_op(*_Iter); }()); +} + +template +void _Implicit_construct_in_place_by_binary_op(_Ty& _Val, _BinaryOp& _Reduce_op, _ArgTy& _Left, _ArgTy& _Right) { + ::new (static_cast(_STD addressof(_Val))) _Ty([&]() -> _Ty { return _Reduce_op(_Left, _Right); }()); +} + +template +void _Implicit_construct_in_place_by_binary_op_deref_rhs( + _Ty& _Val, _BinaryOp& _Reduce_op, _LeftTy&& _Left, const _FwdIt& _Iter) { + ::new (static_cast(_STD addressof(_Val))) + _Ty([&]() -> _Ty { return _Reduce_op(_STD forward<_LeftTy>(_Left), *_Iter); }()); +} + +template +void _Implicit_construct_in_place_by_binary_op_transform_deref_rhs( + _Ty& _Val, _BinaryOp& _Reduce_op, _UnaryOp& _Transform_op, _LeftTy&& _Left, const _FwdIt& _Iter) { + ::new (static_cast(_STD addressof(_Val))) + _Ty([&]() -> _Ty { return _Reduce_op(_STD forward<_LeftTy>(_Left), _Transform_op(*_Iter)); }()); +} + struct _Parallelism_resources_exhausted : exception { _NODISCARD const char* __CLR_OR_THIS_CALL what() const noexcept override { // return pointer to message string @@ -3602,7 +3631,7 @@ struct _Scan_decoupled_lookback { template void _Apply_exclusive_predecessor(_Ty& _Preceding, _FwdIt _First, const _FwdIt _Last, _BinOp _Reduce_op) { // apply _Preceding to [_First, _Last) and _Sum._Ref(), using _Reduce_op - _STD _Construct_in_place(_Sum._Ref(), _Reduce_op(_Preceding, _Local._Ref())); + _STD _Implicit_construct_in_place_by_binary_op(_Sum._Ref(), _Reduce_op, _Preceding, _Local._Ref()); _State.store(_Local_available | _Sum_available); *_First = _Preceding; @@ -3615,7 +3644,7 @@ struct _Scan_decoupled_lookback { template void _Apply_inclusive_predecessor(_Ty& _Preceding, _FwdIt _First, const _FwdIt _Last, _BinOp _Reduce_op) { // apply _Preceding to [_First, _Last) and _Sum._Ref(), using _Reduce_op - _STD _Construct_in_place(_Sum._Ref(), _Reduce_op(_Preceding, _Local._Ref())); + _STD _Implicit_construct_in_place_by_binary_op(_Sum._Ref(), _Reduce_op, _Preceding, _Local._Ref()); _State.store(_Local_available | _Sum_available); #pragma loop(ivdep) @@ -3645,8 +3674,8 @@ typename _Iter_value_t<_BidIt>::value_type _Get_lookback_sum(const _BidIt _Curre auto _Prev = _Current; --_Prev; auto _Prev_state = _Prev->_Get_available_state(); - typename _Iter_value_t<_BidIt>::value_type _Result( - _Reduce_op(_Prev_state & _Sum_available ? _Prev->_Sum._Ref() : _Prev->_Local._Ref(), _Current->_Local._Ref())); + typename _Iter_value_t<_BidIt>::value_type _Result = + _Reduce_op(_Prev_state & _Sum_available ? _Prev->_Sum._Ref() : _Prev->_Local._Ref(), _Current->_Local._Ref()); while (!(_Prev_state & _Sum_available)) { --_Prev; _Prev_state = _Prev->_Get_available_state(); @@ -4334,9 +4363,9 @@ _FwdIt2 _Exclusive_scan_per_chunk(_FwdIt1 _First, const _FwdIt1 _Last, _FwdIt2 _ return _Dest; } - _Ty _Tmp(_Reduce_op(_Val, *_First)); // temp to enable _First == _Dest - *_Dest = _Val; - _Val = _STD move(_Tmp); + _Ty _Tmp = _Reduce_op(_Val, *_First); // temp to enable _First == _Dest + *_Dest = _Val; + _Val = _STD move(_Tmp); } } @@ -4346,13 +4375,13 @@ void _Exclusive_scan_per_chunk_complete( // Sum for parallel exclusive_scan with predecessor available, into [_Dest, _Dest + (_Last - _First)) and stores // successor sum in _Val. // Pre: _Val is *uninitialized* && _First != _Last && predecessor sum is in _Init - _STD _Construct_in_place(_Val, _Reduce_op(_Init, *_First)); + _STD _Implicit_construct_in_place_by_binary_op_deref_rhs(_Val, _Reduce_op, _Init, _First); *_Dest = _Init; while (++_First != _Last) { ++_Dest; - _Ty _Tmp(_Reduce_op(_Val, *_First)); // temp to enable _First == _Dest - *_Dest = _STD move(_Val); - _Val = _STD move(_Tmp); + _Ty _Tmp = _Reduce_op(_Val, *_First); // temp to enable _First == _Dest + *_Dest = _STD move(_Val); + _Val = _STD move(_Tmp); } } @@ -4471,9 +4500,10 @@ _FwdIt2 _Inclusive_scan_per_chunk( // _Val. // pre: _Val is *uninitialized* && _First != _Last if constexpr (is_same_v<_No_init_tag, remove_const_t>>) { - _STD _Construct_in_place(_Val, *_First); + _STD _Implicit_construct_in_place_by_deref(_Val, _First); } else { - _STD _Construct_in_place(_Val, _Reduce_op(_STD forward<_Ty_fwd>(_Predecessor), *_First)); + _STD _Implicit_construct_in_place_by_binary_op_deref_rhs( + _Val, _Reduce_op, _STD forward<_Ty_fwd>(_Predecessor), _First); } for (;;) { @@ -4645,7 +4675,7 @@ _FwdIt2 _Transform_exclusive_scan_per_chunk( // Local-sum for parallel transform_exclusive_scan; writes local sums into [_Dest + 1, _Dest + (_Last - _First)) and // stores successor sum in _Val. // pre: _Val is *uninitialized* && _First != _Last - _STD _Construct_in_place(_Val, _Transform_op(*_First)); + _STD _Implicit_construct_in_place_by_transform_deref(_Val, _Transform_op, _First); for (;;) { ++_First; ++_Dest; @@ -4653,9 +4683,9 @@ _FwdIt2 _Transform_exclusive_scan_per_chunk( return _Dest; } - _Ty _Tmp(_Reduce_op(_Val, _Transform_op(*_First))); // temp to enable _First == _Dest - *_Dest = _Val; - _Val = _STD move(_Tmp); + _Ty _Tmp = _Reduce_op(_Val, _Transform_op(*_First)); // temp to enable _First == _Dest + *_Dest = _Val; + _Val = _STD move(_Tmp); } } @@ -4665,13 +4695,13 @@ void _Transform_exclusive_scan_per_chunk_complete(_FwdIt1 _First, const _FwdIt1 // Sum for parallel transform_exclusive_scan with predecessor available, into [_Dest, _Dest + (_Last - _First)) and // stores successor sum in _Val. // pre: _Val is *uninitialized* && _First != _Last && predecessor sum is in _Init - _STD _Construct_in_place(_Val, _Reduce_op(_Init, _Transform_op(*_First))); + _STD _Implicit_construct_in_place_by_binary_op_transform_deref_rhs(_Val, _Reduce_op, _Transform_op, _Init, _First); *_Dest = _Init; while (++_First != _Last) { ++_Dest; - _Ty _Tmp(_Reduce_op(_Val, _Transform_op(*_First))); // temp to enable _First == _Dest - *_Dest = _STD move(_Val); - _Val = _STD move(_Tmp); + _Ty _Tmp = _Reduce_op(_Val, _Transform_op(*_First)); // temp to enable _First == _Dest + *_Dest = _STD move(_Val); + _Val = _STD move(_Tmp); } } @@ -4791,9 +4821,10 @@ _FwdIt2 _Transform_inclusive_scan_per_chunk(_FwdIt1 _First, const _FwdIt1 _Last, // sum in _Val // pre: _Val is *uninitialized* && _First != _Last if constexpr (is_same_v<_No_init_tag, remove_const_t>>) { - _STD _Construct_in_place(_Val, _Transform_op(*_First)); + _STD _Implicit_construct_in_place_by_transform_deref(_Val, _Transform_op, _First); } else { - _STD _Construct_in_place(_Val, _Reduce_op(_STD forward<_Ty_fwd>(_Predecessor), _Transform_op(*_First))); + _STD _Implicit_construct_in_place_by_binary_op_transform_deref_rhs( + _Val, _Reduce_op, _Transform_op, _STD forward<_Ty_fwd>(_Predecessor), _First); } for (;;) { diff --git a/stl/inc/numeric b/stl/inc/numeric index f10480a3d8c..3961465d2d6 100644 --- a/stl/inc/numeric +++ b/stl/inc/numeric @@ -281,7 +281,7 @@ _CONSTEXPR20 _OutIt exclusive_scan(const _InIt _First, const _InIt _Last, _OutIt auto _UDest = _STD _Get_unwrapped_n(_Dest, _STD _Idl_distance<_InIt>(_UFirst, _ULast)); if (_UFirst != _ULast) { for (;;) { - _Ty _Tmp(_Reduce_op(_Val, *_UFirst)); // temp to enable _First == _Dest, also requirement missing + _Ty _Tmp = _Reduce_op(_Val, *_UFirst); // temp to enable _First == _Dest, also requirement missing *_UDest = _Val; ++_UDest; ++_UFirst; @@ -389,7 +389,7 @@ _CONSTEXPR20 _OutIt transform_exclusive_scan( auto _UDest = _STD _Get_unwrapped_n(_Dest, _STD _Idl_distance<_InIt>(_UFirst, _ULast)); if (_UFirst != _ULast) { for (;;) { - _Ty _Tmp(_Reduce_op(_Val, _Transform_op(*_UFirst))); // temp to enable _First == _Dest + _Ty _Tmp = _Reduce_op(_Val, _Transform_op(*_UFirst)); // temp to enable _First == _Dest *_UDest = _Val; ++_UDest; ++_UFirst; diff --git a/tests/std/test.lst b/tests/std/test.lst index 5a7f22df0b8..41725cfcbd8 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -237,6 +237,7 @@ tests\GH_003867_output_nan tests\GH_004023_mdspan_fwd_prod_overflow tests\GH_004040_container_nonmember_functions tests\GH_004109_iter_value_t_direct_initialization +tests\GH_004129_conversion_in_new_numeric_algorithms tests\GH_004201_chrono_formatter tests\GH_004275_seeking_fancy_iterators tests\LWG2381_num_get_floating_point diff --git a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/env.lst b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/env.lst new file mode 100644 index 00000000000..2de7aab2959 --- /dev/null +++ b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_17_matrix.lst diff --git a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp new file mode 100644 index 00000000000..d8a8b33dd6d --- /dev/null +++ b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp @@ -0,0 +1,149 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// intentionally test narrowing conversion form int64_t to int32_t +#pragma warning(disable : 4244) + +#include +#include +#include +#include +#include + +using namespace std; +using namespace std::execution; + +struct implicitly_convertible_to_i32_only { + int32_t n; + + template + explicit operator int32_t() const = delete; + + operator int64_t() const noexcept { + return n; + } +}; + +static_assert(!is_constructible_v); +static_assert(is_convertible_v); + +struct implicity_validating_converter { + implicitly_convertible_to_i32_only operator()(int n) const noexcept { + return {n}; + } +}; + +struct implicity_validating_plus { + implicitly_convertible_to_i32_only operator()( + implicitly_convertible_to_i32_only l, implicitly_convertible_to_i32_only r) const noexcept { + return implicitly_convertible_to_i32_only{l.n + r.n}; + } + + implicitly_convertible_to_i32_only operator()(int32_t l, implicitly_convertible_to_i32_only r) const noexcept { + return implicitly_convertible_to_i32_only{l + r.n}; + } + + implicitly_convertible_to_i32_only operator()(implicitly_convertible_to_i32_only l, int32_t r) const noexcept { + return implicitly_convertible_to_i32_only{l.n + r}; + } + + implicitly_convertible_to_i32_only operator()(int32_t l, int32_t r) const noexcept { + return implicitly_convertible_to_i32_only{l + r}; + } +}; + +struct implicity_validating_multiplies { + implicitly_convertible_to_i32_only operator()( + implicitly_convertible_to_i32_only l, implicitly_convertible_to_i32_only r) const noexcept { + return implicitly_convertible_to_i32_only{l.n * r.n}; + } + + implicitly_convertible_to_i32_only operator()(int32_t l, implicitly_convertible_to_i32_only r) const noexcept { + return implicitly_convertible_to_i32_only{l * r.n}; + } + + implicitly_convertible_to_i32_only operator()(implicitly_convertible_to_i32_only l, int32_t r) const noexcept { + return implicitly_convertible_to_i32_only{l.n * r}; + } + + implicitly_convertible_to_i32_only operator()(int32_t l, int32_t r) const noexcept { + return implicitly_convertible_to_i32_only{l * r}; + } +}; + +void test_copy_initialization_for_numeric_algorithms() { + int arr[1]{}; + implicitly_convertible_to_i32_only brr[1]{}; + + assert(reduce(arr, arr, int32_t{}, implicity_validating_plus{}) == 0); + assert(reduce(brr, brr, int32_t{}, implicity_validating_plus{}) == 0); + + assert(transform_reduce(arr, arr, arr, int32_t{}, implicity_validating_plus{}, implicity_validating_multiplies{}) + == 0); + assert(transform_reduce(arr, arr, brr, int32_t{}, implicity_validating_plus{}, implicity_validating_multiplies{}) + == 0); + + assert(transform_reduce(arr, arr, int32_t{}, implicity_validating_plus{}, implicity_validating_converter{}) == 0); + assert(transform_reduce(brr, brr, int32_t{}, implicity_validating_plus{}, implicity_validating_converter{}) == 0); + + assert(exclusive_scan(arr, arr, arr, int32_t{}, implicity_validating_plus{}) == arr); + + assert(inclusive_scan(arr, arr, arr, implicity_validating_plus{}) == arr); + assert(inclusive_scan(arr, arr, arr, implicity_validating_plus{}, int32_t{}) == arr); + + assert(transform_exclusive_scan( + arr, arr, arr, int32_t{}, implicity_validating_plus{}, implicity_validating_converter{}) + == arr); + + assert( + transform_inclusive_scan(brr, brr, brr, implicity_validating_plus{}, implicity_validating_converter{}) == brr); + assert(transform_inclusive_scan( + arr, arr, arr, implicity_validating_plus{}, implicity_validating_converter{}, int32_t{}) + == arr); +} + +template +void test_copy_initialization_for_parallel_numeric_algorithms() { + int arr[1]{}; + implicitly_convertible_to_i32_only brr[1]{}; + + assert(reduce(ExPo, arr, arr, int32_t{}, implicity_validating_plus{}) == 0); + assert(reduce(ExPo, brr, brr, int32_t{}, implicity_validating_plus{}) == 0); + + assert( + transform_reduce(ExPo, arr, arr, arr, int32_t{}, implicity_validating_plus{}, implicity_validating_multiplies{}) + == 0); + assert( + transform_reduce(ExPo, arr, arr, brr, int32_t{}, implicity_validating_plus{}, implicity_validating_multiplies{}) + == 0); + + assert(transform_reduce(ExPo, arr, arr, int32_t{}, implicity_validating_plus{}, implicity_validating_converter{}) + == 0); + assert(transform_reduce(ExPo, brr, brr, int32_t{}, implicity_validating_plus{}, implicity_validating_converter{}) + == 0); + + assert(exclusive_scan(ExPo, arr, arr, arr, int32_t{}, implicity_validating_plus{}) == arr); + + assert(inclusive_scan(ExPo, arr, arr, arr, implicity_validating_plus{}) == arr); + assert(inclusive_scan(ExPo, arr, arr, arr, implicity_validating_plus{}, int32_t{}) == arr); + + assert(transform_exclusive_scan( + ExPo, arr, arr, arr, int32_t{}, implicity_validating_plus{}, implicity_validating_converter{}) + == arr); + + assert(transform_inclusive_scan(ExPo, brr, brr, brr, implicity_validating_plus{}, implicity_validating_converter{}) + == brr); + assert(transform_inclusive_scan( + ExPo, arr, arr, arr, implicity_validating_plus{}, implicity_validating_converter{}, int32_t{}) + == arr); +} + +int main() { + test_copy_initialization_for_numeric_algorithms(); + test_copy_initialization_for_parallel_numeric_algorithms(); + test_copy_initialization_for_parallel_numeric_algorithms(); + test_copy_initialization_for_parallel_numeric_algorithms(); +#if _HAS_CXX20 + test_copy_initialization_for_parallel_numeric_algorithms(); +#endif // _HAS_CXX20 +} From e84c2d7ceb98752b99d45bb18a47b10a68d4cda8 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 23 Feb 2024 08:03:09 +0800 Subject: [PATCH 02/10] Missed Clang-format --- stl/inc/numeric | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/numeric b/stl/inc/numeric index 3961465d2d6..ffe819a36e3 100644 --- a/stl/inc/numeric +++ b/stl/inc/numeric @@ -282,7 +282,7 @@ _CONSTEXPR20 _OutIt exclusive_scan(const _InIt _First, const _InIt _Last, _OutIt if (_UFirst != _ULast) { for (;;) { _Ty _Tmp = _Reduce_op(_Val, *_UFirst); // temp to enable _First == _Dest, also requirement missing - *_UDest = _Val; + *_UDest = _Val; ++_UDest; ++_UFirst; if (_UFirst == _ULast) { @@ -390,7 +390,7 @@ _CONSTEXPR20 _OutIt transform_exclusive_scan( if (_UFirst != _ULast) { for (;;) { _Ty _Tmp = _Reduce_op(_Val, _Transform_op(*_UFirst)); // temp to enable _First == _Dest - *_UDest = _Val; + *_UDest = _Val; ++_UDest; ++_UFirst; if (_UFirst == _ULast) { From 3f811a986858b9301ce6882eabc5becb3394c7e2 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 23 Feb 2024 10:30:28 +0800 Subject: [PATCH 03/10] Try to fix old and new tests - s/_Implicit_construct/_Implicitly_construct - Restore some default-initialization --- stl/inc/execution | 33 ++++++----- .../test.cpp | 58 +++++++++++++++---- .../test.cpp | 3 +- .../test.cpp | 3 +- .../test.cpp | 4 +- .../test.cpp | 4 +- 6 files changed, 73 insertions(+), 32 deletions(-) diff --git a/stl/inc/execution b/stl/inc/execution index 845158c063d..a6a302187b0 100644 --- a/stl/inc/execution +++ b/stl/inc/execution @@ -138,29 +138,29 @@ struct is_execution_policy : true_type {}; #endif // _HAS_CXX20 template -void _Implicit_construct_in_place_by_deref(_Ty& _Val, const _FwdIt& _Iter) { - ::new (static_cast(_STD addressof(_Val))) _Ty([&]() -> _Ty { return *_Iter; }()); +void _Construct_in_place_by_deref(_Ty& _Val, const _FwdIt& _Iter) { + ::new (static_cast(_STD addressof(_Val))) _Ty(*_Iter); } template -void _Implicit_construct_in_place_by_transform_deref(_Ty& _Val, _UnaryOp& _Tranform_op, const _FwdIt& _Iter) { - ::new (static_cast(_STD addressof(_Val))) _Ty([&]() -> _Ty { return _Tranform_op(*_Iter); }()); +void _Construct_in_place_by_transform_deref(_Ty& _Val, _UnaryOp& _Tranform_op, const _FwdIt& _Iter) { + ::new (static_cast(_STD addressof(_Val))) _Ty(_Tranform_op(*_Iter)); } template -void _Implicit_construct_in_place_by_binary_op(_Ty& _Val, _BinaryOp& _Reduce_op, _ArgTy& _Left, _ArgTy& _Right) { +void _Implicitly_construct_in_place_by_binary_op(_Ty& _Val, _BinaryOp& _Reduce_op, _ArgTy& _Left, _ArgTy& _Right) { ::new (static_cast(_STD addressof(_Val))) _Ty([&]() -> _Ty { return _Reduce_op(_Left, _Right); }()); } template -void _Implicit_construct_in_place_by_binary_op_deref_rhs( +void _Implicitly_construct_in_place_by_binary_op_deref_rhs( _Ty& _Val, _BinaryOp& _Reduce_op, _LeftTy&& _Left, const _FwdIt& _Iter) { ::new (static_cast(_STD addressof(_Val))) _Ty([&]() -> _Ty { return _Reduce_op(_STD forward<_LeftTy>(_Left), *_Iter); }()); } template -void _Implicit_construct_in_place_by_binary_op_transform_deref_rhs( +void _Implicitly_construct_in_place_by_binary_op_transform_deref_rhs( _Ty& _Val, _BinaryOp& _Reduce_op, _UnaryOp& _Transform_op, _LeftTy&& _Left, const _FwdIt& _Iter) { ::new (static_cast(_STD addressof(_Val))) _Ty([&]() -> _Ty { return _Reduce_op(_STD forward<_LeftTy>(_Left), _Transform_op(*_Iter)); }()); @@ -3631,7 +3631,7 @@ struct _Scan_decoupled_lookback { template void _Apply_exclusive_predecessor(_Ty& _Preceding, _FwdIt _First, const _FwdIt _Last, _BinOp _Reduce_op) { // apply _Preceding to [_First, _Last) and _Sum._Ref(), using _Reduce_op - _STD _Implicit_construct_in_place_by_binary_op(_Sum._Ref(), _Reduce_op, _Preceding, _Local._Ref()); + _STD _Implicitly_construct_in_place_by_binary_op(_Sum._Ref(), _Reduce_op, _Preceding, _Local._Ref()); _State.store(_Local_available | _Sum_available); *_First = _Preceding; @@ -3644,7 +3644,7 @@ struct _Scan_decoupled_lookback { template void _Apply_inclusive_predecessor(_Ty& _Preceding, _FwdIt _First, const _FwdIt _Last, _BinOp _Reduce_op) { // apply _Preceding to [_First, _Last) and _Sum._Ref(), using _Reduce_op - _STD _Implicit_construct_in_place_by_binary_op(_Sum._Ref(), _Reduce_op, _Preceding, _Local._Ref()); + _STD _Implicitly_construct_in_place_by_binary_op(_Sum._Ref(), _Reduce_op, _Preceding, _Local._Ref()); _State.store(_Local_available | _Sum_available); #pragma loop(ivdep) @@ -4375,7 +4375,7 @@ void _Exclusive_scan_per_chunk_complete( // Sum for parallel exclusive_scan with predecessor available, into [_Dest, _Dest + (_Last - _First)) and stores // successor sum in _Val. // Pre: _Val is *uninitialized* && _First != _Last && predecessor sum is in _Init - _STD _Implicit_construct_in_place_by_binary_op_deref_rhs(_Val, _Reduce_op, _Init, _First); + _STD _Implicitly_construct_in_place_by_binary_op_deref_rhs(_Val, _Reduce_op, _Init, _First); *_Dest = _Init; while (++_First != _Last) { ++_Dest; @@ -4500,9 +4500,9 @@ _FwdIt2 _Inclusive_scan_per_chunk( // _Val. // pre: _Val is *uninitialized* && _First != _Last if constexpr (is_same_v<_No_init_tag, remove_const_t>>) { - _STD _Implicit_construct_in_place_by_deref(_Val, _First); + _STD _Construct_in_place_by_deref(_Val, _First); } else { - _STD _Implicit_construct_in_place_by_binary_op_deref_rhs( + _STD _Implicitly_construct_in_place_by_binary_op_deref_rhs( _Val, _Reduce_op, _STD forward<_Ty_fwd>(_Predecessor), _First); } @@ -4675,7 +4675,7 @@ _FwdIt2 _Transform_exclusive_scan_per_chunk( // Local-sum for parallel transform_exclusive_scan; writes local sums into [_Dest + 1, _Dest + (_Last - _First)) and // stores successor sum in _Val. // pre: _Val is *uninitialized* && _First != _Last - _STD _Implicit_construct_in_place_by_transform_deref(_Val, _Transform_op, _First); + _STD _Construct_in_place_by_transform_deref(_Val, _Transform_op, _First); for (;;) { ++_First; ++_Dest; @@ -4695,7 +4695,8 @@ void _Transform_exclusive_scan_per_chunk_complete(_FwdIt1 _First, const _FwdIt1 // Sum for parallel transform_exclusive_scan with predecessor available, into [_Dest, _Dest + (_Last - _First)) and // stores successor sum in _Val. // pre: _Val is *uninitialized* && _First != _Last && predecessor sum is in _Init - _STD _Implicit_construct_in_place_by_binary_op_transform_deref_rhs(_Val, _Reduce_op, _Transform_op, _Init, _First); + _STD _Implicitly_construct_in_place_by_binary_op_transform_deref_rhs( + _Val, _Reduce_op, _Transform_op, _Init, _First); *_Dest = _Init; while (++_First != _Last) { ++_Dest; @@ -4821,9 +4822,9 @@ _FwdIt2 _Transform_inclusive_scan_per_chunk(_FwdIt1 _First, const _FwdIt1 _Last, // sum in _Val // pre: _Val is *uninitialized* && _First != _Last if constexpr (is_same_v<_No_init_tag, remove_const_t>>) { - _STD _Implicit_construct_in_place_by_transform_deref(_Val, _Transform_op, _First); + _STD _Construct_in_place_by_transform_deref(_Val, _Transform_op, _First); } else { - _STD _Implicit_construct_in_place_by_binary_op_transform_deref_rhs( + _STD _Implicitly_construct_in_place_by_binary_op_transform_deref_rhs( _Val, _Reduce_op, _Transform_op, _STD forward<_Ty_fwd>(_Predecessor), _First); } diff --git a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp index d8a8b33dd6d..555da0fb6a4 100644 --- a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp +++ b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp @@ -33,6 +33,23 @@ struct implicity_validating_converter { } }; +struct explicitly_convertible_to_i32_only { + int32_t n; + + explicit operator int32_t() const noexcept { + return n; + } +}; + +static_assert(is_constructible_v); +static_assert(!is_convertible_v); + +struct tranformation_validating_converter { + explicitly_convertible_to_i32_only operator()(int n) const noexcept { + return {n}; + } +}; + struct implicity_validating_plus { implicitly_convertible_to_i32_only operator()( implicitly_convertible_to_i32_only l, implicitly_convertible_to_i32_only r) const noexcept { @@ -52,6 +69,25 @@ struct implicity_validating_plus { } }; +struct implicity_validating_plus_for_transformation { + implicitly_convertible_to_i32_only operator()( + explicitly_convertible_to_i32_only l, explicitly_convertible_to_i32_only r) const noexcept { + return implicitly_convertible_to_i32_only{l.n + r.n}; + } + + implicitly_convertible_to_i32_only operator()(int32_t l, explicitly_convertible_to_i32_only r) const noexcept { + return implicitly_convertible_to_i32_only{l + r.n}; + } + + implicitly_convertible_to_i32_only operator()(explicitly_convertible_to_i32_only l, int32_t r) const noexcept { + return implicitly_convertible_to_i32_only{l.n + r}; + } + + implicitly_convertible_to_i32_only operator()(int32_t l, int32_t r) const noexcept { + return implicitly_convertible_to_i32_only{l + r}; + } +}; + struct implicity_validating_multiplies { implicitly_convertible_to_i32_only operator()( implicitly_convertible_to_i32_only l, implicitly_convertible_to_i32_only r) const noexcept { @@ -91,14 +127,15 @@ void test_copy_initialization_for_numeric_algorithms() { assert(inclusive_scan(arr, arr, arr, implicity_validating_plus{}) == arr); assert(inclusive_scan(arr, arr, arr, implicity_validating_plus{}, int32_t{}) == arr); - assert(transform_exclusive_scan( - arr, arr, arr, int32_t{}, implicity_validating_plus{}, implicity_validating_converter{}) + assert(transform_exclusive_scan(arr, arr, arr, int32_t{}, implicity_validating_plus_for_transformation{}, + tranformation_validating_converter{}) == arr); - assert( - transform_inclusive_scan(brr, brr, brr, implicity_validating_plus{}, implicity_validating_converter{}) == brr); assert(transform_inclusive_scan( - arr, arr, arr, implicity_validating_plus{}, implicity_validating_converter{}, int32_t{}) + brr, brr, brr, implicity_validating_plus_for_transformation{}, tranformation_validating_converter{}) + == brr); + assert(transform_inclusive_scan(arr, arr, arr, implicity_validating_plus_for_transformation{}, + tranformation_validating_converter{}, int32_t{}) == arr); } @@ -127,14 +164,15 @@ void test_copy_initialization_for_parallel_numeric_algorithms() { assert(inclusive_scan(ExPo, arr, arr, arr, implicity_validating_plus{}) == arr); assert(inclusive_scan(ExPo, arr, arr, arr, implicity_validating_plus{}, int32_t{}) == arr); - assert(transform_exclusive_scan( - ExPo, arr, arr, arr, int32_t{}, implicity_validating_plus{}, implicity_validating_converter{}) + assert(transform_exclusive_scan(ExPo, arr, arr, arr, int32_t{}, implicity_validating_plus_for_transformation{}, + tranformation_validating_converter{}) == arr); - assert(transform_inclusive_scan(ExPo, brr, brr, brr, implicity_validating_plus{}, implicity_validating_converter{}) + assert(transform_inclusive_scan(ExPo, brr, brr, brr, implicity_validating_plus_for_transformation{}, + tranformation_validating_converter{}) == brr); - assert(transform_inclusive_scan( - ExPo, arr, arr, arr, implicity_validating_plus{}, implicity_validating_converter{}, int32_t{}) + assert(transform_inclusive_scan(ExPo, arr, arr, arr, implicity_validating_plus_for_transformation{}, + tranformation_validating_converter{}, int32_t{}) == arr); } diff --git a/tests/std/tests/P0024R2_parallel_algorithms_exclusive_scan/test.cpp b/tests/std/tests/P0024R2_parallel_algorithms_exclusive_scan/test.cpp index cdb0c7578dc..5a00a8d07b9 100644 --- a/tests/std/tests/P0024R2_parallel_algorithms_exclusive_scan/test.cpp +++ b/tests/std/tests/P0024R2_parallel_algorithms_exclusive_scan/test.cpp @@ -126,7 +126,8 @@ struct intermediateType { intermediateType() = delete; explicit intermediateType(int) {} // so that the test can make one of these explicit intermediateType(inputType&) {} // Intermediate tmp(*first) - explicit intermediateType(bopResult&&) {} // Intermediate tmp(binary_op((one of tmp, move(tmp), *first), *first)) + // Intermediate tmp = binary_op((one of tmp, move(tmp), *first), *first); + /* implicit */ intermediateType(bopResult&&) {} intermediateType(const intermediateType&) = delete; intermediateType(intermediateType&&) = default; // tmp = move(tmp) intermediateType& operator=(const intermediateType&) = delete; diff --git a/tests/std/tests/P0024R2_parallel_algorithms_inclusive_scan/test.cpp b/tests/std/tests/P0024R2_parallel_algorithms_inclusive_scan/test.cpp index eddb7b3b6b8..a3ecee5b3bd 100644 --- a/tests/std/tests/P0024R2_parallel_algorithms_inclusive_scan/test.cpp +++ b/tests/std/tests/P0024R2_parallel_algorithms_inclusive_scan/test.cpp @@ -135,7 +135,8 @@ struct intermediateType { intermediateType() = delete; explicit intermediateType(int) {} // so that the test can make one of these explicit intermediateType(inputType&) {} // Intermediate tmp(*first) - explicit intermediateType(bopResult&&) {} // Intermediate tmp(binary_op((one of tmp, move(tmp), *first), *first)) + // Intermediate tmp = binary_op((one of tmp, move(tmp), *first), *first); + /* implicit */ intermediateType(bopResult&&) {} intermediateType(const intermediateType&) = delete; intermediateType(intermediateType&&) = default; // tmp = move(tmp) intermediateType& operator=(const intermediateType&) = delete; diff --git a/tests/std/tests/P0024R2_parallel_algorithms_transform_exclusive_scan/test.cpp b/tests/std/tests/P0024R2_parallel_algorithms_transform_exclusive_scan/test.cpp index 96c6bd1f85d..7cb3d6f11d6 100644 --- a/tests/std/tests/P0024R2_parallel_algorithms_transform_exclusive_scan/test.cpp +++ b/tests/std/tests/P0024R2_parallel_algorithms_transform_exclusive_scan/test.cpp @@ -115,8 +115,8 @@ struct intermediateType { intermediateType() = delete; explicit intermediateType(int) {} // so that the test can make one of these explicit intermediateType(transformedType&&) {} // Intermediate tmp(unary_op(*first)) - // Intermediate tmp(binary_op((one of tmp, move(tmp), unary_op(*first)), unary_op(*first))) - explicit intermediateType(bopResult&&) {} + // Intermediate tmp = binary_op((one of tmp, move(tmp), unary_op(*first)), unary_op(*first)); + /* implicit */ intermediateType(bopResult&&) {} intermediateType(const intermediateType&) = delete; intermediateType(intermediateType&&) = default; // tmp = move(tmp) intermediateType& operator=(const intermediateType&) = delete; diff --git a/tests/std/tests/P0024R2_parallel_algorithms_transform_inclusive_scan/test.cpp b/tests/std/tests/P0024R2_parallel_algorithms_transform_inclusive_scan/test.cpp index 7608cfc7e63..c54e01aa69d 100644 --- a/tests/std/tests/P0024R2_parallel_algorithms_transform_inclusive_scan/test.cpp +++ b/tests/std/tests/P0024R2_parallel_algorithms_transform_inclusive_scan/test.cpp @@ -139,8 +139,8 @@ struct intermediateType { intermediateType() = delete; explicit intermediateType(int) {} // so that the test can make one of these explicit intermediateType(transformedType&&) {} // Intermediate tmp(unary_op(*first)) - // Intermediate tmp(binary_op((one of tmp, move(tmp), unary_op(*first)), unary_op(*first))) - explicit intermediateType(bopResult&&) {} + // Intermediate tmp = binary_op((one of tmp, move(tmp), unary_op(*first)), unary_op(*first)); + /* implicit */ intermediateType(bopResult&&) {} intermediateType(const intermediateType&) = delete; intermediateType(intermediateType&&) = default; // tmp = move(tmp) intermediateType& operator=(const intermediateType&) = delete; From e2b2cc2ab301e63f20ec58b25508ead26b52719b Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 23 Feb 2024 11:58:22 +0800 Subject: [PATCH 04/10] Drop mistaken case for `transform_inclusive_scan` --- .../GH_004129_conversion_in_new_numeric_algorithms/test.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp index 555da0fb6a4..1fe551ce763 100644 --- a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp +++ b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp @@ -131,9 +131,6 @@ void test_copy_initialization_for_numeric_algorithms() { tranformation_validating_converter{}) == arr); - assert(transform_inclusive_scan( - brr, brr, brr, implicity_validating_plus_for_transformation{}, tranformation_validating_converter{}) - == brr); assert(transform_inclusive_scan(arr, arr, arr, implicity_validating_plus_for_transformation{}, tranformation_validating_converter{}, int32_t{}) == arr); @@ -168,9 +165,6 @@ void test_copy_initialization_for_parallel_numeric_algorithms() { tranformation_validating_converter{}) == arr); - assert(transform_inclusive_scan(ExPo, brr, brr, brr, implicity_validating_plus_for_transformation{}, - tranformation_validating_converter{}) - == brr); assert(transform_inclusive_scan(ExPo, arr, arr, arr, implicity_validating_plus_for_transformation{}, tranformation_validating_converter{}, int32_t{}) == arr); From f23115bfc4c755fc05bb4d27274c17b44d63bbd3 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 24 Feb 2024 02:46:06 +0800 Subject: [PATCH 05/10] Revert the removal by restoration --- .../GH_004129_conversion_in_new_numeric_algorithms/test.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp index 1fe551ce763..66ed0913e93 100644 --- a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp +++ b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp @@ -131,6 +131,8 @@ void test_copy_initialization_for_numeric_algorithms() { tranformation_validating_converter{}) == arr); + assert( + transform_inclusive_scan(brr, brr, brr, implicity_validating_plus{}, implicity_validating_converter{}) == brr); assert(transform_inclusive_scan(arr, arr, arr, implicity_validating_plus_for_transformation{}, tranformation_validating_converter{}, int32_t{}) == arr); @@ -165,6 +167,8 @@ void test_copy_initialization_for_parallel_numeric_algorithms() { tranformation_validating_converter{}) == arr); + assert(transform_inclusive_scan(ExPo, brr, brr, brr, implicity_validating_plus{}, implicity_validating_converter{})  + == brr); assert(transform_inclusive_scan(ExPo, arr, arr, arr, implicity_validating_plus_for_transformation{}, tranformation_validating_converter{}, int32_t{}) == arr); From eb360dfab36018a50ebf70cdbcf74368979d1549 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 24 Feb 2024 03:02:54 +0800 Subject: [PATCH 06/10] Remove an accidentally inserted U+3000 --- .../GH_004129_conversion_in_new_numeric_algorithms/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp index 66ed0913e93..a273cd111d7 100644 --- a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp +++ b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp @@ -167,7 +167,7 @@ void test_copy_initialization_for_parallel_numeric_algorithms() { tranformation_validating_converter{}) == arr); - assert(transform_inclusive_scan(ExPo, brr, brr, brr, implicity_validating_plus{}, implicity_validating_converter{})  + assert(transform_inclusive_scan(ExPo, brr, brr, brr, implicity_validating_plus{}, implicity_validating_converter{}) == brr); assert(transform_inclusive_scan(ExPo, arr, arr, arr, implicity_validating_plus_for_transformation{}, tranformation_validating_converter{}, int32_t{}) From 48e470219fa3fca5095a02395fc2c967fa6bcd95 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 28 Feb 2024 16:34:08 -0800 Subject: [PATCH 07/10] Fix typos: tranform => transform (preserving case) --- stl/inc/execution | 4 ++-- .../test.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/stl/inc/execution b/stl/inc/execution index a6a302187b0..35de4f23b2a 100644 --- a/stl/inc/execution +++ b/stl/inc/execution @@ -143,8 +143,8 @@ void _Construct_in_place_by_deref(_Ty& _Val, const _FwdIt& _Iter) { } template -void _Construct_in_place_by_transform_deref(_Ty& _Val, _UnaryOp& _Tranform_op, const _FwdIt& _Iter) { - ::new (static_cast(_STD addressof(_Val))) _Ty(_Tranform_op(*_Iter)); +void _Construct_in_place_by_transform_deref(_Ty& _Val, _UnaryOp& _Transform_op, const _FwdIt& _Iter) { + ::new (static_cast(_STD addressof(_Val))) _Ty(_Transform_op(*_Iter)); } template diff --git a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp index a273cd111d7..c8cf5be958f 100644 --- a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp +++ b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp @@ -44,7 +44,7 @@ struct explicitly_convertible_to_i32_only { static_assert(is_constructible_v); static_assert(!is_convertible_v); -struct tranformation_validating_converter { +struct transformation_validating_converter { explicitly_convertible_to_i32_only operator()(int n) const noexcept { return {n}; } @@ -128,13 +128,13 @@ void test_copy_initialization_for_numeric_algorithms() { assert(inclusive_scan(arr, arr, arr, implicity_validating_plus{}, int32_t{}) == arr); assert(transform_exclusive_scan(arr, arr, arr, int32_t{}, implicity_validating_plus_for_transformation{}, - tranformation_validating_converter{}) + transformation_validating_converter{}) == arr); assert( transform_inclusive_scan(brr, brr, brr, implicity_validating_plus{}, implicity_validating_converter{}) == brr); assert(transform_inclusive_scan(arr, arr, arr, implicity_validating_plus_for_transformation{}, - tranformation_validating_converter{}, int32_t{}) + transformation_validating_converter{}, int32_t{}) == arr); } @@ -164,13 +164,13 @@ void test_copy_initialization_for_parallel_numeric_algorithms() { assert(inclusive_scan(ExPo, arr, arr, arr, implicity_validating_plus{}, int32_t{}) == arr); assert(transform_exclusive_scan(ExPo, arr, arr, arr, int32_t{}, implicity_validating_plus_for_transformation{}, - tranformation_validating_converter{}) + transformation_validating_converter{}) == arr); assert(transform_inclusive_scan(ExPo, brr, brr, brr, implicity_validating_plus{}, implicity_validating_converter{}) == brr); assert(transform_inclusive_scan(ExPo, arr, arr, arr, implicity_validating_plus_for_transformation{}, - tranformation_validating_converter{}, int32_t{}) + transformation_validating_converter{}, int32_t{}) == arr); } From 685f457afe250237147235d8cbc8bc249b91664d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 28 Feb 2024 17:02:38 -0800 Subject: [PATCH 08/10] Fix typos: implicity => implicitly --- .../test.cpp | 69 ++++++++++--------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp index c8cf5be958f..02077aa3f1e 100644 --- a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp +++ b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp @@ -27,7 +27,7 @@ struct implicitly_convertible_to_i32_only { static_assert(!is_constructible_v); static_assert(is_convertible_v); -struct implicity_validating_converter { +struct implicitly_validating_converter { implicitly_convertible_to_i32_only operator()(int n) const noexcept { return {n}; } @@ -50,7 +50,7 @@ struct transformation_validating_converter { } }; -struct implicity_validating_plus { +struct implicitly_validating_plus { implicitly_convertible_to_i32_only operator()( implicitly_convertible_to_i32_only l, implicitly_convertible_to_i32_only r) const noexcept { return implicitly_convertible_to_i32_only{l.n + r.n}; @@ -69,7 +69,7 @@ struct implicity_validating_plus { } }; -struct implicity_validating_plus_for_transformation { +struct implicitly_validating_plus_for_transformation { implicitly_convertible_to_i32_only operator()( explicitly_convertible_to_i32_only l, explicitly_convertible_to_i32_only r) const noexcept { return implicitly_convertible_to_i32_only{l.n + r.n}; @@ -88,7 +88,7 @@ struct implicity_validating_plus_for_transformation { } }; -struct implicity_validating_multiplies { +struct implicitly_validating_multiplies { implicitly_convertible_to_i32_only operator()( implicitly_convertible_to_i32_only l, implicitly_convertible_to_i32_only r) const noexcept { return implicitly_convertible_to_i32_only{l.n * r.n}; @@ -111,29 +111,29 @@ void test_copy_initialization_for_numeric_algorithms() { int arr[1]{}; implicitly_convertible_to_i32_only brr[1]{}; - assert(reduce(arr, arr, int32_t{}, implicity_validating_plus{}) == 0); - assert(reduce(brr, brr, int32_t{}, implicity_validating_plus{}) == 0); + assert(reduce(arr, arr, int32_t{}, implicitly_validating_plus{}) == 0); + assert(reduce(brr, brr, int32_t{}, implicitly_validating_plus{}) == 0); - assert(transform_reduce(arr, arr, arr, int32_t{}, implicity_validating_plus{}, implicity_validating_multiplies{}) + assert(transform_reduce(arr, arr, arr, int32_t{}, implicitly_validating_plus{}, implicitly_validating_multiplies{}) == 0); - assert(transform_reduce(arr, arr, brr, int32_t{}, implicity_validating_plus{}, implicity_validating_multiplies{}) + assert(transform_reduce(arr, arr, brr, int32_t{}, implicitly_validating_plus{}, implicitly_validating_multiplies{}) == 0); - assert(transform_reduce(arr, arr, int32_t{}, implicity_validating_plus{}, implicity_validating_converter{}) == 0); - assert(transform_reduce(brr, brr, int32_t{}, implicity_validating_plus{}, implicity_validating_converter{}) == 0); + assert(transform_reduce(arr, arr, int32_t{}, implicitly_validating_plus{}, implicitly_validating_converter{}) == 0); + assert(transform_reduce(brr, brr, int32_t{}, implicitly_validating_plus{}, implicitly_validating_converter{}) == 0); - assert(exclusive_scan(arr, arr, arr, int32_t{}, implicity_validating_plus{}) == arr); + assert(exclusive_scan(arr, arr, arr, int32_t{}, implicitly_validating_plus{}) == arr); - assert(inclusive_scan(arr, arr, arr, implicity_validating_plus{}) == arr); - assert(inclusive_scan(arr, arr, arr, implicity_validating_plus{}, int32_t{}) == arr); + assert(inclusive_scan(arr, arr, arr, implicitly_validating_plus{}) == arr); + assert(inclusive_scan(arr, arr, arr, implicitly_validating_plus{}, int32_t{}) == arr); - assert(transform_exclusive_scan(arr, arr, arr, int32_t{}, implicity_validating_plus_for_transformation{}, + assert(transform_exclusive_scan(arr, arr, arr, int32_t{}, implicitly_validating_plus_for_transformation{}, transformation_validating_converter{}) == arr); - assert( - transform_inclusive_scan(brr, brr, brr, implicity_validating_plus{}, implicity_validating_converter{}) == brr); - assert(transform_inclusive_scan(arr, arr, arr, implicity_validating_plus_for_transformation{}, + assert(transform_inclusive_scan(brr, brr, brr, implicitly_validating_plus{}, implicitly_validating_converter{}) + == brr); + assert(transform_inclusive_scan(arr, arr, arr, implicitly_validating_plus_for_transformation{}, transformation_validating_converter{}, int32_t{}) == arr); } @@ -143,33 +143,34 @@ void test_copy_initialization_for_parallel_numeric_algorithms() { int arr[1]{}; implicitly_convertible_to_i32_only brr[1]{}; - assert(reduce(ExPo, arr, arr, int32_t{}, implicity_validating_plus{}) == 0); - assert(reduce(ExPo, brr, brr, int32_t{}, implicity_validating_plus{}) == 0); + assert(reduce(ExPo, arr, arr, int32_t{}, implicitly_validating_plus{}) == 0); + assert(reduce(ExPo, brr, brr, int32_t{}, implicitly_validating_plus{}) == 0); - assert( - transform_reduce(ExPo, arr, arr, arr, int32_t{}, implicity_validating_plus{}, implicity_validating_multiplies{}) - == 0); - assert( - transform_reduce(ExPo, arr, arr, brr, int32_t{}, implicity_validating_plus{}, implicity_validating_multiplies{}) - == 0); + assert(transform_reduce( + ExPo, arr, arr, arr, int32_t{}, implicitly_validating_plus{}, implicitly_validating_multiplies{}) + == 0); + assert(transform_reduce( + ExPo, arr, arr, brr, int32_t{}, implicitly_validating_plus{}, implicitly_validating_multiplies{}) + == 0); - assert(transform_reduce(ExPo, arr, arr, int32_t{}, implicity_validating_plus{}, implicity_validating_converter{}) + assert(transform_reduce(ExPo, arr, arr, int32_t{}, implicitly_validating_plus{}, implicitly_validating_converter{}) == 0); - assert(transform_reduce(ExPo, brr, brr, int32_t{}, implicity_validating_plus{}, implicity_validating_converter{}) + assert(transform_reduce(ExPo, brr, brr, int32_t{}, implicitly_validating_plus{}, implicitly_validating_converter{}) == 0); - assert(exclusive_scan(ExPo, arr, arr, arr, int32_t{}, implicity_validating_plus{}) == arr); + assert(exclusive_scan(ExPo, arr, arr, arr, int32_t{}, implicitly_validating_plus{}) == arr); - assert(inclusive_scan(ExPo, arr, arr, arr, implicity_validating_plus{}) == arr); - assert(inclusive_scan(ExPo, arr, arr, arr, implicity_validating_plus{}, int32_t{}) == arr); + assert(inclusive_scan(ExPo, arr, arr, arr, implicitly_validating_plus{}) == arr); + assert(inclusive_scan(ExPo, arr, arr, arr, implicitly_validating_plus{}, int32_t{}) == arr); - assert(transform_exclusive_scan(ExPo, arr, arr, arr, int32_t{}, implicity_validating_plus_for_transformation{}, + assert(transform_exclusive_scan(ExPo, arr, arr, arr, int32_t{}, implicitly_validating_plus_for_transformation{}, transformation_validating_converter{}) == arr); - assert(transform_inclusive_scan(ExPo, brr, brr, brr, implicity_validating_plus{}, implicity_validating_converter{}) - == brr); - assert(transform_inclusive_scan(ExPo, arr, arr, arr, implicity_validating_plus_for_transformation{}, + assert( + transform_inclusive_scan(ExPo, brr, brr, brr, implicitly_validating_plus{}, implicitly_validating_converter{}) + == brr); + assert(transform_inclusive_scan(ExPo, arr, arr, arr, implicitly_validating_plus_for_transformation{}, transformation_validating_converter{}, int32_t{}) == arr); } From 7ef665ca923aac19c3bed15e56b7588e56c2acf8 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 28 Feb 2024 17:04:47 -0800 Subject: [PATCH 09/10] Fix typo: form => from --- .../GH_004129_conversion_in_new_numeric_algorithms/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp index 02077aa3f1e..9cf3820ad63 100644 --- a/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp +++ b/tests/std/tests/GH_004129_conversion_in_new_numeric_algorithms/test.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// intentionally test narrowing conversion form int64_t to int32_t +// intentionally test narrowing conversion from int64_t to int32_t #pragma warning(disable : 4244) #include From bb3845aa786b10d8ec4390e4698aa847ac31af72 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 28 Feb 2024 16:43:39 -0800 Subject: [PATCH 10/10] Take ops by value - they're always `_Pass_fn`. --- stl/inc/execution | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stl/inc/execution b/stl/inc/execution index 35de4f23b2a..feef95947db 100644 --- a/stl/inc/execution +++ b/stl/inc/execution @@ -143,25 +143,25 @@ void _Construct_in_place_by_deref(_Ty& _Val, const _FwdIt& _Iter) { } template -void _Construct_in_place_by_transform_deref(_Ty& _Val, _UnaryOp& _Transform_op, const _FwdIt& _Iter) { +void _Construct_in_place_by_transform_deref(_Ty& _Val, _UnaryOp _Transform_op, const _FwdIt& _Iter) { ::new (static_cast(_STD addressof(_Val))) _Ty(_Transform_op(*_Iter)); } template -void _Implicitly_construct_in_place_by_binary_op(_Ty& _Val, _BinaryOp& _Reduce_op, _ArgTy& _Left, _ArgTy& _Right) { +void _Implicitly_construct_in_place_by_binary_op(_Ty& _Val, _BinaryOp _Reduce_op, _ArgTy& _Left, _ArgTy& _Right) { ::new (static_cast(_STD addressof(_Val))) _Ty([&]() -> _Ty { return _Reduce_op(_Left, _Right); }()); } template void _Implicitly_construct_in_place_by_binary_op_deref_rhs( - _Ty& _Val, _BinaryOp& _Reduce_op, _LeftTy&& _Left, const _FwdIt& _Iter) { + _Ty& _Val, _BinaryOp _Reduce_op, _LeftTy&& _Left, const _FwdIt& _Iter) { ::new (static_cast(_STD addressof(_Val))) _Ty([&]() -> _Ty { return _Reduce_op(_STD forward<_LeftTy>(_Left), *_Iter); }()); } template void _Implicitly_construct_in_place_by_binary_op_transform_deref_rhs( - _Ty& _Val, _BinaryOp& _Reduce_op, _UnaryOp& _Transform_op, _LeftTy&& _Left, const _FwdIt& _Iter) { + _Ty& _Val, _BinaryOp _Reduce_op, _UnaryOp _Transform_op, _LeftTy&& _Left, const _FwdIt& _Iter) { ::new (static_cast(_STD addressof(_Val))) _Ty([&]() -> _Ty { return _Reduce_op(_STD forward<_LeftTy>(_Left), _Transform_op(*_Iter)); }()); }