On Thu, 6 Jun 2024 at 21:49, Michael Levine (BLOOMBERG/ 731 LEX) <mlevin...@bloomberg.net> wrote: > > To test the theory that this issue was unrelated to my patch, I moved the > out_value_result definition into std/numeric and restored the version of > bits/ranges_algobase.h to the version in master. I kept the include line > "include <bits/ranges_algobase.h>" in std/numeric even though it wasn't being > used. With the include line I see the same error about __memcmp is not a > member of 'std'.
Thanks, I'll fix that separately and then apply your patch for iota. > > From: Michael Levine (BLOOMBERG/ 731 LEX) At: 05/30/24 13:43:58 UTC-4:00 > To: jwak...@redhat.com > Cc: ppa...@redhat.com, gcc-patches@gcc.gnu.org, libstd...@gcc.gnu.org > Subject: Re: [PATCH v3] libstdc++: Fix std::ranges::iota not in numeric > [PR108760] > > When I remove <bits/stl_algobase.h> for importing __memcmp (my apologies for > writing __memcpy) from libstdc++-v3/include/bits/ranges_algobase.h and try to > rerun the code, I get the following error: > > In file included from > $HOME/projects/objdirforgcc/_pfx/include/c++/15.0.0/numeric:69, > from ranges-iota-fix.cpp:1: > $HOME/projects/objdirforgcc/_pfx/include/c++/15.0.0/bits/ranges_algobase.h: > In member function ‘constexpr bool > std::ranges::__equal_fn::operator()(_Iter1, _Sent1, _Iter2, _Sent2, _Pred, > _Proj1, _Proj2) const’: > $HOME/projects/objdirforgcc/_pfx/include/c++/15.0.0/bits/ranges_algobase.h:143:32: > error: ‘__memcmp’ is not a member of ‘std’; did you mean ‘__memcmpable’? > 143 | return !std::__memcmp(__first1, __first2, __len); > | ^~~~~~~~ > | __memcmpable > > From: jwak...@redhat.com At: 05/24/24 10:12:57 UTC-4:00 > To: Michael Levine (BLOOMBERG/ 731 LEX ) > Cc: ppa...@redhat.com, gcc-patches@gcc.gnu.org, libstd...@gcc.gnu.org > Subject: Re: [PATCH v3] libstdc++: Fix std::ranges::iota not in numeric > [PR108760] > > On 24/05/24 13:56 -0000, Michael Levine (BLOOMBERG/ 731 LEX) wrote: > >I've attached the v3 version of the patch as a single, squashed patch > containing all of the changes. I manually prepended my sign off to the patch. > > > >Signed-off-by: Michael Levine <mlevin...@bloomberg.net> > >--- > >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<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 // __glibcxx_ranges_iota > >- > > #if __glibcxx_ranges_find_last >= 202207L // C++ >= 23 > > > > struct __find_last_fn > >diff --git a/libstdc++-v3/include/bits/ranges_algobase.h > b/libstdc++-v3/include/bits/ranges_algobase.h > >index e26a73a27d6..965b36aed35 100644 > >--- a/libstdc++-v3/include/bits/ranges_algobase.h > >+++ b/libstdc++-v3/include/bits/ranges_algobase.h > >@@ -35,6 +35,7 @@ > > #include <compare> > > #include <bits/stl_iterator_base_funcs.h> > > #include <bits/stl_iterator.h> > >+#include <bits/stl_algobase.h> // __memcpy > > Why is this being added here? What is __memcpy? > > I don't think out_value_result requires any new headers to be included > here, does it? > > > #include <bits/ranges_base.h> // ranges::begin, ranges::range etc. > > #include <bits/invoke.h> // __invoke > > #include <bits/cpp_type_traits.h> // __is_byte > >@@ -70,6 +71,32 @@ namespace ranges > > __is_move_iterator<move_iterator<_Iterator>> = true; > > } // namespace __detail > > > >+#if __glibcxx_ranges_iota >= 202202L // C++ >= 23 > >+ > >+ 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)}; } > >+ }; > >+ > >+#endif // __glibcxx_ranges_iota > >+ > >+ > > 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 c912db4a519..d88f7f02137 100644 > >--- a/libstdc++-v3/include/std/numeric > >+++ b/libstdc++-v3/include/std/numeric > >@@ -65,6 +65,10 @@ > > # include <parallel/numeric> > > #endif > > > >+#if __glibcxx_ranges_iota >= 202202L // C++ >= 23 > >+#include <bits/ranges_algobase.h> // for out_value_result as used by > std::ranges::iota. It transitively also brings in <bits/ranges_base.h>, from > which _Range is used by std::ranges::iota > > We generally try to keep lines below 80 columns, or 120 at a push. > This is unnecessarily long, and I don't know what _Range is meant to > be (that's just a template parameter, not something defined in > <bits/ranges_algobase.h>. Please just use: > > #include <bits/ranges_algobase.h> // for ranges::out_value_result > > Otherwise this looks ready to go in, thanks. > > >+#endif // __glibcxx_ranges_iota > >+ > > #if __cplusplus >= 201402L > > # include <type_traits> > > # include <bit> > >@@ -726,6 +730,40 @@ namespace __detail > > /// @} group numeric_ops > > #endif // C++17 > > > >+namespace ranges > >+{ > >+#if __glibcxx_ranges_iota >= 202202L // C++ >= 23 > >+ > >+ 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 // __glibcxx_ranges_iota > >+} // namespace ranges > >+ > > _GLIBCXX_END_NAMESPACE_VERSION > > } // namespace std > > > >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 61bf418b4da..040c48d91ce 100644 > >--- a/libstdc++-v3/testsuite/25_algorithms/iota/1.cc > >+++ b/libstdc++-v3/testsuite/26_numerics/iota/2.cc > >@@ -1,6 +1,6 @@ > > // { dg-do run { target c++23 } } > > > >-#include <algorithm> > >+#include <numeric> > > #include <testsuite_hooks.h> > > #include <testsuite_iterators.h> > > > >