Re: [PATCH] libstdc++: Fix std::ranges::iota is not included in numeric [PR108760]
On Thu, 18 Apr 2024 at 22:59, Patrick Palka wrote: > > On Wed, 17 Apr 2024, Michael Levine (BLOOMBERG/ 919 3RD A) wrote: > > > This patch fixes GCC Bug 108760: > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108760 > > Before this patch, using std::ranges::iota required including > > when it should have been sufficient to only include . > > > > When the patch is applied, the following code will compile: > > https://godbolt.org/z/33EPeqd1b > > > > I added a test case for this change as well. > > > > I built my local version of gcc using the following configuration: $ > > ../gcc/configure --disable-bootstrap --prefix="$(pwd)/_pfx/" > > --enable-languages=c,c++,lto > > > > and I tested my changes by running: $ make check-c++ -jN -k > > Nice, thanks for the patch! > > > > > I ran this on the following OS: > > > > Virtualization: wsl > > Operating System: Ubuntu 20.04.6 LTS > > Kernel: Linux 5.15.146.1-microsoft-standard-WSL2 > > Architecture: x86-64 > > > From bd04070c281572ed7a3b48e3d33543e25b8c8afe Mon Sep 17 00:00:00 2001 > > From: Michael Levine > > Date: Fri, 23 Feb 2024 14:13:13 -0500 > > Subject: [PATCH 1/2] Fix the bug > > > > Signed-off-by: Michael Levine > > --- > > libstdc++-v3/include/bits/ranges_algo.h | 52 -- > > libstdc++-v3/include/bits/stl_numeric.h | 57 - > > 2 files changed, 56 insertions(+), 53 deletions(-) > > > > diff --git a/libstdc++-v3/include/bits/ranges_algo.h > > b/libstdc++-v3/include/bits/ranges_algo.h > > index 62faff173bd..d258be0b93f 100644 > > --- a/libstdc++-v3/include/bits/ranges_algo.h > > +++ b/libstdc++-v3/include/bits/ranges_algo.h > > @@ -3521,58 +3521,6 @@ namespace ranges > > > > #endif // __glibcxx_ranges_contains > > > > -#if __glibcxx_ranges_iota >= 202202L // C++ >= 23 > > - > > - template > > -struct out_value_result > > -{ > > - [[no_unique_address]] _Out out; > > - [[no_unique_address]] _Tp value; > > - > > - template > > - requires convertible_to > > - && convertible_to > > - constexpr > > - operator out_value_result<_Out2, _Tp2>() const & > > - { return {out, value}; } > > - > > - template > > - requires convertible_to<_Out, _Out2> > > - && convertible_to<_Tp, _Tp2> > > - constexpr > > - operator out_value_result<_Out2, _Tp2>() && > > - { return {std::move(out), std::move(value)}; } > > -}; > > - > > - template > > -using iota_result = out_value_result<_Out, _Tp>; > > - > > - struct __iota_fn > > - { > > -template _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(__value); > > - ++__first; > > - ++__value; > > - } > > - return {std::move(__first), std::move(__value)}; > > - } > > - > > -template _Range> > > - constexpr iota_result, _Tp> > > - operator()(_Range&& __r, _Tp __value) const > > - { return (*this)(ranges::begin(__r), ranges::end(__r), > > std::move(__value)); } > > - }; > > - > > - inline constexpr __iota_fn iota{}; > > - > > -#endif // __glibcxx_ranges_iota > > - > > #if __glibcxx_ranges_find_last >= 202207L // C++ >= 23 > > > >struct __find_last_fn > > diff --git a/libstdc++-v3/include/bits/stl_numeric.h > > b/libstdc++-v3/include/bits/stl_numeric.h > > index fe911154ab7..1b06c26dc02 100644 > > --- a/libstdc++-v3/include/bits/stl_numeric.h > > +++ b/libstdc++-v3/include/bits/stl_numeric.h > > @@ -59,7 +59,7 @@ > > #include > > #include > > #include // For _GLIBCXX_MOVE > > - > > +#include // For _Range as used by std::ranges::iota > > > > namespace std _GLIBCXX_VISIBILITY(default) > > { > > @@ -102,6 +102,61 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > } > > #endif > > > > +namespace ranges > > +{ > > +#if __glibcxx_ranges_iota >= 202202L // C++ >= 23 > > + > > + template > > +struct out_value_result > > +{ > > + [[no_unique_address]] _Out out; > > + [[no_unique_address]] _Tp value; > > + > > + template > > + requires convertible_to > > + && convertible_to > > + constexpr > > + operator out_value_result<_Out2, _Tp2>() const & > > + { return {out, value}; } > > + > > + template > > + requires convertible_to<_Out, _Out2> > > + && convertible_to<_Tp, _Tp2> > > + constexpr > > + operator out_value_result<_Out2, _Tp2>() && > > + { return {std::move(out), std::move(value)}; } > > +}; > > IIUC out_value_result should continue to be available from , so we > probably don't want to move it to (or one of its internal headers). > Better would be to move it to I think. > > > + > > + template > > +using iota_result = out_value_result<_Out, _Tp>; > > + > > + struct __iota_fn > > + { > > +template _Sent, >
Re: [PATCH] libstdc++: Fix std::ranges::iota is not included in numeric [PR108760]
On Wed, 17 Apr 2024, Michael Levine (BLOOMBERG/ 919 3RD A) wrote: > This patch fixes GCC Bug 108760: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108760 > Before this patch, using std::ranges::iota required including > when it should have been sufficient to only include . > > When the patch is applied, the following code will compile: > https://godbolt.org/z/33EPeqd1b > > I added a test case for this change as well. > > I built my local version of gcc using the following configuration: $ > ../gcc/configure --disable-bootstrap --prefix="$(pwd)/_pfx/" > --enable-languages=c,c++,lto > > and I tested my changes by running: $ make check-c++ -jN -k Nice, thanks for the patch! > > I ran this on the following OS: > > Virtualization: wsl > Operating System: Ubuntu 20.04.6 LTS > Kernel: Linux 5.15.146.1-microsoft-standard-WSL2 > Architecture: x86-64 > From bd04070c281572ed7a3b48e3d33543e25b8c8afe Mon Sep 17 00:00:00 2001 > From: Michael Levine > Date: Fri, 23 Feb 2024 14:13:13 -0500 > Subject: [PATCH 1/2] Fix the bug > > Signed-off-by: Michael Levine > --- > libstdc++-v3/include/bits/ranges_algo.h | 52 -- > libstdc++-v3/include/bits/stl_numeric.h | 57 - > 2 files changed, 56 insertions(+), 53 deletions(-) > > diff --git a/libstdc++-v3/include/bits/ranges_algo.h > b/libstdc++-v3/include/bits/ranges_algo.h > index 62faff173bd..d258be0b93f 100644 > --- a/libstdc++-v3/include/bits/ranges_algo.h > +++ b/libstdc++-v3/include/bits/ranges_algo.h > @@ -3521,58 +3521,6 @@ namespace ranges > > #endif // __glibcxx_ranges_contains > > -#if __glibcxx_ranges_iota >= 202202L // C++ >= 23 > - > - template > -struct out_value_result > -{ > - [[no_unique_address]] _Out out; > - [[no_unique_address]] _Tp value; > - > - template > - requires convertible_to > - && convertible_to > - constexpr > - operator out_value_result<_Out2, _Tp2>() const & > - { return {out, value}; } > - > - template > - requires convertible_to<_Out, _Out2> > - && convertible_to<_Tp, _Tp2> > - constexpr > - operator out_value_result<_Out2, _Tp2>() && > - { return {std::move(out), std::move(value)}; } > -}; > - > - template > -using iota_result = out_value_result<_Out, _Tp>; > - > - struct __iota_fn > - { > -template _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(__value); > - ++__first; > - ++__value; > - } > - return {std::move(__first), std::move(__value)}; > - } > - > -template _Range> > - constexpr iota_result, _Tp> > - operator()(_Range&& __r, _Tp __value) const > - { return (*this)(ranges::begin(__r), ranges::end(__r), > std::move(__value)); } > - }; > - > - inline constexpr __iota_fn iota{}; > - > -#endif // __glibcxx_ranges_iota > - > #if __glibcxx_ranges_find_last >= 202207L // C++ >= 23 > >struct __find_last_fn > diff --git a/libstdc++-v3/include/bits/stl_numeric.h > b/libstdc++-v3/include/bits/stl_numeric.h > index fe911154ab7..1b06c26dc02 100644 > --- a/libstdc++-v3/include/bits/stl_numeric.h > +++ b/libstdc++-v3/include/bits/stl_numeric.h > @@ -59,7 +59,7 @@ > #include > #include > #include // For _GLIBCXX_MOVE > - > +#include // For _Range as used by std::ranges::iota > > namespace std _GLIBCXX_VISIBILITY(default) > { > @@ -102,6 +102,61 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > } > #endif > > +namespace ranges > +{ > +#if __glibcxx_ranges_iota >= 202202L // C++ >= 23 > + > + template > +struct out_value_result > +{ > + [[no_unique_address]] _Out out; > + [[no_unique_address]] _Tp value; > + > + template > + requires convertible_to > + && convertible_to > + constexpr > + operator out_value_result<_Out2, _Tp2>() const & > + { return {out, value}; } > + > + template > + requires convertible_to<_Out, _Out2> > + && convertible_to<_Tp, _Tp2> > + constexpr > + operator out_value_result<_Out2, _Tp2>() && > + { return {std::move(out), std::move(value)}; } > +}; IIUC out_value_result should continue to be available from , so we probably don't want to move it to (or one of its internal headers). Better would be to move it to I think. > + > + template > +using iota_result = out_value_result<_Out, _Tp>; > + > + struct __iota_fn > + { > +template _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(__value); > + ++__first; > + ++__value; > +