diff options
author | Patrick Palka <ppalka@redhat.com> | 2023-02-03 10:52:15 -0500 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2023-02-03 10:52:15 -0500 |
commit | 28752bcbbfb2efa1b57db725d7a3e352eabcc336 (patch) | |
tree | 8981ecf930add5bc6243de5911decda553dca98d /libstdc++-v3 | |
parent | 6716822c541bfd5e4bb91a39c0cb2c85b70f83de (diff) | |
download | gcc-28752bcbbfb2efa1b57db725d7a3e352eabcc336.zip gcc-28752bcbbfb2efa1b57db725d7a3e352eabcc336.tar.gz gcc-28752bcbbfb2efa1b57db725d7a3e352eabcc336.tar.bz2 |
libstdc++: Implement ranges::iota from P2440R1
libstdc++-v3/ChangeLog:
* include/bits/ranges_algo.h (out_value_result): Define.
(iota_result): Define.
(__iota_fn, iota): Define.
* testsuite/25_algorithms/iota/1.cc: New test.
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/include/bits/ranges_algo.h | 48 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/25_algorithms/iota/1.cc | 29 |
2 files changed, 77 insertions, 0 deletions
diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index b2c9902..8f9e1f8 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -3517,6 +3517,54 @@ namespace ranges }; inline constexpr __contains_subrange_fn contains_subrange{}; + + template<typename _Out, typename _Tp> + struct out_value_result + { + [[no_unique_address]] _Out out; + [[no_unique_address]] _Tp value; + + template<typename _Out2, typename _Tp2> + requires convertible_to<const _Out&, _Out2> + && convertible_to<const _Tp&, _Tp2> + constexpr + operator out_value_result<_Out2, _Tp2>() const & + { return {out, value}; } + + template<typename _Out2, typename _Tp2> + requires convertible_to<_Out, _Out2> + && convertible_to<_Tp, _Tp2> + constexpr + operator out_value_result<_Out2, _Tp2>() && + { return {std::move(out), std::move(value)}; } + }; + + template<typename _Out, typename _Tp> + using iota_result = out_value_result<_Out, _Tp>; + + struct __iota_fn + { + template<input_or_output_iterator _Out, sentinel_for<_Out> _Sent, weakly_incrementable _Tp> + requires indirectly_writable<_Out, const _Tp&> + constexpr iota_result<_Out, _Tp> + operator()(_Out __first, _Sent __last, _Tp __value) const + { + while (__first != __last) + { + *__first = static_cast<const _Tp&>(__value); + ++__first; + ++__value; + } + return {std::move(__first), std::move(__value)}; + } + + template<weakly_incrementable _Tp, output_range<const _Tp&> _Range> + constexpr iota_result<borrowed_iterator_t<_Range>, _Tp> + operator()(_Range&& __r, _Tp __value) const + { return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__value)); } + }; + + inline constexpr __iota_fn iota{}; #endif // C++23 } // namespace ranges diff --git a/libstdc++-v3/testsuite/25_algorithms/iota/1.cc b/libstdc++-v3/testsuite/25_algorithms/iota/1.cc new file mode 100644 index 0000000..ad2bf08 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/iota/1.cc @@ -0,0 +1,29 @@ +// { dg-options "-std=gnu++23" } +// { dg-do run { target c++23 } } + +#include <algorithm> +#include <testsuite_hooks.h> +#include <testsuite_iterators.h> + +namespace ranges = std::ranges; + +void +test01() +{ + int x[3] = {}; + __gnu_test::test_output_range<int> rx(x); + auto r0 = ranges::iota(rx, 0); + VERIFY( r0.out.ptr == x+3 ); + VERIFY( r0.value == 3 ); + VERIFY( ranges::equal(x, (int[]){0,1,2}) ); + auto r1 = ranges::iota(x, x+2, 5); + VERIFY( r1.out == x+2 ); + VERIFY( r1.value == 7 ); + VERIFY( ranges::equal(x, (int[]){5,6,2}) ); +} + +int +main() +{ + test01(); +} |