]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Use deducing this in range adaptors even in C++20 [PR111550]
authorPatrick Palka <ppalka@redhat.com>
Fri, 5 Dec 2025 17:16:30 +0000 (12:16 -0500)
committerPatrick Palka <ppalka@redhat.com>
Fri, 5 Dec 2025 17:16:30 +0000 (12:16 -0500)
Use deducing this to implement perfect forwarding even in C++20 mode
by using the _GLIBCXX_EXPLICIT_THIS_PARAMETER internal FTM instead of
the standard __cpp_explicit_this_parameter.  This fixes the original
testcase from this PR even in C++20 mode.

PR libstdc++/111550

libstdc++-v3/ChangeLog:

* include/std/ranges (views::__adaptor::_Partial::operator())
[_GLIBCXX_EXPLICIT_THIS_PARAMETER]: Also use deducing this
in C++20 mode when possible.
(views::__adaptor::_Pipe::Operator())
[_GLIBCXX_EXPLICIT_THIS_PARAMETER]: Likewise.
* testsuite/std/ranges/adaptors/take.cc (test07): New test.

Reviewed-by: Tomasz KamiƄski <tkaminsk@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/include/std/ranges
libstdc++-v3/testsuite/std/ranges/adaptors/take.cc

index b3105c55383965e3ecd8007eedf70ca758d56239..b81ee784ec375e7c2c57c7173919804ad5769c64 100644 (file)
@@ -1259,7 +1259,9 @@ namespace views::__adaptor
 
       // Invoke _Adaptor with arguments __r, _M_args... according to the
       // value category of this _Partial object.
-#if __cpp_explicit_this_parameter
+#if _GLIBCXX_EXPLICIT_THIS_PARAMETER
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wc++23-extensions" // deducing this
       template<typename _Self, typename _Range>
        requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
        constexpr auto
@@ -1268,6 +1270,7 @@ namespace views::__adaptor
          return _Binder::_S_call(__like_t<_Self, _Partial>(__self)._M_binder,
                                  std::forward<_Range>(__r));
        }
+# pragma GCC diagnostic pop
 #else
       template<typename _Range>
        requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
@@ -1336,7 +1339,9 @@ namespace views::__adaptor
 
       // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
       // range adaptor closure object.
-#if __cpp_explicit_this_parameter
+#if _GLIBCXX_EXPLICIT_THIS_PARAMETER
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wc++23-extensions" // deducing this
       template<typename _Self, typename _Range>
        requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
        constexpr auto
@@ -1346,6 +1351,7 @@ namespace views::__adaptor
                  (__like_t<_Self, _Pipe>(__self)._M_lhs
                   (std::forward<_Range>(__r))));
        }
+# pragma GCC diagnostic pop
 #else
       template<typename _Range>
        requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
index 167377264cbf4b2cb83a5c800a079b238b51b3a1..9584c576b96543b8ceff850b812396071aab92c1 100644 (file)
@@ -118,6 +118,20 @@ test06()
   static_assert(!requires { views::all | take; });
 }
 
+void
+test07()
+{
+  // PR libstdc++/111550
+  struct Five {
+    operator int() & { return 5; }
+    operator int() && = delete;
+  };
+  auto take_five = views::take(Five{});
+  auto r = take_five(views::iota(0));
+  auto take_five_piped = views::take(Five{}) | views::transform(std::identity{});
+  auto s = take_five_piped(views::iota(0));
+}
+
 int
 main()
 {
@@ -127,4 +141,5 @@ main()
   test04();
   test05();
   test06();
+  test07();
 }