From baf623fbb881ac51a66271aaaf1c06adeb4bb20c Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Wed, 8 Jul 2020 19:35:07 +0200 Subject: [PATCH 1/3] Implement ranges::transform --- stl/inc/algorithm | 113 +++++++++++++++ tests/std/include/range_algorithm_support.hpp | 5 + tests/std/test.lst | 2 + .../env.lst | 4 + .../test.cpp | 132 ++++++++++++++++++ .../env.lst | 4 + .../test.cpp | 59 ++++++++ 7 files changed, 319 insertions(+) create mode 100644 tests/std/tests/P0896R4_ranges_alg_transform_binary/env.lst create mode 100644 tests/std/tests/P0896R4_ranges_alg_transform_binary/test.cpp create mode 100644 tests/std/tests/P0896R4_ranges_alg_transform_unary/env.lst create mode 100644 tests/std/tests/P0896R4_ranges_alg_transform_unary/test.cpp diff --git a/stl/inc/algorithm b/stl/inc/algorithm index 945936ee546..3001c619e79 100644 --- a/stl/inc/algorithm +++ b/stl/inc/algorithm @@ -3266,6 +3266,119 @@ _FwdIt3 transform(_ExPo&& _Exec, const _FwdIt1 _First1, const _FwdIt1 _Last1, co _Fn _Func) noexcept; // terminates #endif // _HAS_CXX17 +#ifdef __cpp_lib_concepts +namespace ranges { + // ALIAS TEMPLATE unary_transform_result + template + using unary_transform_result = in_out_result<_In, _Out>; + + // ALIAS TEMPLATE binary_transform_result + template + using binary_transform_result = in_in_out_result<_In1, _In2, _Out>; + + // VARIABLE ranges::transform + class _Transform_fn : private _Not_quite_object { + public: + using _Not_quite_object::_Not_quite_object; + + // clang-format off + template _Se, weakly_incrementable _Out, copy_constructible _Fn, + class _Pj = identity> + requires indirectly_writable<_Out, indirect_result_t<_Fn&, projected<_It, _Pj>>> + constexpr unary_transform_result<_It, _Out> operator()( + _It _First, _Se _Last, _Out _Result, _Fn _Func, _Pj _Proj = {}) const { + _Adl_verify_range(_First, _Last); + auto _UResult = _Transform_unchecked(_Get_unwrapped(_STD move(_First)), _Get_unwrapped(_STD move(_Last)), + _STD move(_Result), _Pass_fn(_Func), _Pass_fn(_Proj)); + + _Seek_wrapped(_First, _STD move(_UResult.in)); + return {_STD move(_First), _STD move(_UResult.out)}; + } + + template + requires indirectly_writable<_Out, indirect_result_t<_Fn&, projected, _Pj>>> + constexpr unary_transform_result, _Out> operator()( + _Rng&& _Range, _Out _Result, _Fn _Func, _Pj _Proj = {}) const { + auto _First = _RANGES begin(_Range); + auto _UResult = _Transform_unchecked( + _Get_unwrapped(_STD move(_First)), _Uend(_Range), _STD move(_Result), _Pass_fn(_Func), _Pass_fn(_Proj)); + + _Seek_wrapped(_First, _STD move(_UResult.in)); + return {_STD move(_First), _STD move(_UResult.out)}; + } + + template _Se1, input_iterator _It2, sentinel_for<_It2> _Se2, + weakly_incrementable _Out, copy_constructible _Fn, class _Pj1 = identity, class _Pj2 = identity> + requires indirectly_writable<_Out, indirect_result_t<_Fn&, projected<_It1, _Pj1>, projected<_It2, _Pj2>>> + constexpr binary_transform_result<_It1, _It2, _Out> operator()(_It1 _First1, _Se1 _Last1, _It2 _First2, + _Se2 _Last2, _Out _Result, _Fn _Func, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const { + _Adl_verify_range(_First1, _Last1); + _Adl_verify_range(_First2, _Last2); + auto _UResult = _Transform_unchecked(_Get_unwrapped(_STD move(_First1)), _Get_unwrapped(_STD move(_Last1)), + _Get_unwrapped(_STD move(_First2)), _Get_unwrapped(_STD move(_Last2)), _STD move(_Result), + _Pass_fn(_Func), _Pass_fn(_Proj1), _Pass_fn(_Proj2)); + + _Seek_wrapped(_First1, _STD move(_UResult.in1)); + _Seek_wrapped(_First2, _STD move(_UResult.in2)); + return {_STD move(_First1), _STD move(_First2), _STD move(_UResult.out)}; + } + + template + requires indirectly_writable<_Out, indirect_result_t<_Fn&, projected, _Pj1>, + projected, _Pj2>>> + constexpr binary_transform_result, borrowed_iterator_t<_Rng2>, _Out> operator()( + _Rng1&& _Range1, _Rng2&& _Range2, _Out _Result, _Fn _Func, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const { + auto _First1 = _RANGES begin(_Range1); + auto _First2 = _RANGES begin(_Range2); + auto _UResult = _Transform_unchecked(_Get_unwrapped(_STD move(_First1)), _Uend(_Range1), + _Get_unwrapped(_STD move(_First2)), _Uend(_Range2), _STD move(_Result), _Pass_fn(_Func), + _Pass_fn(_Proj1), _Pass_fn(_Proj2)); + + _Seek_wrapped(_First1, _STD move(_UResult.in1)); + _Seek_wrapped(_First2, _STD move(_UResult.in2)); + return {_STD move(_First1), _STD move(_First2), _STD move(_UResult.out)}; + } + // clang-format on + + private: + template + _NODISCARD static constexpr unary_transform_result<_It, _Out> _Transform_unchecked( + _It _First, const _Se _Last, _Out _Result, _Fn _Func, _Pj _Proj) { + // transform projected [_First, _Last) with _Func + _STL_INTERNAL_STATIC_ASSERT(input_iterator<_It>); + _STL_INTERNAL_STATIC_ASSERT(weakly_incrementable<_Out>); + _STL_INTERNAL_STATIC_ASSERT(indirectly_writable<_Out, indirect_result_t<_Fn&, projected<_It, _Pj>>>); + + for (; _First != _Last; ++_First, (void) ++_Result) { + *_Result = _STD invoke(_Func, _STD invoke(_Proj, *_First)); + } + + return {_STD move(_First), _STD move(_Result)}; + } + + template + _NODISCARD static constexpr binary_transform_result<_It1, _It2, _Out> _Transform_unchecked(_It1 _First1, + const _Se1 _Last1, _It2 _First2, const _Se2 _Last2, _Out _Result, _Fn _Func, _Pj1 _Proj1, _Pj2 _Proj2) { + // transform projected [_First1, _Last1) and projected [_First2, Last2) with _Func + _STL_INTERNAL_STATIC_ASSERT(input_iterator<_It1>); + _STL_INTERNAL_STATIC_ASSERT(input_iterator<_It2>); + _STL_INTERNAL_STATIC_ASSERT(weakly_incrementable<_Out>); + _STL_INTERNAL_STATIC_ASSERT( + indirectly_writable<_Out, indirect_result_t<_Fn&, projected<_It1, _Pj1>, projected<_It2, _Pj2>>>); + + for (; _First1 != _Last1 && _First2 != _Last2; ++_First1, (void) ++_First2, ++_Result) { + *_Result = _STD invoke(_Func, _STD invoke(_Proj1, *_First1), _STD invoke(_Proj2, *_First2)); + } + + return {_STD move(_First1), _STD move(_First2), _STD move(_Result)}; + } + }; + + inline constexpr _Transform_fn transform{_Not_quite_object::_Construct_tag{}}; +} // namespace ranges +#endif // __cpp_lib_concepts + // FUNCTION TEMPLATE replace template _CONSTEXPR20 void replace(const _FwdIt _First, const _FwdIt _Last, const _Ty& _Oldval, const _Ty& _Newval) { diff --git a/tests/std/include/range_algorithm_support.hpp b/tests/std/include/range_algorithm_support.hpp index d5fa87ddd08..4795d82cb3e 100644 --- a/tests/std/include/range_algorithm_support.hpp +++ b/tests/std/include/range_algorithm_support.hpp @@ -1018,6 +1018,11 @@ constexpr void test_read_write() { with_input_iterators, Element1>::call(); } +template +constexpr void test_in_in_write() { + with_input_ranges, Element2>, Element1>::call(); +} + template struct get_nth_fn { template diff --git a/tests/std/test.lst b/tests/std/test.lst index 4c9d6bf510c..ff3cf7ba453 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -273,6 +273,8 @@ tests\P0896R4_ranges_alg_replace_if tests\P0896R4_ranges_alg_search tests\P0896R4_ranges_alg_search_n tests\P0896R4_ranges_alg_swap_ranges +tests\P0896R4_ranges_alg_transform_binary +tests\P0896R4_ranges_alg_transform_unary tests\P0896R4_ranges_iterator_machinery tests\P0896R4_ranges_range_machinery tests\P0896R4_ranges_subrange diff --git a/tests/std/tests/P0896R4_ranges_alg_transform_binary/env.lst b/tests/std/tests/P0896R4_ranges_alg_transform_binary/env.lst new file mode 100644 index 00000000000..f3ccc8613c6 --- /dev/null +++ b/tests/std/tests/P0896R4_ranges_alg_transform_binary/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\concepts_matrix.lst diff --git a/tests/std/tests/P0896R4_ranges_alg_transform_binary/test.cpp b/tests/std/tests/P0896R4_ranges_alg_transform_binary/test.cpp new file mode 100644 index 00000000000..f9990b8c130 --- /dev/null +++ b/tests/std/tests/P0896R4_ranges_alg_transform_binary/test.cpp @@ -0,0 +1,132 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include +#include +#include + +#include + +using namespace std; +using P = pair; + +// Validate that binary_transform_result aliases in_in_out_result +STATIC_ASSERT(same_as, ranges::in_in_out_result>); + +// Validate dangling story +STATIC_ASSERT( + same_as{}, borrowed{}, static_cast(nullptr), plus{})), + ranges::binary_transform_result>); +STATIC_ASSERT( + same_as{}, borrowed{}, static_cast(nullptr), plus{})), + ranges::binary_transform_result>); +STATIC_ASSERT( + same_as{}, borrowed{}, static_cast(nullptr), plus{})), + ranges::binary_transform_result>); +STATIC_ASSERT( + same_as{}, borrowed{}, static_cast(nullptr), plus{})), + ranges::binary_transform_result>); + +struct instantiator { + static constexpr P input1[3] = {{1, 99}, {4, 98}, {5, 97}}; + static constexpr P input2[3] = {{99, 6}, {98, 7}, {97, 8}}; + static constexpr int expected[3] = {7, 11, 13}; + + static constexpr P shortInput1[2] = {{1, 99}, {4, 98}}; + static constexpr P shortInput2[2] = {{99, 6}, {98, 7}}; + static constexpr int shortExpected[2] = {7, 11}; + + template + static constexpr void call() { + using ranges::transform, ranges::binary_transform_result, ranges::iterator_t; + { // Validate iterator + sentinel overload first range shorter + int output[2] = {-1, -1}; + Read1 wrapped_in1{shortInput1}; + Read2 wrapped_in2{input2}; + + auto result = transform(wrapped_in1.begin(), wrapped_in1.end(), wrapped_in2.begin(), wrapped_in2.end(), + Write{output}, plus{}, get_first, get_second); + STATIC_ASSERT( + same_as, iterator_t, Write>>); + assert(result.in1 == wrapped_in1.end()); + assert(next(result.in2) == wrapped_in2.end()); + assert(result.out.peek() == output + 2); + assert(ranges::equal(output, shortExpected)); + } + { // Validate iterator + sentinel overload second range shorter + int output[2] = {-1, -1}; + Read1 wrapped_in1{input1}; + Read2 wrapped_in2{shortInput2}; + + auto result = transform(wrapped_in1.begin(), wrapped_in1.end(), wrapped_in2.begin(), wrapped_in2.end(), + Write{output}, plus{}, get_first, get_second); + STATIC_ASSERT( + same_as, iterator_t, Write>>); + assert(next(result.in1) == wrapped_in1.end()); + assert(result.in2 == wrapped_in2.end()); + assert(result.out.peek() == output + 2); + assert(ranges::equal(output, shortExpected)); + } + { // Validate range overload first range shorter + int output[2] = {-1, -1}; + Read1 wrapped_in1{shortInput1}; + Read2 wrapped_in2{input2}; + + auto result = transform(wrapped_in1, wrapped_in2, Write{output}, plus{}, get_first, get_second); + STATIC_ASSERT( + same_as, iterator_t, Write>>); + assert(result.in1 == wrapped_in1.end()); + assert(next(result.in2) == wrapped_in2.end()); + assert(result.out.peek() == output + 2); + assert(ranges::equal(output, shortExpected)); + } + { // Validate range overload second range shorter + int output[2] = {-1, -1}; + Read1 wrapped_in1{input1}; + Read2 wrapped_in2{shortInput2}; + + auto result = transform(wrapped_in1, wrapped_in2, Write{output}, plus{}, get_first, get_second); + STATIC_ASSERT( + same_as, iterator_t, Write>>); + assert(next(result.in1) == wrapped_in1.end()); + assert(result.in2 == wrapped_in2.end()); + assert(result.out.peek() == output + 2); + assert(ranges::equal(output, shortExpected)); + } + } +}; + +using Elem1 = const P; +using Elem2 = const P; +using Elem3 = int; + +#ifdef TEST_EVERYTHING +int main() { + // No constexpr test here; the test_in_in_write call exceeds the maximum number of steps in a constexpr computation. + test_in_in_write(); +} +#else // ^^^ test all range combinations // test only interesting range combos vvv +template +using in_test_range = test::range; +template +using out_test_iterator = + test::iterator; + +constexpr bool run_tests() { + // All (except contiguous) proxy reference types, since the algorithm doesn't really care. + using test::Common, test::Sized; + + // both input, non-common, and sized or unsized + instantiator::call, in_test_range, out_test_iterator>(); + instantiator::call, in_test_range, out_test_iterator>(); + return true; +} + +int main() { + STATIC_ASSERT(run_tests()); + run_tests(); +} +#endif // TEST_EVERYTHING diff --git a/tests/std/tests/P0896R4_ranges_alg_transform_unary/env.lst b/tests/std/tests/P0896R4_ranges_alg_transform_unary/env.lst new file mode 100644 index 00000000000..f3ccc8613c6 --- /dev/null +++ b/tests/std/tests/P0896R4_ranges_alg_transform_unary/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\concepts_matrix.lst diff --git a/tests/std/tests/P0896R4_ranges_alg_transform_unary/test.cpp b/tests/std/tests/P0896R4_ranges_alg_transform_unary/test.cpp new file mode 100644 index 00000000000..a859c2283bd --- /dev/null +++ b/tests/std/tests/P0896R4_ranges_alg_transform_unary/test.cpp @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include +#include +#include + +#include + +using namespace std; +using P = pair; + +// Validate that unary_transform_result aliases in_out_result +STATIC_ASSERT(same_as, ranges::in_out_result>); + +constexpr auto minus_one = [](int x) -> int { return x - 1; }; + +// Validate dangling story +STATIC_ASSERT(same_as{}, static_cast(nullptr), minus_one)), + ranges::unary_transform_result>); +STATIC_ASSERT(same_as{}, static_cast(nullptr), minus_one)), + ranges::unary_transform_result>); + +struct instantiator { + static constexpr P input[3] = {{1, 99}, {4, 98}, {5, 97}}; + static constexpr int expected[3] = {0, 3, 4}; + + template + static constexpr void call() { + using ranges::transform, ranges::unary_transform_result, ranges::iterator_t; + { // Validate iterator + sentinel overload + int output[3] = {-1, -1, -1}; + Read wrapped_in{input}; + + auto result = transform(wrapped_in.begin(), wrapped_in.end(), Write{output}, minus_one, get_first); + STATIC_ASSERT(same_as, Write>>); + assert(result.in == wrapped_in.end()); + assert(result.out.peek() == output + 3); + assert(ranges::equal(output, expected)); + } + { // Validate range overload + int output[3] = {-1, -1, -1}; + Read wrapped_in{input}; + + auto result = transform(wrapped_in, Write{output}, minus_one, get_first); + STATIC_ASSERT(same_as, Write>>); + assert(result.in == wrapped_in.end()); + assert(result.out.peek() == output + 3); + assert(ranges::equal(output, expected)); + } + } +}; + +int main() { + STATIC_ASSERT((test_in_write(), true)); + test_in_write(); +} From aed017eece60d58aa4a6739d4ab5531a2995d6a0 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Mon, 13 Jul 2020 12:47:31 +0200 Subject: [PATCH 2/3] Review comments --- stl/inc/algorithm | 21 ++++++++-------- .../tests/P0896R4_ranges_alg_copy/test.cpp | 5 ++-- .../tests/P0896R4_ranges_alg_copy_if/test.cpp | 6 ++--- .../tests/P0896R4_ranges_alg_move/test.cpp | 5 ++-- .../P0896R4_ranges_alg_replace_copy/test.cpp | 4 ++-- .../test.cpp | 4 ++-- .../test.cpp | 24 ++++++++----------- .../test.cpp | 6 ++--- 8 files changed, 35 insertions(+), 40 deletions(-) diff --git a/stl/inc/algorithm b/stl/inc/algorithm index 3001c619e79..b72e8a35a55 100644 --- a/stl/inc/algorithm +++ b/stl/inc/algorithm @@ -3288,8 +3288,8 @@ namespace ranges { constexpr unary_transform_result<_It, _Out> operator()( _It _First, _Se _Last, _Out _Result, _Fn _Func, _Pj _Proj = {}) const { _Adl_verify_range(_First, _Last); - auto _UResult = _Transform_unchecked(_Get_unwrapped(_STD move(_First)), _Get_unwrapped(_STD move(_Last)), - _STD move(_Result), _Pass_fn(_Func), _Pass_fn(_Proj)); + auto _UResult = _Transform_unary_unchecked(_Get_unwrapped(_STD move(_First)), + _Get_unwrapped(_STD move(_Last)), _STD move(_Result), _Pass_fn(_Func), _Pass_fn(_Proj)); _Seek_wrapped(_First, _STD move(_UResult.in)); return {_STD move(_First), _STD move(_UResult.out)}; @@ -3300,7 +3300,7 @@ namespace ranges { constexpr unary_transform_result, _Out> operator()( _Rng&& _Range, _Out _Result, _Fn _Func, _Pj _Proj = {}) const { auto _First = _RANGES begin(_Range); - auto _UResult = _Transform_unchecked( + auto _UResult = _Transform_unary_unchecked( _Get_unwrapped(_STD move(_First)), _Uend(_Range), _STD move(_Result), _Pass_fn(_Func), _Pass_fn(_Proj)); _Seek_wrapped(_First, _STD move(_UResult.in)); @@ -3314,9 +3314,10 @@ namespace ranges { _Se2 _Last2, _Out _Result, _Fn _Func, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const { _Adl_verify_range(_First1, _Last1); _Adl_verify_range(_First2, _Last2); - auto _UResult = _Transform_unchecked(_Get_unwrapped(_STD move(_First1)), _Get_unwrapped(_STD move(_Last1)), - _Get_unwrapped(_STD move(_First2)), _Get_unwrapped(_STD move(_Last2)), _STD move(_Result), - _Pass_fn(_Func), _Pass_fn(_Proj1), _Pass_fn(_Proj2)); + auto _UResult = + _Transform_binary_unchecked(_Get_unwrapped(_STD move(_First1)), _Get_unwrapped(_STD move(_Last1)), + _Get_unwrapped(_STD move(_First2)), _Get_unwrapped(_STD move(_Last2)), _STD move(_Result), + _Pass_fn(_Func), _Pass_fn(_Proj1), _Pass_fn(_Proj2)); _Seek_wrapped(_First1, _STD move(_UResult.in1)); _Seek_wrapped(_First2, _STD move(_UResult.in2)); @@ -3331,7 +3332,7 @@ namespace ranges { _Rng1&& _Range1, _Rng2&& _Range2, _Out _Result, _Fn _Func, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const { auto _First1 = _RANGES begin(_Range1); auto _First2 = _RANGES begin(_Range2); - auto _UResult = _Transform_unchecked(_Get_unwrapped(_STD move(_First1)), _Uend(_Range1), + auto _UResult = _Transform_binary_unchecked(_Get_unwrapped(_STD move(_First1)), _Uend(_Range1), _Get_unwrapped(_STD move(_First2)), _Uend(_Range2), _STD move(_Result), _Pass_fn(_Func), _Pass_fn(_Proj1), _Pass_fn(_Proj2)); @@ -3343,7 +3344,7 @@ namespace ranges { private: template - _NODISCARD static constexpr unary_transform_result<_It, _Out> _Transform_unchecked( + _NODISCARD static constexpr unary_transform_result<_It, _Out> _Transform_unary_unchecked( _It _First, const _Se _Last, _Out _Result, _Fn _Func, _Pj _Proj) { // transform projected [_First, _Last) with _Func _STL_INTERNAL_STATIC_ASSERT(input_iterator<_It>); @@ -3358,9 +3359,9 @@ namespace ranges { } template - _NODISCARD static constexpr binary_transform_result<_It1, _It2, _Out> _Transform_unchecked(_It1 _First1, + _NODISCARD static constexpr binary_transform_result<_It1, _It2, _Out> _Transform_binary_unchecked(_It1 _First1, const _Se1 _Last1, _It2 _First2, const _Se2 _Last2, _Out _Result, _Fn _Func, _Pj1 _Proj1, _Pj2 _Proj2) { - // transform projected [_First1, _Last1) and projected [_First2, Last2) with _Func + // transform projected [_First1, _Last1) and projected [_First2, _Last2) with _Func _STL_INTERNAL_STATIC_ASSERT(input_iterator<_It1>); _STL_INTERNAL_STATIC_ASSERT(input_iterator<_It2>); _STL_INTERNAL_STATIC_ASSERT(weakly_incrementable<_Out>); diff --git a/tests/std/tests/P0896R4_ranges_alg_copy/test.cpp b/tests/std/tests/P0896R4_ranges_alg_copy/test.cpp index 6fd9130e399..da5250e5256 100644 --- a/tests/std/tests/P0896R4_ranges_alg_copy/test.cpp +++ b/tests/std/tests/P0896R4_ranges_alg_copy/test.cpp @@ -15,10 +15,9 @@ using namespace std; STATIC_ASSERT(same_as, ranges::in_out_result>); // Validate dangling story -STATIC_ASSERT(same_as{}, static_cast(nullptr))), - ranges::copy_result>); STATIC_ASSERT( - same_as{}, static_cast(nullptr))), ranges::copy_result>); + same_as{}, nullptr_to)), ranges::copy_result>); +STATIC_ASSERT(same_as{}, nullptr_to)), ranges::copy_result>); struct instantiator { static constexpr int input[3] = {13, 42, 1729}; diff --git a/tests/std/tests/P0896R4_ranges_alg_copy_if/test.cpp b/tests/std/tests/P0896R4_ranges_alg_copy_if/test.cpp index aa257403649..95795d1ab9a 100644 --- a/tests/std/tests/P0896R4_ranges_alg_copy_if/test.cpp +++ b/tests/std/tests/P0896R4_ranges_alg_copy_if/test.cpp @@ -65,10 +65,10 @@ constexpr auto is_odd = [](int const x) { return x % 2 != 0; }; STATIC_ASSERT(same_as, ranges::in_out_result>); // Validate dangling story -STATIC_ASSERT(same_as{}, static_cast(nullptr), is_odd)), +STATIC_ASSERT(same_as{}, nullptr_to, is_odd)), ranges::copy_if_result>); -STATIC_ASSERT(same_as{}, static_cast(nullptr), is_odd)), - ranges::copy_if_result>); +STATIC_ASSERT( + same_as{}, nullptr_to, is_odd)), ranges::copy_if_result>); struct instantiator { static constexpr P input[3] = {{1, 99}, {4, 98}, {5, 97}}; diff --git a/tests/std/tests/P0896R4_ranges_alg_move/test.cpp b/tests/std/tests/P0896R4_ranges_alg_move/test.cpp index c97f016e4bc..34c485670ef 100644 --- a/tests/std/tests/P0896R4_ranges_alg_move/test.cpp +++ b/tests/std/tests/P0896R4_ranges_alg_move/test.cpp @@ -27,10 +27,9 @@ struct int_wrapper { STATIC_ASSERT(same_as, ranges::in_out_result>); // Validate dangling story -STATIC_ASSERT(same_as{}, static_cast(nullptr))), - ranges::move_result>); STATIC_ASSERT( - same_as{}, static_cast(nullptr))), ranges::move_result>); + same_as{}, nullptr_to)), ranges::move_result>); +STATIC_ASSERT(same_as{}, nullptr_to)), ranges::move_result>); struct instantiator { static constexpr int_wrapper expected_output[3] = {13, 55, 12345}; diff --git a/tests/std/tests/P0896R4_ranges_alg_replace_copy/test.cpp b/tests/std/tests/P0896R4_ranges_alg_replace_copy/test.cpp index 965c5ecd5ac..b020fbcd8c2 100644 --- a/tests/std/tests/P0896R4_ranges_alg_replace_copy/test.cpp +++ b/tests/std/tests/P0896R4_ranges_alg_replace_copy/test.cpp @@ -15,9 +15,9 @@ using P = pair; STATIC_ASSERT(same_as, ranges::in_out_result>); // Validate dangling story -STATIC_ASSERT(same_as{}, static_cast(nullptr), 42, 5)), +STATIC_ASSERT(same_as{}, nullptr_to, 42, 5)), ranges::replace_copy_result>); -STATIC_ASSERT(same_as{}, static_cast(nullptr), 42, 5)), +STATIC_ASSERT(same_as{}, nullptr_to, 42, 5)), ranges::replace_copy_result>); struct instantiator { diff --git a/tests/std/tests/P0896R4_ranges_alg_replace_copy_if/test.cpp b/tests/std/tests/P0896R4_ranges_alg_replace_copy_if/test.cpp index 0048304155c..57afc1c7226 100644 --- a/tests/std/tests/P0896R4_ranges_alg_replace_copy_if/test.cpp +++ b/tests/std/tests/P0896R4_ranges_alg_replace_copy_if/test.cpp @@ -17,9 +17,9 @@ constexpr auto matches = [](int const val) { return val == 47; }; STATIC_ASSERT(same_as, ranges::in_out_result>); // Validate dangling story -STATIC_ASSERT(same_as{}, static_cast(nullptr), matches, 5)), +STATIC_ASSERT(same_as{}, nullptr_to, matches, 5)), ranges::replace_copy_if_result>); -STATIC_ASSERT(same_as{}, static_cast(nullptr), matches, 5)), +STATIC_ASSERT(same_as{}, nullptr_to, matches, 5)), ranges::replace_copy_if_result>); struct instantiator { diff --git a/tests/std/tests/P0896R4_ranges_alg_transform_binary/test.cpp b/tests/std/tests/P0896R4_ranges_alg_transform_binary/test.cpp index f9990b8c130..7658141d1d6 100644 --- a/tests/std/tests/P0896R4_ranges_alg_transform_binary/test.cpp +++ b/tests/std/tests/P0896R4_ranges_alg_transform_binary/test.cpp @@ -16,18 +16,14 @@ using P = pair; STATIC_ASSERT(same_as, ranges::in_in_out_result>); // Validate dangling story -STATIC_ASSERT( - same_as{}, borrowed{}, static_cast(nullptr), plus{})), - ranges::binary_transform_result>); -STATIC_ASSERT( - same_as{}, borrowed{}, static_cast(nullptr), plus{})), - ranges::binary_transform_result>); -STATIC_ASSERT( - same_as{}, borrowed{}, static_cast(nullptr), plus{})), - ranges::binary_transform_result>); -STATIC_ASSERT( - same_as{}, borrowed{}, static_cast(nullptr), plus{})), - ranges::binary_transform_result>); +STATIC_ASSERT(same_as{}, borrowed{}, nullptr_to, plus{})), + ranges::binary_transform_result>); +STATIC_ASSERT(same_as{}, borrowed{}, nullptr_to, plus{})), + ranges::binary_transform_result>); +STATIC_ASSERT(same_as{}, borrowed{}, nullptr_to, plus{})), + ranges::binary_transform_result>); +STATIC_ASSERT(same_as{}, borrowed{}, nullptr_to, plus{})), + ranges::binary_transform_result>); struct instantiator { static constexpr P input1[3] = {{1, 99}, {4, 98}, {5, 97}}; @@ -41,7 +37,7 @@ struct instantiator { template static constexpr void call() { using ranges::transform, ranges::binary_transform_result, ranges::iterator_t; - { // Validate iterator + sentinel overload first range shorter + { // Validate iterator + sentinel overload, first range shorter int output[2] = {-1, -1}; Read1 wrapped_in1{shortInput1}; Read2 wrapped_in2{input2}; @@ -55,7 +51,7 @@ struct instantiator { assert(result.out.peek() == output + 2); assert(ranges::equal(output, shortExpected)); } - { // Validate iterator + sentinel overload second range shorter + { // Validate iterator + sentinel overload, second range shorter int output[2] = {-1, -1}; Read1 wrapped_in1{input1}; Read2 wrapped_in2{shortInput2}; diff --git a/tests/std/tests/P0896R4_ranges_alg_transform_unary/test.cpp b/tests/std/tests/P0896R4_ranges_alg_transform_unary/test.cpp index a859c2283bd..3d65ceb8996 100644 --- a/tests/std/tests/P0896R4_ranges_alg_transform_unary/test.cpp +++ b/tests/std/tests/P0896R4_ranges_alg_transform_unary/test.cpp @@ -15,12 +15,12 @@ using P = pair; // Validate that unary_transform_result aliases in_out_result STATIC_ASSERT(same_as, ranges::in_out_result>); -constexpr auto minus_one = [](int x) -> int { return x - 1; }; +constexpr auto minus_one = [](const int x) { return x - 1; }; // Validate dangling story -STATIC_ASSERT(same_as{}, static_cast(nullptr), minus_one)), +STATIC_ASSERT(same_as{}, nullptr_to, minus_one)), ranges::unary_transform_result>); -STATIC_ASSERT(same_as{}, static_cast(nullptr), minus_one)), +STATIC_ASSERT(same_as{}, nullptr_to, minus_one)), ranges::unary_transform_result>); struct instantiator { From 8ec89f60b54b03db481eac9b3097a54942a27c4f Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 13 Jul 2020 16:23:27 -0700 Subject: [PATCH 3/3] Apply suggestions from code review --- tests/std/tests/P0896R4_ranges_alg_transform_binary/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/std/tests/P0896R4_ranges_alg_transform_binary/test.cpp b/tests/std/tests/P0896R4_ranges_alg_transform_binary/test.cpp index 7658141d1d6..11c31b21f0c 100644 --- a/tests/std/tests/P0896R4_ranges_alg_transform_binary/test.cpp +++ b/tests/std/tests/P0896R4_ranges_alg_transform_binary/test.cpp @@ -65,7 +65,7 @@ struct instantiator { assert(result.out.peek() == output + 2); assert(ranges::equal(output, shortExpected)); } - { // Validate range overload first range shorter + { // Validate range overload, first range shorter int output[2] = {-1, -1}; Read1 wrapped_in1{shortInput1}; Read2 wrapped_in2{input2}; @@ -78,7 +78,7 @@ struct instantiator { assert(result.out.peek() == output + 2); assert(ranges::equal(output, shortExpected)); } - { // Validate range overload second range shorter + { // Validate range overload, second range shorter int output[2] = {-1, -1}; Read1 wrapped_in1{input1}; Read2 wrapped_in2{shortInput2};