| Index: base/bind_internal.h.pump
|
| diff --git a/base/bind_internal.h.pump b/base/bind_internal.h.pump
|
| index 4ccec5ebee10e3ebe85e0bc088bfbadb33e66d98..90528d7d9c725eb589323296674a84492545a4dc 100644
|
| --- a/base/bind_internal.h.pump
|
| +++ b/base/bind_internal.h.pump
|
| @@ -19,6 +19,7 @@ $var MAX_ARITY = 6
|
| #include "base/callback_internal.h"
|
| #include "base/template_util.h"
|
| #include "build/build_config.h"
|
| +#include "base/memory/weak_ptr.h"
|
|
|
| #if defined(OS_WIN)
|
| #include "base/bind_internal_win.h"
|
| @@ -42,10 +43,21 @@ namespace internal {
|
| // a calback.
|
| // InvokerStorageN<> -- Provides storage for the bound parameters, and
|
| // typedefs to the above.
|
| +// IsWeakMethod<> -- Determines if we are binding a method to a WeakPtr<>.
|
| //
|
| // More details about the design of each class is included in a comment closer
|
| // to their defition.
|
|
|
| +
|
| +// IsWeakMethod determines if we are binding a method to a WeakPtr<> for an
|
| +// object. It is used to select an InvokerN that will no-op itself in the
|
| +// event the WeakPtr<> for the target object is invalidated.
|
| +template <bool IsMethod, typename T>
|
| +struct IsWeakMethod : public false_type {};
|
| +
|
| +template <typename T>
|
| +struct IsWeakMethod<true, WeakPtr<T> > : public true_type {};
|
| +
|
| // FunctionTraits<>
|
| //
|
| // The FunctionTraits<> template determines the type of function, and also
|
| @@ -83,6 +95,8 @@ struct FunctionTraits<R(*)($for ARG , [[X$(ARG)]])> {
|
| typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]);
|
| typedef false_type IsMethod;
|
|
|
| + typedef R Return;
|
| +
|
| $if ARITY > 0 [[
|
|
|
| // Target type for each bound parameter.
|
| @@ -102,6 +116,8 @@ struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]])> {
|
| typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]);
|
| typedef true_type IsMethod;
|
|
|
| + typedef R Return;
|
| +
|
| // Target type for each bound parameter.
|
| typedef T B1;
|
|
|
| @@ -119,6 +135,8 @@ struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]]) const> {
|
| typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]);
|
| typedef true_type IsMethod;
|
|
|
| + typedef R Return;
|
| +
|
| // Target type for each bound parameter.
|
| typedef T B1;
|
|
|
| @@ -154,7 +172,7 @@ $for ARG [[
|
| $range BOUND 0..MAX_ARITY
|
| $for BOUND [[
|
|
|
| -template <typename StorageType, typename NormalizedSig>
|
| +template <bool IsWeak, typename StorageType, typename NormalizedSig>
|
| struct Invoker$(BOUND);
|
|
|
| $range ARITY 0..MAX_ARITY
|
| @@ -179,7 +197,7 @@ $range M_UNBOUND_ARG (M_ARITY - UNBOUND + 1)..M_ARITY
|
| template <typename StorageType, typename R[[]]
|
| $if ARITY > 0 [[,]][[]]
|
| $for ARG , [[typename X$(ARG)]]>
|
| -struct Invoker$(BOUND)<StorageType, R(*)($for ARG , [[X$(ARG)]])> {
|
| +struct Invoker$(BOUND)<false, StorageType, R(*)($for ARG , [[X$(ARG)]])> {
|
| static R DoInvoke(InvokerStorageBase* base[[]]
|
| $if UNBOUND != 0 [[, ]][[]]
|
| $for UNBOUND_ARG , [[typename internal::ParamTraits<X$(UNBOUND_ARG)>::ForwardType x$(UNBOUND_ARG)]]) {
|
| @@ -196,7 +214,7 @@ $if BOUND > 0 [[
|
| // Method: Arity $(M_ARITY) -> $(UNBOUND).
|
| template <typename StorageType, typename R, typename T[[]]
|
| $if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]>
|
| -struct Invoker$(BOUND)<StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]])> {
|
| +struct Invoker$(BOUND)<false, StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]])> {
|
| static R DoInvoke(InvokerStorageBase* base[[]]
|
| $if UNBOUND > 0 [[, ]][[]]
|
| $for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::ForwardType x$(M_UNBOUND_ARG)]]) {
|
| @@ -208,13 +226,30 @@ $for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]);
|
| }
|
| };
|
|
|
| +// WeakPtr Method: Arity $(M_ARITY) -> $(UNBOUND).
|
| +template <typename StorageType, typename T[[]]
|
| +$if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]>
|
| +struct Invoker$(BOUND)<true, StorageType, void(T::*)($for M_ARG , [[X$(M_ARG)]])> {
|
| + static void DoInvoke(InvokerStorageBase* base[[]]
|
| +$if UNBOUND > 0 [[, ]][[]]
|
| +$for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::ForwardType x$(M_UNBOUND_ARG)]]) {
|
| + StorageType* invoker = static_cast<StorageType*>(base);
|
| + if (!invoker->p1_.get()) {
|
| + return;
|
| + }
|
| + (invoker->p1_->*invoker->f_)([[]]
|
| +$for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]]
|
| +$if UNBOUND > 0 [[$if BOUND > 1 [[, ]]]][[]]
|
| +$for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]);
|
| + }
|
| +};
|
| +
|
| ]] $$ if BOUND
|
|
|
| ]] $$ if UNBOUND
|
| ]] $$ for ARITY
|
| ]] $$ for BOUND
|
|
|
| -
|
| // InvokerStorageN<>
|
| //
|
| // These are the actual storage classes for the Invokers.
|
| @@ -239,9 +274,20 @@ class InvokerStorage$(BOUND) : public InvokerStorageBase {
|
| public:
|
| typedef InvokerStorage$(BOUND) StorageType;
|
| typedef FunctionTraits<Sig> TargetTraits;
|
| - typedef Invoker$(BOUND)<StorageType, typename TargetTraits::NormalizedSig> Invoker;
|
| typedef typename TargetTraits::IsMethod IsMethod;
|
|
|
| +$if BOUND == 0 [[
|
| + typedef Invoker$(BOUND)<false, StorageType,
|
| + typename TargetTraits::NormalizedSig> Invoker;
|
| +]] $else [[
|
| + typedef Invoker$(BOUND)<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
|
| + typename TargetTraits::NormalizedSig> Invoker;
|
| + COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
|
| + is_void<typename TargetTraits::Return>::value,
|
| + weak_ptrs_can_only_bind_to_methods_without_return_values);
|
| +]]
|
| +
|
| +
|
| $for BOUND_ARG [[
|
| $if BOUND_ARG == 1 [[
|
|
|
|
|