From: Patrick Palka Date: Thu, 17 Jun 2021 13:46:07 +0000 (-0400) Subject: libstdc++: Non-triv-copyable extra args aren't simple [PR100940] X-Git-Tag: upstream/12.2.0~7130 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2b87f3318cf6334a3a42dcf27f2fdec0fce04665;p=platform%2Fupstream%2Fgcc.git 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. --- diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index a428900..73c35da 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -896,11 +896,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; @@ -930,6 +931,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 8ef0846..06be498 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" }