From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2136) id 0B05339960E5; Wed, 17 Jun 2020 18:59:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0B05339960E5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1592420343; bh=sZ1YPJfbYKd0eiMyiHH2sIrwgqZzciemod8qBG6eqYI=; h=From:To:Subject:Date:From; b=C/tO184m9JthSnkvum+ol6i1GdQkwPN4nVnmGl1HHzrr8VWfIGjCMRhQeWJRiwfBc 4Smwb3lA8SdLLgs/VtJmKZmRd5xk2iirSpl5WNSFfDarjzIevazQrDGq5O4IDt7NGD pzA9w1BLYkTXBan6q/76MxoybNK3qkWkctiZ7aQE= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Aldy Hernandez To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc/devel/ranger] libstdc++: P2106R0 Alternative wording for GB315 and GB316 X-Act-Checkin: gcc X-Git-Author: Patrick Palka X-Git-Refname: refs/heads/devel/ranger X-Git-Oldrev: f3169941996c76ecbfae9c37709d2b57652be555 X-Git-Newrev: aa667c3f36d6a78e1b38e7a9a26899fd385bfcb7 Message-Id: <20200617185903.0B05339960E5@sourceware.org> Date: Wed, 17 Jun 2020 18:59:03 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Jun 2020 18:59:03 -0000 https://gcc.gnu.org/g:aa667c3f36d6a78e1b38e7a9a26899fd385bfcb7 commit aa667c3f36d6a78e1b38e7a9a26899fd385bfcb7 Author: Patrick Palka Date: Mon Feb 17 16:13:28 2020 -0500 libstdc++: P2106R0 Alternative wording for GB315 and GB316 libstdc++-v3/ChangeLog: P2106R0 Alternative wording for GB315 and GB316 * include/bits/ranges_algo.h (in_fun_result): New. (for_each_result, for_each_n_result): Change into an alias of in_fun_result. (in_in_result): New. (mismatch_result): Change into an alias of in_in_result. (copy_if_result): Change into an alias of in_out_result. (swap_ranges_result): Change into an alias of in_in_result. (unary_transform_result): Change into an alias of in_out_result. (in_in_out_result): New. (binary_transform_result): Change into an alias of in_in_out_result. (replace_copy_result, replace_copy_if_result, remove_copy_if_result, remove_copy_result, unique_copy_result, reverse_copy_result, rotate_copy_result, partial_sort_copy_result): Change into an alias of in_out_result. (in_out_out_result): New. (partition_copy_result, merge_result): Change into an alias of in_out_out_result. (set_union_result, set_intersection_result): Change into an alias of in_in_out_result. (set_difference_result): Change into an alias of in_out_result. (set_symmetric_difference): Change into an alias of in_in_out_result. (min_max_result): New. (minmax_result, minmax_element_result): Change into an alias of min_max_result. (in_found_result): New. (next_permutation_result, prev_permutation_result): Change into an alias of in_found_result. (__next_permutation_fn::operator(), __prev_permutation_fn::operator()): Adjust following changes to next_permutation_result and prev_permutation_result. * include/bits/ranges_algobase.h (in_out_result): New. (copy_result, move_result, move_backward_result, copy_backward_result, copy_n_result): Change into an alias of in_out_result. * include/bits/ranges_uninitialized.h (uninitialized_copy_result, uninitialized_copy_n_result, uninitialized_move_result, uninitialized_move_n_result): Likewise. * testsuite/25_algorithms/next_permutation/constrained.cc: Adjust uses of structured bindings. * testsuite/25_algorithms/prev_permutation/constrained.cc: Likewise. Diff: --- libstdc++-v3/ChangeLog | 41 ++++++ libstdc++-v3/include/bits/ranges_algo.h | 137 +++++++++++++-------- libstdc++-v3/include/bits/ranges_algobase.h | 19 +-- libstdc++-v3/include/bits/ranges_uninitialized.h | 8 +- .../25_algorithms/next_permutation/constrained.cc | 4 +- .../25_algorithms/prev_permutation/constrained.cc | 4 +- 6 files changed, 149 insertions(+), 64 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c230b2bae69..ea53bb7269f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,46 @@ 2020-02-17 Patrick Palka + P2106R0 Alternative wording for GB315 and GB316 + * include/bits/ranges_algo.h (in_fun_result): New. + (for_each_result, for_each_n_result): Change into an alias of + in_fun_result. + (in_in_result): New. + (mismatch_result): Change into an alias of in_in_result. + (copy_if_result): Change into an alias of in_out_result. + (swap_ranges_result): Change into an alias of in_in_result. + (unary_transform_result): Change into an alias of in_out_result. + (in_in_out_result): New. + (binary_transform_result): Change into an alias of in_in_out_result. + (replace_copy_result, replace_copy_if_result, remove_copy_if_result, + remove_copy_result, unique_copy_result, reverse_copy_result, + rotate_copy_result, partial_sort_copy_result): Change into an alias of + in_out_result. + (in_out_out_result): New. + (partition_copy_result, merge_result): Change into an alias of + in_out_out_result. + (set_union_result, set_intersection_result): Change into an alias of + in_in_out_result. + (set_difference_result): Change into an alias of in_out_result. + (set_symmetric_difference): Change into an alias of in_in_out_result. + (min_max_result): New. + (minmax_result, minmax_element_result): Change into an alias of + min_max_result. + (in_found_result): New. + (next_permutation_result, prev_permutation_result): Change into an alias + of in_found_result. + (__next_permutation_fn::operator(), __prev_permutation_fn::operator()): + Adjust following changes to next_permutation_result and + prev_permutation_result. + * include/bits/ranges_algobase.h (in_out_result): New. + (copy_result, move_result, move_backward_result, copy_backward_result, + copy_n_result): Change into an alias of in_out_result. + * include/bits/ranges_uninitialized.h (uninitialized_copy_result, + uninitialized_copy_n_result, uninitialized_move_result, + uninitialized_move_n_result): Likewise. + * testsuite/25_algorithms/next_permutation/constrained.cc: Adjust uses of + structured bindings. + * testsuite/25_algorithms/prev_permutation/constrained.cc: Likewise. + P1243R4 Rangify new algorithms * include/bits/ranges_algo.h (for_each_n_result, __for_each_n_fn, for_each_n, __sample_fn, sample, __clamp_fn, clamp): New. diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index c50b369c6c0..31b1bf0d448 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -152,7 +152,7 @@ namespace ranges inline constexpr __none_of_fn none_of{}; template - struct for_each_result + struct in_fun_result { [[no_unique_address]] _Iter in; [[no_unique_address]] _Fp fun; @@ -160,15 +160,20 @@ namespace ranges template requires convertible_to && convertible_to - operator for_each_result<_Iter2, _F2p>() const & + constexpr + operator in_fun_result<_Iter2, _F2p>() const & { return {in, fun}; } template requires convertible_to<_Iter, _Iter2> && convertible_to<_Fp, _F2p> - operator for_each_result<_Iter2, _F2p>() && + constexpr + operator in_fun_result<_Iter2, _F2p>() && { return {std::move(in), std::move(fun)}; } }; + template + using for_each_result = in_fun_result<_Iter, _Fp>; + struct __for_each_fn { template _Sent, @@ -196,7 +201,7 @@ namespace ranges inline constexpr __for_each_fn for_each{}; template - using for_each_n_result = for_each_result<_Iter, _Fp>; + using for_each_n_result = in_fun_result<_Iter, _Fp>; struct __for_each_n_fn { @@ -416,7 +421,7 @@ namespace ranges inline constexpr __count_if_fn count_if{}; template - struct mismatch_result + struct in_in_result { [[no_unique_address]] _Iter1 in1; [[no_unique_address]] _Iter2 in2; @@ -424,16 +429,21 @@ namespace ranges template requires convertible_to && convertible_to - operator mismatch_result<_IIter1, _IIter2>() const & + constexpr + operator in_in_result<_IIter1, _IIter2>() const & { return {in1, in2}; } template requires convertible_to<_Iter1, _IIter1> && convertible_to<_Iter2, _IIter2> - operator mismatch_result<_IIter1, _IIter2>() && + constexpr + operator in_in_result<_IIter1, _IIter2>() && { return {std::move(in1), std::move(in2)}; } }; + template + using mismatch_result = in_in_result<_Iter1, _Iter2>; + struct __mismatch_fn { template _Sent1, @@ -830,7 +840,7 @@ namespace ranges inline constexpr __is_permutation_fn is_permutation{}; template - using copy_if_result = copy_result<_Iter, _Out>; + using copy_if_result = in_out_result<_Iter, _Out>; struct __copy_if_fn { @@ -869,7 +879,7 @@ namespace ranges inline constexpr __copy_if_fn copy_if{}; template - using swap_ranges_result = mismatch_result<_Iter1, _Iter2>; + using swap_ranges_result = in_in_result<_Iter1, _Iter2>; struct __swap_ranges_fn { @@ -900,10 +910,10 @@ namespace ranges inline constexpr __swap_ranges_fn swap_ranges{}; template - using unary_transform_result = copy_result<_Iter, _Out>; + using unary_transform_result = in_out_result<_Iter, _Out>; template - struct binary_transform_result + struct in_in_out_result { [[no_unique_address]] _Iter1 in1; [[no_unique_address]] _Iter2 in2; @@ -913,17 +923,22 @@ namespace ranges requires convertible_to && convertible_to && convertible_to - operator binary_transform_result<_IIter1, _IIter2, _OOut>() const & + constexpr + operator in_in_out_result<_IIter1, _IIter2, _OOut>() const & { return {in1, in2, out}; } template requires convertible_to<_Iter1, _IIter1> && convertible_to<_Iter2, _IIter2> && convertible_to<_Out, _OOut> - operator binary_transform_result<_IIter1, _IIter2, _OOut>() && + constexpr + operator in_in_out_result<_IIter1, _IIter2, _OOut>() && { return {std::move(in1), std::move(in2), std::move(out)}; } }; + template + using binary_transform_result = in_in_out_result<_Iter1, _Iter2, _Out>; + struct __transform_fn { template _Sent, @@ -1065,7 +1080,7 @@ namespace ranges inline constexpr __replace_if_fn replace_if{}; template - using replace_copy_result = copy_result<_Iter, _Out>; + using replace_copy_result = in_out_result<_Iter, _Out>; struct __replace_copy_fn { @@ -1108,7 +1123,7 @@ namespace ranges inline constexpr __replace_copy_fn replace_copy{}; template - using replace_copy_if_result = copy_result<_Iter, _Out>; + using replace_copy_if_result = in_out_result<_Iter, _Out>; struct __replace_copy_if_fn { @@ -1261,7 +1276,7 @@ namespace ranges inline constexpr __remove_fn remove{}; template - using remove_copy_if_result = copy_result<_Iter, _Out>; + using remove_copy_if_result = in_out_result<_Iter, _Out>; struct __remove_copy_if_fn { @@ -1300,7 +1315,7 @@ namespace ranges inline constexpr __remove_copy_if_fn remove_copy_if{}; template - using remove_copy_result = copy_result<_Iter, _Out>; + using remove_copy_result = in_out_result<_Iter, _Out>; struct __remove_copy_fn { @@ -1379,7 +1394,7 @@ namespace ranges inline constexpr __unique_fn unique{}; template - using unique_copy_result = copy_result<_Iter, _Out>; + using unique_copy_result = in_out_result<_Iter, _Out>; struct __unique_copy_fn { @@ -1514,7 +1529,7 @@ namespace ranges inline constexpr __reverse_fn reverse{}; template - using reverse_copy_result = copy_result<_Iter, _Out>; + using reverse_copy_result = in_out_result<_Iter, _Out>; struct __reverse_copy_fn { @@ -1695,7 +1710,7 @@ namespace ranges inline constexpr __rotate_fn rotate{}; template - using rotate_copy_result = copy_result<_Iter, _Out>; + using rotate_copy_result = in_out_result<_Iter, _Out>; struct __rotate_copy_fn { @@ -2093,7 +2108,7 @@ namespace ranges inline constexpr __partial_sort_fn partial_sort{}; template - using partial_sort_copy_result = copy_result<_Iter, _Out>; + using partial_sort_copy_result = in_out_result<_Iter, _Out>; struct __partial_sort_copy_fn { @@ -2580,28 +2595,33 @@ namespace ranges inline constexpr __stable_partition_fn stable_partition{}; - template - struct partition_copy_result + template + struct in_out_out_result { [[no_unique_address]] _Iter in; [[no_unique_address]] _Out1 out1; - [[no_unique_address]] _O2 out2; + [[no_unique_address]] _Out2 out2; template requires convertible_to && convertible_to - && convertible_to - operator partition_copy_result<_IIter, _OOut1, _OOut2>() const & + && convertible_to + constexpr + operator in_out_out_result<_IIter, _OOut1, _OOut2>() const & { return {in, out1, out2}; } template requires convertible_to<_Iter, _IIter> && convertible_to<_Out1, _OOut1> - && convertible_to<_O2, _OOut2> - operator partition_copy_result<_IIter, _OOut1, _OOut2>() && + && convertible_to<_Out2, _OOut2> + constexpr + operator in_out_out_result<_IIter, _OOut1, _OOut2>() && { return {std::move(in), std::move(out1), std::move(out2)}; } }; + template + using partition_copy_result = in_out_out_result<_Iter, _Out1, _Out2>; + struct __partition_copy_fn { template _Sent, @@ -2692,7 +2712,7 @@ namespace ranges inline constexpr __partition_point_fn partition_point{}; template - using merge_result = binary_transform_result<_Iter1, _Iter2, _Out>; + using merge_result = in_in_out_result<_Iter1, _Iter2, _Out>; struct __merge_fn { @@ -2834,7 +2854,7 @@ namespace ranges inline constexpr __includes_fn includes{}; template - using set_union_result = binary_transform_result<_Iter1, _Iter2, _Out>; + using set_union_result = in_in_out_result<_Iter1, _Iter2, _Out>; struct __set_union_fn { @@ -2902,8 +2922,7 @@ namespace ranges inline constexpr __set_union_fn set_union{}; template - using set_intersection_result - = binary_transform_result<_Iter1, _Iter2, _Out>; + using set_intersection_result = in_in_out_result<_Iter1, _Iter2, _Out>; struct __set_intersection_fn { @@ -2961,7 +2980,7 @@ namespace ranges inline constexpr __set_intersection_fn set_intersection{}; template - using set_difference_result = copy_result<_Iter, _Out>; + using set_difference_result = in_out_result<_Iter, _Out>; struct __set_difference_fn { @@ -3019,7 +3038,7 @@ namespace ranges template using set_symmetric_difference_result - = binary_transform_result<_Iter1, _Iter2, _Out>; + = in_in_out_result<_Iter1, _Iter2, _Out>; struct __set_symmetric_difference_fn { @@ -3218,22 +3237,27 @@ namespace ranges inline constexpr __clamp_fn clamp{}; template - struct minmax_result + struct min_max_result { [[no_unique_address]] _Tp min; [[no_unique_address]] _Tp max; template requires convertible_to - operator minmax_result<_Tp2>() const & + constexpr + operator min_max_result<_Tp2>() const & { return {min, max}; } template requires convertible_to<_Tp, _Tp2> - operator minmax_result<_Tp2>() && + constexpr + operator min_max_result<_Tp2>() && { return {std::move(min), std::move(max)}; } }; + template + using minmax_result = min_max_result<_Tp>; + struct __minmax_fn { template - using minmax_element_result = minmax_result<_Iter>; + using minmax_element_result = min_max_result<_Iter>; struct __minmax_element_fn { @@ -3516,12 +3540,27 @@ namespace ranges inline constexpr __lexicographical_compare_fn lexicographical_compare; template - struct next_permutation_result + struct in_found_result { + [[no_unique_address]] _Iter in; bool found; - _Iter in; + + template + requires convertible_to + constexpr + operator in_found_result<_Iter2>() const & + { return {in, found}; } + + template + requires convertible_to<_Iter, _Iter2> + constexpr + operator in_found_result<_Iter2>() && + { return {std::move(in), found}; } }; + template + using next_permutation_result = in_found_result<_Iter>; + struct __next_permutation_fn { template _Sent, @@ -3532,12 +3571,12 @@ namespace ranges _Comp __comp = {}, _Proj __proj = {}) const { if (__first == __last) - return {false, std::move(__first)}; + return {std::move(__first), false}; auto __i = __first; ++__i; if (__i == __last) - return {false, std::move(__i)}; + return {std::move(__i), false}; auto __lasti = ranges::next(__first, __last); __i = __lasti; @@ -3558,12 +3597,12 @@ namespace ranges ; ranges::iter_swap(__i, __j); ranges::reverse(__ii, __last); - return {true, std::move(__lasti)}; + return {std::move(__lasti), true}; } if (__i == __first) { ranges::reverse(__first, __last); - return {false, std::move(__lasti)}; + return {std::move(__lasti), false}; } } } @@ -3582,7 +3621,7 @@ namespace ranges inline constexpr __next_permutation_fn next_permutation{}; template - using prev_permutation_result = next_permutation_result<_Iter>; + using prev_permutation_result = in_found_result<_Iter>; struct __prev_permutation_fn { @@ -3594,12 +3633,12 @@ namespace ranges _Comp __comp = {}, _Proj __proj = {}) const { if (__first == __last) - return {false, std::move(__first)}; + return {std::move(__first), false}; auto __i = __first; ++__i; if (__i == __last) - return {false, std::move(__i)}; + return {std::move(__i), false}; auto __lasti = ranges::next(__first, __last); __i = __lasti; @@ -3620,12 +3659,12 @@ namespace ranges ; ranges::iter_swap(__i, __j); ranges::reverse(__ii, __last); - return {true, std::move(__lasti)}; + return {std::move(__lasti), true}; } if (__i == __first) { ranges::reverse(__first, __last); - return {false, std::move(__lasti)}; + return {std::move(__lasti), false}; } } } diff --git a/libstdc++-v3/include/bits/ranges_algobase.h b/libstdc++-v3/include/bits/ranges_algobase.h index eedd29f570a..7424766f053 100644 --- a/libstdc++-v3/include/bits/ranges_algobase.h +++ b/libstdc++-v3/include/bits/ranges_algobase.h @@ -157,7 +157,7 @@ namespace ranges inline constexpr __equal_fn equal{}; template - struct copy_result + struct in_out_result { [[no_unique_address]] _Iter in; [[no_unique_address]] _Out out; @@ -165,24 +165,29 @@ namespace ranges template requires convertible_to && convertible_to - operator copy_result<_Iter2, _Out2>() const & + constexpr + operator in_out_result<_Iter2, _Out2>() const & { return {in, out}; } template requires convertible_to<_Iter, _Iter2> && convertible_to<_Out, _Out2> - operator copy_result<_Iter2, _Out2>() && + constexpr + operator in_out_result<_Iter2, _Out2>() && { return {std::move(in), std::move(out)}; } }; template - using move_result = copy_result<_Iter, _Out>; + using copy_result = in_out_result<_Iter, _Out>; + + template + using move_result = in_out_result<_Iter, _Out>; template - using move_backward_result = copy_result<_Iter1, _Iter2>; + using move_backward_result = in_out_result<_Iter1, _Iter2>; template - using copy_backward_result = copy_result<_Iter1, _Iter2>; + using copy_backward_result = in_out_result<_Iter1, _Iter2>; template _Sent, @@ -483,7 +488,7 @@ namespace ranges inline constexpr __move_backward_fn move_backward{}; template - using copy_n_result = copy_result<_Iter, _Out>; + using copy_n_result = in_out_result<_Iter, _Out>; struct __copy_n_fn { diff --git a/libstdc++-v3/include/bits/ranges_uninitialized.h b/libstdc++-v3/include/bits/ranges_uninitialized.h index bbf683de066..881bf39d5f8 100644 --- a/libstdc++-v3/include/bits/ranges_uninitialized.h +++ b/libstdc++-v3/include/bits/ranges_uninitialized.h @@ -253,7 +253,7 @@ namespace ranges uninitialized_value_construct_n; template - using uninitialized_copy_result = copy_result<_Iter, _Out>; + using uninitialized_copy_result = in_out_result<_Iter, _Out>; struct __uninitialized_copy_fn { @@ -302,7 +302,7 @@ namespace ranges inline constexpr __uninitialized_copy_fn uninitialized_copy{}; template - using uninitialized_copy_n_result = uninitialized_copy_result<_Iter, _Out>; + using uninitialized_copy_n_result = in_out_result<_Iter, _Out>; struct __uninitialized_copy_n_fn { @@ -337,7 +337,7 @@ namespace ranges inline constexpr __uninitialized_copy_n_fn uninitialized_copy_n{}; template - using uninitialized_move_result = uninitialized_copy_result<_Iter, _Out>; + using uninitialized_move_result = in_out_result<_Iter, _Out>; struct __uninitialized_move_fn { @@ -389,7 +389,7 @@ namespace ranges inline constexpr __uninitialized_move_fn uninitialized_move{}; template - using uninitialized_move_n_result = uninitialized_copy_result<_Iter, _Out>; + using uninitialized_move_n_result = in_out_result<_Iter, _Out>; struct __uninitialized_move_n_fn { diff --git a/libstdc++-v3/testsuite/25_algorithms/next_permutation/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/next_permutation/constrained.cc index e69b551a56b..b397a4e8ed7 100644 --- a/libstdc++-v3/testsuite/25_algorithms/next_permutation/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/next_permutation/constrained.cc @@ -41,7 +41,7 @@ test01() for (int j = 0; ; j++) { auto found1 = std::next_permutation(cx.begin(), cx.end()); - auto [found2,last] = ranges::next_permutation(cy.begin(), cy.end()); + auto [last,found2] = ranges::next_permutation(cy.begin(), cy.end()); VERIFY( found1 == found2 ); VERIFY( ranges::equal(cx, cy) ); if (!found2) @@ -55,7 +55,7 @@ test02() { int x[] = {5, 4, 3, 2, 1}; test_range rx(x); - auto [found,last] = ranges::next_permutation(rx, ranges::greater{}); + auto [last,found] = ranges::next_permutation(rx, ranges::greater{}); VERIFY( found && last == rx.end() ); VERIFY( last == rx.end() ); VERIFY( ranges::equal(rx, (int[]){5,4,3,1,2}) ); diff --git a/libstdc++-v3/testsuite/25_algorithms/prev_permutation/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/prev_permutation/constrained.cc index 25bbad9be0c..22f1329b4c7 100644 --- a/libstdc++-v3/testsuite/25_algorithms/prev_permutation/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/prev_permutation/constrained.cc @@ -41,7 +41,7 @@ test01() for (int j = 0; ; j++) { auto found1 = std::prev_permutation(cx.begin(), cx.end()); - auto [found2,last] = ranges::prev_permutation(cy.begin(), cy.end()); + auto [last,found2] = ranges::prev_permutation(cy.begin(), cy.end()); VERIFY( found1 == found2 ); VERIFY( ranges::equal(cx, cy) ); if (!found2) @@ -55,7 +55,7 @@ test02() { int x[] = {1, 2, 3, 4, 5}; test_range rx(x); - auto [found,last] = ranges::prev_permutation(rx, ranges::greater{}); + auto [last,found] = ranges::prev_permutation(rx, ranges::greater{}); VERIFY( found && last == rx.end() ); VERIFY( last == rx.end() ); VERIFY( ranges::equal(rx, (int[]){1,2,3,5,4}) );