Support move-only type on base::Callback::Run
Change base::Callback<R(Args...)>::Run argument signature from
CallbackParamTraits<Args>::ForwardType to bare Arg, and forward the
arguments in the rest of the callchain to the bound function.
This implies making an extra copy when a pass-by-value argument of
Callback::Run() is a copyable-but-not-efficiently-movable types.
That is due to broken Perfect Forwarding from the callchain from
Callback::Run() to the bound function. However, Perfect Forwarding
idiom is not fully applicable to the callchain, since we have to
determine the type of a function pointer in the Callback ctor,
before Callback::Run() is called.
Also, this CL converts a copy construction to a move construction
when a pass-by-value argument of Callback::Run() is a general movable
type. E.g. std::string, std::map and others movable class without
DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND.
BUG=554299
Review URL: https://codereview.chromium.org/1709483002
Cr-Commit-Position: refs/heads/master@{#380080}
CrOS-Libchrome-Original-Commit: a43eff01d5024ee6722ebd637c30890681fbfe21
diff --git a/base/bind_internal.h b/base/bind_internal.h
index f296bbc..38a5756 100644
--- a/base/bind_internal.h
+++ b/base/bind_internal.h
@@ -339,19 +339,19 @@
typename StorageType,
typename InvokeHelperType,
typename R,
- typename... UnboundForwardArgs>
-struct Invoker<IndexSequence<bound_indices...>, StorageType,
- InvokeHelperType, R(UnboundForwardArgs...)> {
- static R Run(BindStateBase* base,
- UnboundForwardArgs... unbound_args) {
+ typename... UnboundArgs>
+struct Invoker<IndexSequence<bound_indices...>,
+ StorageType,
+ InvokeHelperType,
+ R(UnboundArgs...)> {
+ static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) {
StorageType* storage = static_cast<StorageType*>(base);
// Local references to make debugger stepping easier. If in a debugger,
// you really want to warp ahead and step through the
// InvokeHelper<>::MakeItSo() call below.
return InvokeHelperType::MakeItSo(
- storage->runnable_,
- Unwrap(get<bound_indices>(storage->bound_args_))...,
- CallbackForward(unbound_args)...);
+ storage->runnable_, Unwrap(get<bound_indices>(storage->bound_args_))...,
+ std::forward<UnboundArgs>(unbound_args)...);
}
};
@@ -406,18 +406,14 @@
IsWeakMethod<is_method, typename std::decay<BoundArgs>::type...>;
using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>;
- using UnboundForwardArgs = DropTypeListItem<
- sizeof...(BoundArgs),
- TypeList<typename CallbackParamTraits<Args>::ForwardType...>>;
- using UnboundForwardRunType = MakeFunctionType<R, UnboundForwardArgs>;
using InvokeHelperType = InvokeHelper<IsWeakCall::value, R, Runnable>;
using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>;
public:
- using InvokerType = Invoker<BoundIndices, StorageType,
- InvokeHelperType, UnboundForwardRunType>;
using UnboundRunType = MakeFunctionType<R, UnboundArgs>;
+ using InvokerType =
+ Invoker<BoundIndices, StorageType, InvokeHelperType, UnboundRunType>;
template <typename... ForwardArgs>
BindState(const Runnable& runnable, ForwardArgs&&... bound_args)