https://gcc.gnu.org/g:aa66f142d4e8ffd6dfeccde0378439d1bce4eccc
commit r13-9241-gaa66f142d4e8ffd6dfeccde0378439d1bce4eccc Author: Jonathan Wakely <jwak...@redhat.com> Date: Fri Dec 6 21:32:29 2024 +0000 libstdc++: Add missing constraint to operator+ for std::move_iterator This constraint was added by the One Ranges proposal (P0896R4) and then fixed by LWG 3293, but it was missing from libstdc++. libstdc++-v3/ChangeLog: * include/bits/stl_iterator.h (operator+): Add constraint to move_iterator operator. * testsuite/24_iterators/move_iterator/rel_ops_c++20.cc: Check it's constrained. (cherry picked from commit f91e34644e66b2eb7f4930f17a30da9f49e7d4d2) Diff: --- libstdc++-v3/include/bits/stl_iterator.h | 4 ++++ .../testsuite/24_iterators/move_iterator/rel_ops_c++20.cc | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 203ccc7bf6b4..68bb1023081a 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1747,6 +1747,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline _GLIBCXX17_CONSTEXPR bool operator==(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y) + // N.B. No contraints, x.base() == y.base() is always well-formed. { return __x.base() == __y.base(); } #if __cpp_lib_three_way_comparison @@ -1807,6 +1808,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator> operator+(typename move_iterator<_Iterator>::difference_type __n, const move_iterator<_Iterator>& __x) +#ifdef __cpp_lib_concepts + requires requires { { __x.base() + __n } -> same_as<_Iterator>; } +#endif { return __x + __n; } template<typename _Iterator> diff --git a/libstdc++-v3/testsuite/24_iterators/move_iterator/rel_ops_c++20.cc b/libstdc++-v3/testsuite/24_iterators/move_iterator/rel_ops_c++20.cc index 9f437acb50a6..49e1032a3d18 100644 --- a/libstdc++-v3/testsuite/24_iterators/move_iterator/rel_ops_c++20.cc +++ b/libstdc++-v3/testsuite/24_iterators/move_iterator/rel_ops_c++20.cc @@ -19,6 +19,7 @@ // { dg-do compile { target c++2a } } #include <iterator> +#include <testsuite_iterators.h> template<int> struct Iter @@ -142,3 +143,14 @@ static_assert( cend > beg ); static_assert( beg <= cend ); static_assert( cend >= beg ); static_assert( std::is_lt(beg <=> cend) ); + +template<typename I> + concept has_plus = requires(std::iter_difference_t<I> n, I i) { + { n + i } -> std::same_as<I>; + }; + +using namespace __gnu_test; +using MBI = std::move_iterator<bidirectional_iterator_wrapper<int>>; +static_assert( ! has_plus<MBI> ); +using MRI = std::move_iterator<random_access_iterator_wrapper<int>>; +static_assert( has_plus<MRI> );