]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Implement LWG 3664 changes to ranges::distance
authorPatrick Palka <ppalka@redhat.com>
Sat, 5 Oct 2024 17:48:06 +0000 (13:48 -0400)
committerPatrick Palka <ppalka@redhat.com>
Sat, 5 Oct 2024 17:48:06 +0000 (13:48 -0400)
libstdc++-v3/ChangeLog:

* include/bits/ranges_base.h (__distance_fn::operator()):
Adjust iterator/sentinel overloads as per LWG 3664.
* testsuite/24_iterators/range_operations/distance.cc:
Test LWG 3664 example.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/include/bits/ranges_base.h
libstdc++-v3/testsuite/24_iterators/range_operations/distance.cc

index 137c3c98e146367aa04427e0c70cc0b35866e0a3..cb2eba1f841a2990b898c72a61a691aaeaa80787 100644 (file)
@@ -947,7 +947,9 @@ namespace ranges
 
   struct __distance_fn final
   {
-    template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
+    // _GLIBCXX_RESOLVE_LIB_DEFECTS
+    // 3664. LWG 3392 broke std::ranges::distance(a, a+3)
+    template<typename _It, sentinel_for<_It> _Sent>
       requires (!sized_sentinel_for<_Sent, _It>)
       constexpr iter_difference_t<_It>
       operator()[[nodiscard]](_It __first, _Sent __last) const
@@ -961,13 +963,11 @@ namespace ranges
        return __n;
       }
 
-    template<input_or_output_iterator _It, sized_sentinel_for<_It> _Sent>
+    template<typename _It, sized_sentinel_for<decay_t<_It>> _Sent>
       [[nodiscard]]
-      constexpr iter_difference_t<_It>
-      operator()(const _It& __first, const _Sent& __last) const
-      {
-       return __last - __first;
-      }
+      constexpr iter_difference_t<decay_t<_It>>
+      operator()(_It&& __first, _Sent __last) const
+      { return __last - static_cast<const decay_t<_It>&>(__first); }
 
     template<range _Range>
       [[nodiscard]]
index 9a1d0c3efe8346fc8ce43544cfc2a294f2652549..336956936c2258268462e5202420054aa6b32f91 100644 (file)
@@ -144,6 +144,16 @@ test05()
   VERIFY( std::ranges::distance(c4) == 5 );
 }
 
+void
+test06()
+{
+  // LWG 3664 - LWG 3392 broke std::ranges::distance(a, a+3)
+  int a[] = {1, 2, 3};
+  VERIFY( std::ranges::distance(a, a+3) == 3 );
+  VERIFY( std::ranges::distance(a, a) == 0 );
+  VERIFY( std::ranges::distance(a+3, a) == -3 );
+}
+
 int
 main()
 {
@@ -152,4 +162,5 @@ main()
   test03();
   test04();
   test05();
+  test06();
 }