summaryrefslogtreecommitdiffstats
path: root/base/bind_internal.h.pump
diff options
context:
space:
mode:
Diffstat (limited to 'base/bind_internal.h.pump')
-rw-r--r--base/bind_internal.h.pump63
1 files changed, 58 insertions, 5 deletions
diff --git a/base/bind_internal.h.pump b/base/bind_internal.h.pump
index 4ccec5e..85875de 100644
--- a/base/bind_internal.h.pump
+++ b/base/bind_internal.h.pump
@@ -17,6 +17,7 @@ $var MAX_ARITY = 6
#include "base/bind_helpers.h"
#include "base/callback_internal.h"
+#include "base/memory/weak_ptr.h"
#include "base/template_util.h"
#include "build/build_config.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,31 @@ $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);
+ typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
+ if (!weak_ptr.get()) {
+ return;
+ }
+ (weak_ptr->*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,8 +275,25 @@ 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;
+ typedef Sig Signature;
+
+$for BOUND_ARG [[
+ typedef ParamTraits<P$(BOUND_ARG)> P$(BOUND_ARG)Traits;
+
+]]
+
+$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 [[