On Mon, 13 Oct 2025 at 16:17, Patrick Palka <[email protected]> wrote:
>
> 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.

OK for trunk.

> ---
>  libstdc++-v3/include/std/ranges                   | 10 ++++++++--
>  .../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 fd290ea362cc..9b8aa8d734e6 100644
> --- a/libstdc++-v3/include/std/ranges
> +++ b/libstdc++-v3/include/std/ranges
> @@ -1061,7 +1061,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
> @@ -1070,6 +1072,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&...>
> @@ -1138,7 +1141,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
> @@ -1148,6 +1153,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();
>  }
> --
> 2.51.0.491.g4b71b29477
>

Reply via email to