https://gcc.gnu.org/g:997d51f3dc16607a8ddb27c3601cb033c92e43e1
commit r13-9544-g997d51f3dc16607a8ddb27c3601cb033c92e43e1 Author: Michael Levine <mlevin...@bloomberg.net> Date: Fri Jun 7 09:54:38 2024 +0100 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 <mlevin...@bloomberg.net> (cherry picked from commit 0bb1db32ccf54a9de59bea718f7575f7ef22abf5) Diff: --- libstdc++-v3/include/bits/ranges_algo.h | 50 --------------------- libstdc++-v3/include/bits/ranges_algobase.h | 52 ++++++++++++++++++++++ libstdc++-v3/include/std/numeric | 4 ++ .../iota/1.cc => 26_numerics/iota/2.cc} | 2 +- 4 files changed, 57 insertions(+), 51 deletions(-) diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index 410d3ae1dd82..48efe9f81655 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -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 diff --git a/libstdc++-v3/include/bits/ranges_algobase.h b/libstdc++-v3/include/bits/ranges_algobase.h index c9bfdaa1d5f5..fbf0c2dad206 100644 --- a/libstdc++-v3/include/bits/ranges_algobase.h +++ b/libstdc++-v3/include/bits/ranges_algobase.h @@ -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, diff --git a/libstdc++-v3/include/std/numeric b/libstdc++-v3/include/std/numeric index dfbaf8499cbd..19977cdff6f0 100644 --- a/libstdc++-v3/include/std/numeric +++ b/libstdc++-v3/include/std/numeric @@ -79,6 +79,10 @@ # include <limits> #endif +#if __cplusplus > 202002L +# include <bits/ranges_algobase.h> // for ranges::iota +#endif + /** * @defgroup numerics Numerics * diff --git a/libstdc++-v3/testsuite/25_algorithms/iota/1.cc b/libstdc++-v3/testsuite/26_numerics/iota/2.cc similarity index 96% rename from libstdc++-v3/testsuite/25_algorithms/iota/1.cc rename to libstdc++-v3/testsuite/26_numerics/iota/2.cc index ad2bf08adf57..446048600dad 100644 --- a/libstdc++-v3/testsuite/25_algorithms/iota/1.cc +++ b/libstdc++-v3/testsuite/26_numerics/iota/2.cc @@ -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>