https://gcc.gnu.org/g:5a2a527b26c22df4f1764f61b2285ac0c380ff68
commit r16-5918-g5a2a527b26c22df4f1764f61b2285ac0c380ff68 Author: Patrick Palka <[email protected]> Date: Fri Dec 5 12:16:30 2025 -0500 libstdc++: Use deducing this in range adaptors even in C++20 [PR111550] 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 <[email protected]> Reviewed-by: Jonathan Wakely <[email protected]> Diff: --- libstdc++-v3/include/std/ranges | 10 ++++++++-- libstdc++-v3/testsuite/std/ranges/adaptors/take.cc | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index b3105c553839..b81ee784ec37 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -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> diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/take.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/take.cc index 167377264cbf..9584c576b965 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/take.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/take.cc @@ -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(); }
