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.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user