mirror of git://gcc.gnu.org/git/gcc.git
libstdc++: Fix std::ranges::iota is not included in numeric [PR108760]
Before this patch, using std::ranges::iota required including
<algorithm> when it should have been sufficient to only include
<numeric>.
For the backport to the release branch ranges::iota is defined in
<bits/ranges_algobase.h> so that it's available in both <numeric> and
<algorithm>. This avoids breaking code that compiles successfully using
existing releases where <algorithm> defines ranges::iota.
libstdc++-v3/ChangeLog:
PR libstdc++/108760
* include/bits/ranges_algo.h (ranges::out_value_result)
(ranges::iota_result, ranges::__iota_fn, ranges::iota): Move to
<bits/ranges_algobase.h>.
* include/bits/ranges_algobase.h (ranges::out_value_result):
(ranges::iota_result, ranges::__iota_fn, ranges::iota): Move to
here.
* include/std/numeric: Include <bits/ranges_algobase.h>.
* testsuite/25_algorithms/iota/1.cc: Renamed to ...
* testsuite/26_numerics/iota/2.cc: ... here.
Signed-off-by: Michael Levine <mlevine55@bloomberg.net>
(cherry picked from commit 0bb1db32cc
)
This commit is contained in:
parent
285f01004e
commit
997d51f3dc
|
@ -3524,56 +3524,6 @@ namespace ranges
|
|||
|
||||
inline constexpr __contains_subrange_fn contains_subrange{};
|
||||
|
||||
#define __cpp_lib_ranges_iota 202202L
|
||||
|
||||
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{};
|
||||
|
||||
#define __cpp_lib_ranges_find_last 202207L
|
||||
|
||||
struct __find_last_fn
|
||||
|
|
|
@ -71,6 +71,58 @@ namespace ranges
|
|||
__is_move_iterator<move_iterator<_Iterator>> = true;
|
||||
} // namespace __detail
|
||||
|
||||
#if __cplusplus > 202002L
|
||||
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)}; }
|
||||
};
|
||||
|
||||
#define __cpp_lib_ranges_iota 202202L
|
||||
|
||||
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
|
||||
|
||||
struct __equal_fn
|
||||
{
|
||||
template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
|
||||
|
|
|
@ -79,6 +79,10 @@
|
|||
# include <limits>
|
||||
#endif
|
||||
|
||||
#if __cplusplus > 202002L
|
||||
# include <bits/ranges_algobase.h> // for ranges::iota
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup numerics Numerics
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// { dg-options "-std=gnu++23" }
|
||||
// { dg-do run { target c++23 } }
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
Loading…
Reference in New Issue