From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1888) id C6BAE3858C3A; Fri, 3 Feb 2023 15:54:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C6BAE3858C3A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1675439655; bh=vYQ6DN7pE45zkMnwtYiIl7/ZVRDiso5AHtGZF1dzeWc=; h=From:To:Subject:Date:From; b=bv2EgbA0D1BCflNY9WIlin4QWabcKeMT9RwnmmBR+xtPRG2KNk0FP3RwaseJAP8Op KYNRwjxyLv8Akvh5q9nQDM8hFkPl8qHWU7jnumme/4OgFsL7Y7LEmjNb9Lq4I/+GD4 c3YahIAl7mfP6291Bn3EfJg068htLZVaYBXOHypM= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Patrick Palka To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r13-5687] libstdc++: Implement ranges::contains/contains_subrange from P2302R4 X-Act-Checkin: gcc X-Git-Author: Patrick Palka X-Git-Refname: refs/heads/master X-Git-Oldrev: 330d665ce6dcc63ed0bd78d807e69bbfc55255b6 X-Git-Newrev: 6716822c541bfd5e4bb91a39c0cb2c85b70f83de Message-Id: <20230203155415.C6BAE3858C3A@sourceware.org> Date: Fri, 3 Feb 2023 15:54:15 +0000 (GMT) List-Id: https://gcc.gnu.org/g:6716822c541bfd5e4bb91a39c0cb2c85b70f83de commit r13-5687-g6716822c541bfd5e4bb91a39c0cb2c85b70f83de Author: Patrick Palka Date: Fri Feb 3 10:52:13 2023 -0500 libstdc++: Implement ranges::contains/contains_subrange from P2302R4 libstdc++-v3/ChangeLog: * include/bits/ranges_algo.h (__contains_fn, contains): Define. (__contains_subrange_fn, contains_subrange): Define. * testsuite/25_algorithms/contains/1.cc: New test. * testsuite/25_algorithms/contains_subrange/1.cc: New test. Diff: --- libstdc++-v3/include/bits/ranges_algo.h | 54 ++++++++++++++++++++++ libstdc++-v3/testsuite/25_algorithms/contains/1.cc | 33 +++++++++++++ .../testsuite/25_algorithms/contains_subrange/1.cc | 37 +++++++++++++++ 3 files changed, 124 insertions(+) diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index b33c9ab7d1b..b2c99028916 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -3464,6 +3464,60 @@ namespace ranges inline constexpr __prev_permutation_fn prev_permutation{}; +#if __cplusplus > 202002L + struct __contains_fn + { + template _Sent, + typename _Tp, typename _Proj = identity> + requires indirect_binary_predicate, const _Tp*> + constexpr bool + operator()(_Iter __first, _Sent __last, const _Tp& __value, _Proj __proj = {}) const + { return ranges::find(std::move(__first), __last, __value, std::move(__proj)) != __last; } + + template + requires indirect_binary_predicate, _Proj>, const _Tp*> + constexpr bool + operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const + { return (*this)(ranges::begin(__r), ranges::end(__r), __value, std::move(__proj)); } + }; + + inline constexpr __contains_fn contains{}; + + struct __contains_subrange_fn + { + template _Sent1, + forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, + typename _Pred = ranges::equal_to, + typename Proj1 = identity, typename Proj2 = identity> + requires indirectly_comparable<_Iter1, _Iter2, _Pred, Proj1, Proj2> + constexpr bool + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred __pred = {}, Proj1 __proj1 = {}, Proj2 __proj2 = {}) const + { + return __first2 == __last2 + || !ranges::search(__first1, __last1, __first2, __last2, + std::move(__pred), std::move(__proj1), std::move(__proj2)).empty(); + } + + template + requires indirectly_comparable, iterator_t<_Range2>, + _Pred, _Proj1, _Proj2> + constexpr bool + operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {}, + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const + { + return (*this)(ranges::begin(__r1), ranges::end(__r1), + ranges::begin(__r2), ranges::end(__r2), + std::move(__pred), std::move(__proj1), std::move(__proj2)); + } + }; + + inline constexpr __contains_subrange_fn contains_subrange{}; +#endif // C++23 } // namespace ranges #define __cpp_lib_shift 201806L diff --git a/libstdc++-v3/testsuite/25_algorithms/contains/1.cc b/libstdc++-v3/testsuite/25_algorithms/contains/1.cc new file mode 100644 index 00000000000..146ab593b70 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/contains/1.cc @@ -0,0 +1,33 @@ +// { dg-options "-std=gnu++23" } +// { dg-do run { target c++23 } } + +#include +#include +#include + +namespace ranges = std::ranges; + +void +test01() +{ + int x[] = {1,2,3}; + using to_input = __gnu_test::test_input_range; + VERIFY( ranges::contains(to_input(x), 1) ); + VERIFY( ranges::contains(to_input(x), 2) ); + VERIFY( ranges::contains(to_input(x), 3) ); + VERIFY( !ranges::contains(to_input(x), 4) ); + VERIFY( !ranges::contains(x, x+2, 3) ); + auto neg = [](int n) { return -n; }; + VERIFY( ranges::contains(to_input(x), -1, neg) ); + VERIFY( ranges::contains(to_input(x), -2, neg) ); + VERIFY( ranges::contains(to_input(x), -3, neg) ); + VERIFY( !ranges::contains(to_input(x), -4, neg) ); + + VERIFY( !ranges::contains(x, x+2, -3, neg) ); +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/contains_subrange/1.cc b/libstdc++-v3/testsuite/25_algorithms/contains_subrange/1.cc new file mode 100644 index 00000000000..6c3c99c0fd6 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/contains_subrange/1.cc @@ -0,0 +1,37 @@ +// { dg-options "-std=gnu++23" } +// { dg-do run { target c++23 } } + +#include +#include +#include + +namespace ranges = std::ranges; + +void +test01() +{ + int x[] = {1,2,3,4,5}; + int y[] = {2,3,4}; + int z[] = {4,5,6}; + __gnu_test::test_forward_range rx(x); + __gnu_test::test_forward_range ry(y); + __gnu_test::test_forward_range rz(z); + VERIFY( ranges::contains_subrange(rx, ry) ); + VERIFY( !ranges::contains_subrange(rx, rz) ); + VERIFY( ranges::contains_subrange(rx, ry, ranges::less{}) ); + VERIFY( ranges::contains_subrange(rx, rz, ranges::less{}) ); + auto plus3 = [](int n) { return n+3; }; + VERIFY( !ranges::contains_subrange(rx, ry, {}, plus3) ); + VERIFY( ranges::contains_subrange(rx, rz, {}, plus3) ); + VERIFY( ranges::contains_subrange(rx, ry, {}, plus3, plus3) ); + VERIFY( !ranges::contains_subrange(rx, rz, {}, plus3, plus3) ); + + VERIFY( ranges::contains_subrange(x, x+2, y, y+1) ); + VERIFY( !ranges::contains_subrange(x, x+2, y, y+2) ); +} + +int +main() +{ + test01(); +}