mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
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.
This commit is contained in:
@@ -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<typename _Adaptor, typename... _Args>
|
||||
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<typename _Adaptor, typename _Arg>
|
||||
requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
|
||||
&& is_trivially_copyable_v<_Arg>
|
||||
struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
|
||||
{
|
||||
_Arg _M_arg;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
// PR libstdc++/100577
|
||||
|
||||
#include <ranges>
|
||||
#include <functional>
|
||||
|
||||
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<bool(bool)>;
|
||||
static_assert(!std::is_trivially_copyable_v<F>);
|
||||
using views::__adaptor::__closure_has_simple_call_op;
|
||||
static_assert(!__closure_has_simple_call_op<decltype(views::take_while(std::declval<F>()))>);
|
||||
static_assert(!__closure_has_simple_call_op<decltype(views::drop_while(std::declval<F>()))>);
|
||||
static_assert(!__closure_has_simple_call_op<decltype(views::filter(std::declval<F>()))>);
|
||||
static_assert(!__closure_has_simple_call_op<decltype(views::transform(std::declval<F>()))>);
|
||||
}
|
||||
|
||||
// { dg-prune-output "in requirements" }
|
||||
|
||||
Reference in New Issue
Block a user