https://gcc.gnu.org/g:f91e34644e66b2eb7f4930f17a30da9f49e7d4d2

commit r15-5254-gf91e34644e66b2eb7f4930f17a30da9f49e7d4d2
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Thu Nov 14 10:50:34 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:

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 5ea901bf1f6c..e872598d7d8f 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -1731,6 +1731,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(); }
 
 #ifdef __cpp_lib_three_way_comparison
@@ -1791,6 +1792,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 __glibcxx_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 b2c1fe0e9f8d..deb177222578 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
@@ -18,6 +18,7 @@
 // { dg-do compile { target c++20 } }
 
 #include <iterator>
+#include <testsuite_iterators.h>
 
 template<int>
 struct Iter
@@ -141,3 +142,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> );

Reply via email to