diff --git a/stl/inc/execution b/stl/inc/execution index 11067c2606..7544ea646f 100644 --- a/stl/inc/execution +++ b/stl/inc/execution @@ -4235,7 +4235,8 @@ struct _Static_partitioned_transform_reduce2 { // transformed reduction task sch auto& _Transform_op = _This->_Transform_op; auto _Chunk = _This->_Basis._Get_chunk(_Key); auto _Next = _Chunk._First; - _Ty _Val{_Reduce_op(_Transform_op(*_Chunk._First), _Transform_op(*++_Next))}; + + _Ty _Val = _Reduce_op(_Transform_op(*_Chunk._First), _Transform_op(*++_Next)); while (++_Next != _Chunk._Last) { _Val = _Reduce_op(_STD move(_Val), _Transform_op(*_Next)); } diff --git a/tests/std/tests/P0024R2_parallel_algorithms_transform_reduce/test.cpp b/tests/std/tests/P0024R2_parallel_algorithms_transform_reduce/test.cpp index 9141838019..c1a8a7dccf 100644 --- a/tests/std/tests/P0024R2_parallel_algorithms_transform_reduce/test.cpp +++ b/tests/std/tests/P0024R2_parallel_algorithms_transform_reduce/test.cpp @@ -1,7 +1,9 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#pragma warning(disable : 4242 4244 4365) // test_case_incorrect_special_case_reasoning tests narrowing on purpose +// test_case_incorrect_special_case_reasoning and test_case_narrowing_conversion test narrowing on purpose +#pragma warning(disable : 4242 4244 4267 4365) + #include #include #include @@ -144,6 +146,25 @@ void test_case_incorrect_special_case_reasoning() { assert(transform_reduce(begin(c), end(c), d, 0, multiplies<>{}, plus{}) == 0); } +void test_case_narrowing_conversion() { + size_t a[] = {1, 2, 3}; + auto return_itself = [](size_t x) { return x; }; + // Initializing a smaller type (int here) with a larger type (size_t here). + // According to N4971 [transform.reduce]/7, + // this narrowing conversion should compile without error. + assert(transform_reduce(begin(a), end(a), 0, plus{}, return_itself) == 6); + assert(transform_reduce(seq, begin(a), end(a), 0, plus{}, return_itself) == 6); + assert(transform_reduce(par, begin(a), end(a), 0, plus{}, return_itself) == 6); + + size_t b[] = {1, 2, 3}; + // Initializing a smaller type (int here) with a larger type (size_t here). + // According to N4971 [transform.reduce]/3, + // this narrowing conversion should compile without error. + assert(transform_reduce(begin(a), end(a), b, 0, plus{}, plus{}) == 12); + assert(transform_reduce(seq, begin(a), end(a), b, 0, plus{}, plus{}) == 12); + assert(transform_reduce(par, begin(a), end(a), b, 0, plus{}, plus{}) == 12); +} + int main() { mt19937 gen(1729); parallel_test_case(test_case_transform_reduce_binary, gen); @@ -153,4 +174,5 @@ int main() { parallel_test_case([](const size_t testSize) { test_case_move_only(seq, testSize); }); parallel_test_case([](const size_t testSize) { test_case_move_only(par, testSize); }); test_case_incorrect_special_case_reasoning(); + test_case_narrowing_conversion(); }