From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1888) id 4619C3835800; Fri, 18 Jun 2021 03:05:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4619C3835800 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Patrick Palka To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r11-8613] libstdc++: Non-triv-copyable extra args aren't simple [PR100940] X-Act-Checkin: gcc X-Git-Author: Patrick Palka X-Git-Refname: refs/heads/releases/gcc-11 X-Git-Oldrev: bc7a522548c37daf612c2ba4c44e9ea93548ed45 X-Git-Newrev: f0d8d001d94166242be4387ca72fe0fc483860f1 Message-Id: <20210618030558.4619C3835800@sourceware.org> Date: Fri, 18 Jun 2021 03:05:58 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Jun 2021 03:05:58 -0000 https://gcc.gnu.org/g:f0d8d001d94166242be4387ca72fe0fc483860f1 commit r11-8613-gf0d8d001d94166242be4387ca72fe0fc483860f1 Author: Patrick Palka Date: Thu Jun 17 09:46:07 2021 -0400 libstdc++: Non-triv-copyable extra args aren't simple [PR100940] This force-enables perfect forwarding call wrapper semantics whenever the extra arguments of a partially applied range adaptor aren't all trivially copyable, so as to avoid incurring unnecessary copies of potentially expensive-to-copy objects (such as std::function objects) when invoking the adaptor. PR libstdc++/100940 libstdc++-v3/ChangeLog: * include/std/ranges (__adaptor::_Partial): For the "simple" forwarding partial specializations, also require that the extra arguments are trivially copyable. * testsuite/std/ranges/adaptors/100577.cc (test04): New test. (cherry picked from commit 2b87f3318cf6334a3a42dcf27f2fdec0fce04665) Diff: --- libstdc++-v3/include/std/ranges | 8 +++++--- libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 4921afc37df..9d1c4e1356a 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -892,11 +892,12 @@ namespace views::__adaptor }; // Partial specialization of the primary template for the case where the extra - // arguments of the adaptor can always be safely forwarded by const reference. - // This lets us get away with a single operator() overload, which makes - // overload resolution failure diagnostics more concise. + // arguments of the adaptor can always be safely and efficiently forwarded by + // const reference. This lets us get away with a single operator() overload, + // which makes overload resolution failure diagnostics more concise. template requires __adaptor_has_simple_extra_args<_Adaptor, _Args...> + && (is_trivially_copyable_v<_Args> && ...) struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure { tuple<_Args...> _M_args; @@ -926,6 +927,7 @@ namespace views::__adaptor // where _Adaptor accepts a single extra argument. template requires __adaptor_has_simple_extra_args<_Adaptor, _Arg> + && is_trivially_copyable_v<_Arg> struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure { _Arg _M_arg; diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc index 8ef084621f9..06be4980ddb 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc @@ -21,6 +21,7 @@ // PR libstdc++/100577 #include +#include namespace ranges = std::ranges; namespace views = std::ranges::views; @@ -113,4 +114,17 @@ test03() x | std::views::drop(S{}); } +void +test04() +{ + // Non-trivially-copyable extra arguments make a closure not simple. + using F = std::function; + static_assert(!std::is_trivially_copyable_v); + using views::__adaptor::__closure_has_simple_call_op; + static_assert(!__closure_has_simple_call_op()))>); + static_assert(!__closure_has_simple_call_op()))>); + static_assert(!__closure_has_simple_call_op()))>); + static_assert(!__closure_has_simple_call_op()))>); +} + // { dg-prune-output "in requirements" }