Chromium Code Reviews| Index: base/bind_internal.h |
| diff --git a/base/bind_internal.h b/base/bind_internal.h |
| index 4da13eed99d20a001e08c564f3fd7818d9549955..68ee48b3d4effa58bf7d6e043f4904079ed85aa6 100644 |
| --- a/base/bind_internal.h |
| +++ b/base/bind_internal.h |
| @@ -300,7 +300,7 @@ struct InvokeHelper; |
| template <typename ReturnType> |
| struct InvokeHelper<false, ReturnType> { |
| template <typename Runnable, typename... RunArgs> |
| - static ReturnType MakeItSo(Runnable&& runnable, RunArgs&&... args) { |
| + static inline ReturnType MakeItSo(Runnable&& runnable, RunArgs&&... args) { |
| return std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...); |
| } |
| }; |
| @@ -308,7 +308,7 @@ struct InvokeHelper<false, ReturnType> { |
| template <> |
| struct InvokeHelper<false, void> { |
| template <typename Runnable, typename... RunArgs> |
| - static void MakeItSo(Runnable&& runnable, RunArgs&&... args) { |
| + static inline void MakeItSo(Runnable&& runnable, RunArgs&&... args) { |
| std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...); |
| } |
| }; |
| @@ -316,9 +316,9 @@ struct InvokeHelper<false, void> { |
| template <> |
| struct InvokeHelper<true, void> { |
| template <typename Runnable, typename BoundWeakPtr, typename... RunArgs> |
| - static void MakeItSo(Runnable&& runnable, |
| - BoundWeakPtr weak_ptr, |
| - RunArgs&&... args) { |
| + static inline void MakeItSo(Runnable&& runnable, |
| + BoundWeakPtr weak_ptr, |
| + RunArgs&&... args) { |
| if (!weak_ptr.get()) { |
| return; |
| } |
| @@ -343,27 +343,38 @@ struct InvokeHelper<true, ReturnType> { |
| // Invoker<> |
| // |
| // See description at the top of the file. |
| -template <typename BoundIndices, typename StorageType, |
| - bool is_weak_call, typename UnboundForwardRunType> |
| +template <typename StorageType, typename UnboundRunType> |
| struct Invoker; |
| -template <size_t... bound_indices, |
| - typename StorageType, |
| - bool is_weak_call, |
| - typename R, |
| - typename... UnboundArgs> |
| -struct Invoker<IndexSequence<bound_indices...>, |
| - StorageType, |
| - is_weak_call, |
| - R(UnboundArgs...)> { |
| +template <typename StorageType, typename R, typename... UnboundArgs> |
| +struct Invoker<StorageType, 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. |
| + StorageType* storage = static_cast<StorageType*>(base); |
| + constexpr size_t num_bound_args = |
|
Yuta Kitamura
2016/06/23 07:22:45
nit: Add "static" since constexpr doesn't imply st
tzik
2016/06/23 08:16:10
Hmm, I think that does not make any diff in this c
|
| + std::tuple_size<decltype(storage->bound_args_)>::value; |
| + return RunImpl(storage->runnable_, |
| + storage->bound_args_, |
| + MakeIndexSequence<num_bound_args>(), |
| + std::forward<UnboundArgs>(unbound_args)...); |
| + } |
| + |
| + template <typename Runnable, typename BoundArgsTuple, size_t... indices> |
| + static inline R RunImpl(Runnable&& runnable, |
| + BoundArgsTuple&& bound, |
| + IndexSequence<indices...>, |
| + UnboundArgs&&... unbound_args) { |
| + constexpr bool is_method = |
| + HasIsMethodTag<typename std::decay<Runnable>::type>::value; |
| + constexpr bool is_weak_call = |
| + IsWeakMethod<is_method, |
| + typename std::decay<BoundArgsTuple>::type>::value; |
| + |
| return InvokeHelper<is_weak_call, R>::MakeItSo( |
| - storage->runnable_, |
| - Unwrap(std::get<bound_indices>(storage->bound_args_))..., |
| + std::forward<Runnable>(runnable), |
| + Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))..., |
| std::forward<UnboundArgs>(unbound_args)...); |
| } |
| }; |
| @@ -387,44 +398,40 @@ template <bool is_method, typename... BoundArgs> |
| using MakeArgsStorage = typename MakeArgsStorageImpl< |
| is_method, typename std::decay<BoundArgs>::type...>::Type; |
| +// Used to implement MakeUnboundRunType. |
| +template <typename Functor, typename... BoundArgs> |
| +struct MakeUnboundRunTypeImpl { |
| + using RunType = typename FunctorTraits<Functor>::RunType; |
| + using ReturnType = ExtractReturnType<RunType>; |
| + using Args = ExtractArgs<RunType>; |
| + using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), Args>; |
| + using Type = MakeFunctionType<ReturnType, UnboundArgs>; |
| +}; |
| + |
| +// Returns a RunType of bound functor. |
| +// E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C). |
| +template <typename Functor, typename... BoundArgs> |
| +using MakeUnboundRunType = |
| + typename MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type; |
| + |
| // BindState<> |
| // |
| // This stores all the state passed into Bind() and is also where most |
| // of the template resolution magic occurs. |
| // |
| // Runnable is the functor we are binding arguments to. |
| -// RunType is type of the Run() function that the Invoker<> should use. |
| -// Normally, this is the same as the RunType of the Runnable, but it can |
| -// be different if an adapter like IgnoreResult() has been used. |
| // |
| // BoundArgs contains the storage type for all the bound arguments. |
| -template <typename Runnable, typename RunType, typename... BoundArgs> |
| -struct BindState; |
| - |
| -template <typename Runnable, |
| - typename R, |
| - typename... Args, |
| - typename... BoundArgs> |
| -struct BindState<Runnable, R(Args...), BoundArgs...> final |
| - : public BindStateBase { |
| +template <typename Runnable, typename... BoundArgs> |
| +struct BindState final : public BindStateBase { |
| private: |
| - using StorageType = BindState<Runnable, R(Args...), BoundArgs...>; |
| using RunnableType = typename std::decay<Runnable>::type; |
| - enum { is_method = HasIsMethodTag<RunnableType>::value }; |
| - enum { is_weak_call = IsWeakMethod< |
| - is_method, typename std::decay<BoundArgs>::type...>::value}; |
| - |
| - using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>; |
| - using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>; |
| + static constexpr bool is_method = HasIsMethodTag<RunnableType>::value; |
| public: |
| - using UnboundRunType = MakeFunctionType<R, UnboundArgs>; |
| - using InvokerType = |
| - Invoker<BoundIndices, StorageType, is_weak_call, UnboundRunType>; |
| - |
| template <typename... ForwardArgs> |
| - BindState(RunnableType runnable, ForwardArgs&&... bound_args) |
| + explicit BindState(RunnableType runnable, ForwardArgs&&... bound_args) |
| : BindStateBase(&Destroy), |
| runnable_(std::move(runnable)), |
| bound_args_(std::forward<ForwardArgs>(bound_args)...) {} |