diff options
Diffstat (limited to 'base/bind_internal.h')
-rw-r--r-- | base/bind_internal.h | 3585 |
1 files changed, 1769 insertions, 1816 deletions
diff --git a/base/bind_internal.h b/base/bind_internal.h index 7beba51..6c76d80 100644 --- a/base/bind_internal.h +++ b/base/bind_internal.h @@ -4,6 +4,12 @@ +// TODO(ajwong): If you create an fully unbound method, is there a way to +// enforce the first argument must be refcounted? Or do we just say +// "oh well"? +// +// Do we want to allow creating a fully unbound method?? + // Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -26,2167 +32,2114 @@ namespace base { namespace internal { -// The method by which a function is invoked is determined by 3 different -// dimensions: -// -// 1) The type of function (normal or method). -// 2) The arity of the function. -// 3) The number of bound parameters. +// CONCEPTS: +// Runnable -- A type (really a type class) that has a single Run() method +// and a RunType typedef that corresponds to the type of Run(). +// A Runnable can declare that it should treated like a method +// call by including a typedef named IsMethod. The value of +// this typedef is NOT inspected, only the existence. When a +// Runnable declares itself a method, Bind() will enforce special +// refcounting + WeakPtr handling semantics for the first +// parameter which is expected to be an object. +// Functor -- A copyable type representing something that should be called. +// All function pointers, Callback<>, and Runnables are functors +// even if the invocation syntax differs. +// RunType -- A function type (as opposed to function _pointer_ type) for +// a Run() function. Usually just a convenience typedef. +// (Bound)ArgsType -- A function type that is being (ab)used to store the +// types of set of arguments. The "return" type is always +// void here. We use this hack so that we do not need +// a new type name for each arity of type. (eg., +// BindState1, BindState2). This makes forward +// declarations and friending much much easier. // -// The templates below handle the determination of each of these dimensions. -// In brief: -// -// FunctionTraits<> -- Provides a normalied signature, and other traits. -// InvokerN<> -- Provides a DoInvoke() function that actually executes -// 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<> +// Types: +// RunnableAdapter<> -- Wraps the various "function" pointer types into an +// object that adheres to the Runnable interface. +// There are |3*ARITY| RunnableAdapter types. +// FunctionTraits<> -- Type traits that unwrap a function signature into a +// a set of easier to use typedefs. Used mainly for +// compile time asserts. +// There are |ARITY| FunctionTraits types. +// ForceVoidReturn<> -- Helper class for translating function signatures to +// equivalent forms with a "void" return type. +// There are |ARITY| ForceVoidReturn types. +// FunctorTraits<> -- Type traits used determine the correct RunType and +// RunnableType for a Functor. This is where function +// signature adapters are applied. +// There are |ARITY| ForceVoidReturn types. +// MakeRunnable<> -- Takes a Functor and returns an object in the Runnable +// type class that represents the underlying Functor. +// There are |O(1)| MakeRunnable types. +// InvokeHelper<> -- Take a Runnable + arguments and actully invokes it. +// Handle the differing syntaxes needed for WeakPtr<> support, +// and for ignoring return values. This is separate from +// Invoker to avoid creating multiple version of Invoker<> +// which grows at O(n^2) with the arity. +// There are |k*ARITY| InvokeHelper types. +// Invoker<> -- Unwraps the curried parameters and executes the Runnable. +// There are |(ARITY^2 + ARITY)/2| Invoketypes. +// BindState<> -- Stores the curried parameters, and is the main entry point +// into the Bind() system, doing most of the type resolution. +// There are ARITY BindState types. + + +// RunnableAdapter<> // -// The FunctionTraits<> template determines the type of function, and also -// creates a NormalizedType used to select the InvokerN classes. It turns out -// that syntactically, you only really have 2 variations when invoking a -// funciton pointer: normal, and method. One is invoked func_ptr(arg1). The -// other is invoked (*obj_->method_ptr(arg1)). +// The RunnableAdapter<> templates provide a uniform interface for invoking +// a function pointer, method pointer, or const method pointer. The adapter +// exposes a Run() method with an appropriate signature. Using this wrapper +// allows for writing code that supports all three pointer types without +// undue repetition. Without it, a lot of code would need to be repeated 3 +// times. // -// However, in the type system, there are many more distinctions. In standard -// C++, there's all variations of const, and volatile on the function pointer. -// In Windows, there are additional calling conventions (eg., __stdcall, -// __fastcall, etc.). FunctionTraits<> handles categorizing each of these into -// a normalized signature. +// For method pointers and const method pointers the first argument to Run() +// is considered to be the received of the method. This is similar to STL's +// mem_fun(). // -// Having a NormalizedSignature signature, reduces the combinatoric -// complexity of defintions for the InvokerN<> later. Even though there are -// only 2 syntactic variations on invoking a function, without normalizing the -// signature, there would need to be one specialization of InvokerN for each -// unique (function_type, bound_arg, unbound_args) tuple in order to match all -// function signatures. +// This class also exposes a RunType typedef that is the function type of the +// Run() function. // -// By normalizing the function signature, we reduce function_type to exactly 2. +// If and only if the wrapper contains a method or const method pointer, an +// IsMethod typedef is exposed. The existence of this typedef (NOT the value) +// marks that the wrapper should be considered a method wrapper. -template <typename Sig> -struct FunctionTraits; +template <typename Functor> +class RunnableAdapter; // Function: Arity 0. template <typename R> -struct FunctionTraits<R(*)()> { - typedef R (*NormalizedSig)(); - typedef false_type IsMethod; +class RunnableAdapter<R(*)()> { + public: + typedef R (RunType)(); + + explicit RunnableAdapter(R(*function)()) + : function_(function) { + } - typedef R Return; + R Run() { + return function_(); + } + private: + R (*function_)(); }; // Method: Arity 0. template <typename R, typename T> -struct FunctionTraits<R(T::*)()> { - typedef R (T::*NormalizedSig)(); +class RunnableAdapter<R(T::*)()> { + public: + typedef R (RunType)(T*); typedef true_type IsMethod; - typedef R Return; + explicit RunnableAdapter(R(T::*method)()) + : method_(method) { + } - // Target type for each bound parameter. - typedef T B1; + R Run(T* object) { + return (object->*method_)(); + } + private: + R (T::*method_)(); }; // Const Method: Arity 0. template <typename R, typename T> -struct FunctionTraits<R(T::*)() const> { - typedef R (T::*NormalizedSig)(); +class RunnableAdapter<R(T::*)() const> { + public: + typedef R (RunType)(const T*); typedef true_type IsMethod; - typedef R Return; + explicit RunnableAdapter(R(T::*method)() const) + : method_(method) { + } - // Target type for each bound parameter. - typedef T B1; + R Run(const T* object) { + return (object->*method_)(); + } + private: + R (T::*method_)() const; }; // Function: Arity 1. -template <typename R, typename X1> -struct FunctionTraits<R(*)(X1)> { - typedef R (*NormalizedSig)(X1); - typedef false_type IsMethod; +template <typename R, typename A1> +class RunnableAdapter<R(*)(A1)> { + public: + typedef R (RunType)(A1); - typedef R Return; + explicit RunnableAdapter(R(*function)(A1)) + : function_(function) { + } - // Target type for each bound parameter. - typedef X1 B1; + R Run(typename CallbackParamTraits<A1>::ForwardType a1) { + return function_(a1); + } + private: + R (*function_)(A1); }; // Method: Arity 1. -template <typename R, typename T, typename X1> -struct FunctionTraits<R(T::*)(X1)> { - typedef R (T::*NormalizedSig)(X1); +template <typename R, typename T, typename A1> +class RunnableAdapter<R(T::*)(A1)> { + public: + typedef R (RunType)(T*, A1); typedef true_type IsMethod; - typedef R Return; + explicit RunnableAdapter(R(T::*method)(A1)) + : method_(method) { + } - // Target type for each bound parameter. - typedef T B1; - typedef X1 B2; + R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1) { + return (object->*method_)(a1); + } + private: + R (T::*method_)(A1); }; // Const Method: Arity 1. -template <typename R, typename T, typename X1> -struct FunctionTraits<R(T::*)(X1) const> { - typedef R (T::*NormalizedSig)(X1); +template <typename R, typename T, typename A1> +class RunnableAdapter<R(T::*)(A1) const> { + public: + typedef R (RunType)(const T*, A1); typedef true_type IsMethod; - typedef R Return; + explicit RunnableAdapter(R(T::*method)(A1) const) + : method_(method) { + } - // Target type for each bound parameter. - typedef T B1; - typedef X1 B2; + R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1) { + return (object->*method_)(a1); + } + private: + R (T::*method_)(A1) const; }; // Function: Arity 2. -template <typename R, typename X1, typename X2> -struct FunctionTraits<R(*)(X1, X2)> { - typedef R (*NormalizedSig)(X1, X2); - typedef false_type IsMethod; +template <typename R, typename A1, typename A2> +class RunnableAdapter<R(*)(A1, A2)> { + public: + typedef R (RunType)(A1, A2); - typedef R Return; + explicit RunnableAdapter(R(*function)(A1, A2)) + : function_(function) { + } - // Target type for each bound parameter. - typedef X1 B1; - typedef X2 B2; + R Run(typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2) { + return function_(a1, a2); + } + private: + R (*function_)(A1, A2); }; // Method: Arity 2. -template <typename R, typename T, typename X1, typename X2> -struct FunctionTraits<R(T::*)(X1, X2)> { - typedef R (T::*NormalizedSig)(X1, X2); +template <typename R, typename T, typename A1, typename A2> +class RunnableAdapter<R(T::*)(A1, A2)> { + public: + typedef R (RunType)(T*, A1, A2); typedef true_type IsMethod; - typedef R Return; + explicit RunnableAdapter(R(T::*method)(A1, A2)) + : method_(method) { + } - // Target type for each bound parameter. - typedef T B1; - typedef X1 B2; - typedef X2 B3; + R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2) { + return (object->*method_)(a1, a2); + } + private: + R (T::*method_)(A1, A2); }; // Const Method: Arity 2. -template <typename R, typename T, typename X1, typename X2> -struct FunctionTraits<R(T::*)(X1, X2) const> { - typedef R (T::*NormalizedSig)(X1, X2); +template <typename R, typename T, typename A1, typename A2> +class RunnableAdapter<R(T::*)(A1, A2) const> { + public: + typedef R (RunType)(const T*, A1, A2); typedef true_type IsMethod; - typedef R Return; + explicit RunnableAdapter(R(T::*method)(A1, A2) const) + : method_(method) { + } - // Target type for each bound parameter. - typedef T B1; - typedef X1 B2; - typedef X2 B3; + R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2) { + return (object->*method_)(a1, a2); + } + private: + R (T::*method_)(A1, A2) const; }; // Function: Arity 3. -template <typename R, typename X1, typename X2, typename X3> -struct FunctionTraits<R(*)(X1, X2, X3)> { - typedef R (*NormalizedSig)(X1, X2, X3); - typedef false_type IsMethod; +template <typename R, typename A1, typename A2, typename A3> +class RunnableAdapter<R(*)(A1, A2, A3)> { + public: + typedef R (RunType)(A1, A2, A3); - typedef R Return; + explicit RunnableAdapter(R(*function)(A1, A2, A3)) + : function_(function) { + } - // Target type for each bound parameter. - typedef X1 B1; - typedef X2 B2; - typedef X3 B3; + R Run(typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2, + typename CallbackParamTraits<A3>::ForwardType a3) { + return function_(a1, a2, a3); + } + private: + R (*function_)(A1, A2, A3); }; // Method: Arity 3. -template <typename R, typename T, typename X1, typename X2, typename X3> -struct FunctionTraits<R(T::*)(X1, X2, X3)> { - typedef R (T::*NormalizedSig)(X1, X2, X3); +template <typename R, typename T, typename A1, typename A2, typename A3> +class RunnableAdapter<R(T::*)(A1, A2, A3)> { + public: + typedef R (RunType)(T*, A1, A2, A3); typedef true_type IsMethod; - typedef R Return; + explicit RunnableAdapter(R(T::*method)(A1, A2, A3)) + : method_(method) { + } - // Target type for each bound parameter. - typedef T B1; - typedef X1 B2; - typedef X2 B3; - typedef X3 B4; + R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2, + typename CallbackParamTraits<A3>::ForwardType a3) { + return (object->*method_)(a1, a2, a3); + } + private: + R (T::*method_)(A1, A2, A3); }; // Const Method: Arity 3. -template <typename R, typename T, typename X1, typename X2, typename X3> -struct FunctionTraits<R(T::*)(X1, X2, X3) const> { - typedef R (T::*NormalizedSig)(X1, X2, X3); +template <typename R, typename T, typename A1, typename A2, typename A3> +class RunnableAdapter<R(T::*)(A1, A2, A3) const> { + public: + typedef R (RunType)(const T*, A1, A2, A3); typedef true_type IsMethod; - typedef R Return; + explicit RunnableAdapter(R(T::*method)(A1, A2, A3) const) + : method_(method) { + } - // Target type for each bound parameter. - typedef T B1; - typedef X1 B2; - typedef X2 B3; - typedef X3 B4; + R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2, + typename CallbackParamTraits<A3>::ForwardType a3) { + return (object->*method_)(a1, a2, a3); + } + private: + R (T::*method_)(A1, A2, A3) const; }; // Function: Arity 4. -template <typename R, typename X1, typename X2, typename X3, typename X4> -struct FunctionTraits<R(*)(X1, X2, X3, X4)> { - typedef R (*NormalizedSig)(X1, X2, X3, X4); - typedef false_type IsMethod; +template <typename R, typename A1, typename A2, typename A3, typename A4> +class RunnableAdapter<R(*)(A1, A2, A3, A4)> { + public: + typedef R (RunType)(A1, A2, A3, A4); - typedef R Return; + explicit RunnableAdapter(R(*function)(A1, A2, A3, A4)) + : function_(function) { + } - // Target type for each bound parameter. - typedef X1 B1; - typedef X2 B2; - typedef X3 B3; - typedef X4 B4; + R Run(typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2, + typename CallbackParamTraits<A3>::ForwardType a3, + typename CallbackParamTraits<A4>::ForwardType a4) { + return function_(a1, a2, a3, a4); + } + private: + R (*function_)(A1, A2, A3, A4); }; // Method: Arity 4. -template <typename R, typename T, typename X1, typename X2, typename X3, - typename X4> -struct FunctionTraits<R(T::*)(X1, X2, X3, X4)> { - typedef R (T::*NormalizedSig)(X1, X2, X3, X4); +template <typename R, typename T, typename A1, typename A2, typename A3, + typename A4> +class RunnableAdapter<R(T::*)(A1, A2, A3, A4)> { + public: + typedef R (RunType)(T*, A1, A2, A3, A4); typedef true_type IsMethod; - typedef R Return; + explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4)) + : method_(method) { + } - // Target type for each bound parameter. - typedef T B1; - typedef X1 B2; - typedef X2 B3; - typedef X3 B4; - typedef X4 B5; + R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2, + typename CallbackParamTraits<A3>::ForwardType a3, + typename CallbackParamTraits<A4>::ForwardType a4) { + return (object->*method_)(a1, a2, a3, a4); + } + private: + R (T::*method_)(A1, A2, A3, A4); }; // Const Method: Arity 4. -template <typename R, typename T, typename X1, typename X2, typename X3, - typename X4> -struct FunctionTraits<R(T::*)(X1, X2, X3, X4) const> { - typedef R (T::*NormalizedSig)(X1, X2, X3, X4); +template <typename R, typename T, typename A1, typename A2, typename A3, + typename A4> +class RunnableAdapter<R(T::*)(A1, A2, A3, A4) const> { + public: + typedef R (RunType)(const T*, A1, A2, A3, A4); typedef true_type IsMethod; - typedef R Return; + explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4) const) + : method_(method) { + } - // Target type for each bound parameter. - typedef T B1; - typedef X1 B2; - typedef X2 B3; - typedef X3 B4; - typedef X4 B5; + R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2, + typename CallbackParamTraits<A3>::ForwardType a3, + typename CallbackParamTraits<A4>::ForwardType a4) { + return (object->*method_)(a1, a2, a3, a4); + } + private: + R (T::*method_)(A1, A2, A3, A4) const; }; // Function: Arity 5. -template <typename R, typename X1, typename X2, typename X3, typename X4, - typename X5> -struct FunctionTraits<R(*)(X1, X2, X3, X4, X5)> { - typedef R (*NormalizedSig)(X1, X2, X3, X4, X5); - typedef false_type IsMethod; +template <typename R, typename A1, typename A2, typename A3, typename A4, + typename A5> +class RunnableAdapter<R(*)(A1, A2, A3, A4, A5)> { + public: + typedef R (RunType)(A1, A2, A3, A4, A5); - typedef R Return; + explicit RunnableAdapter(R(*function)(A1, A2, A3, A4, A5)) + : function_(function) { + } - // Target type for each bound parameter. - typedef X1 B1; - typedef X2 B2; - typedef X3 B3; - typedef X4 B4; - typedef X5 B5; + R Run(typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2, + typename CallbackParamTraits<A3>::ForwardType a3, + typename CallbackParamTraits<A4>::ForwardType a4, + typename CallbackParamTraits<A5>::ForwardType a5) { + return function_(a1, a2, a3, a4, a5); + } + private: + R (*function_)(A1, A2, A3, A4, A5); }; // Method: Arity 5. -template <typename R, typename T, typename X1, typename X2, typename X3, - typename X4, typename X5> -struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5)> { - typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5); +template <typename R, typename T, typename A1, typename A2, typename A3, + typename A4, typename A5> +class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5)> { + public: + typedef R (RunType)(T*, A1, A2, A3, A4, A5); typedef true_type IsMethod; - typedef R Return; + explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4, A5)) + : method_(method) { + } - // Target type for each bound parameter. - typedef T B1; - typedef X1 B2; - typedef X2 B3; - typedef X3 B4; - typedef X4 B5; - typedef X5 B6; + R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2, + typename CallbackParamTraits<A3>::ForwardType a3, + typename CallbackParamTraits<A4>::ForwardType a4, + typename CallbackParamTraits<A5>::ForwardType a5) { + return (object->*method_)(a1, a2, a3, a4, a5); + } + private: + R (T::*method_)(A1, A2, A3, A4, A5); }; // Const Method: Arity 5. -template <typename R, typename T, typename X1, typename X2, typename X3, - typename X4, typename X5> -struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5) const> { - typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5); +template <typename R, typename T, typename A1, typename A2, typename A3, + typename A4, typename A5> +class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5) const> { + public: + typedef R (RunType)(const T*, A1, A2, A3, A4, A5); typedef true_type IsMethod; - typedef R Return; + explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4, A5) const) + : method_(method) { + } - // Target type for each bound parameter. - typedef T B1; - typedef X1 B2; - typedef X2 B3; - typedef X3 B4; - typedef X4 B5; - typedef X5 B6; + R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2, + typename CallbackParamTraits<A3>::ForwardType a3, + typename CallbackParamTraits<A4>::ForwardType a4, + typename CallbackParamTraits<A5>::ForwardType a5) { + return (object->*method_)(a1, a2, a3, a4, a5); + } + private: + R (T::*method_)(A1, A2, A3, A4, A5) const; }; // Function: Arity 6. -template <typename R, typename X1, typename X2, typename X3, typename X4, - typename X5, typename X6> -struct FunctionTraits<R(*)(X1, X2, X3, X4, X5, X6)> { - typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6); - typedef false_type IsMethod; +template <typename R, typename A1, typename A2, typename A3, typename A4, + typename A5, typename A6> +class RunnableAdapter<R(*)(A1, A2, A3, A4, A5, A6)> { + public: + typedef R (RunType)(A1, A2, A3, A4, A5, A6); - typedef R Return; + explicit RunnableAdapter(R(*function)(A1, A2, A3, A4, A5, A6)) + : function_(function) { + } - // Target type for each bound parameter. - typedef X1 B1; - typedef X2 B2; - typedef X3 B3; - typedef X4 B4; - typedef X5 B5; - typedef X6 B6; + R Run(typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2, + typename CallbackParamTraits<A3>::ForwardType a3, + typename CallbackParamTraits<A4>::ForwardType a4, + typename CallbackParamTraits<A5>::ForwardType a5, + typename CallbackParamTraits<A6>::ForwardType a6) { + return function_(a1, a2, a3, a4, a5, a6); + } + private: + R (*function_)(A1, A2, A3, A4, A5, A6); }; // Method: Arity 6. -template <typename R, typename T, typename X1, typename X2, typename X3, - typename X4, typename X5, typename X6> -struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6)> { - typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6); +template <typename R, typename T, typename A1, typename A2, typename A3, + typename A4, typename A5, typename A6> +class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5, A6)> { + public: + typedef R (RunType)(T*, A1, A2, A3, A4, A5, A6); typedef true_type IsMethod; - typedef R Return; + explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4, A5, A6)) + : method_(method) { + } - // Target type for each bound parameter. - typedef T B1; - typedef X1 B2; - typedef X2 B3; - typedef X3 B4; - typedef X4 B5; - typedef X5 B6; - typedef X6 B7; + R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2, + typename CallbackParamTraits<A3>::ForwardType a3, + typename CallbackParamTraits<A4>::ForwardType a4, + typename CallbackParamTraits<A5>::ForwardType a5, + typename CallbackParamTraits<A6>::ForwardType a6) { + return (object->*method_)(a1, a2, a3, a4, a5, a6); + } + private: + R (T::*method_)(A1, A2, A3, A4, A5, A6); }; // Const Method: Arity 6. -template <typename R, typename T, typename X1, typename X2, typename X3, - typename X4, typename X5, typename X6> -struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6) const> { - typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6); +template <typename R, typename T, typename A1, typename A2, typename A3, + typename A4, typename A5, typename A6> +class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5, A6) const> { + public: + typedef R (RunType)(const T*, A1, A2, A3, A4, A5, A6); typedef true_type IsMethod; - typedef R Return; + explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4, A5, A6) const) + : method_(method) { + } - // Target type for each bound parameter. - typedef T B1; - typedef X1 B2; - typedef X2 B3; - typedef X3 B4; - typedef X4 B5; - typedef X5 B6; - typedef X6 B7; + R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1, + typename CallbackParamTraits<A2>::ForwardType a2, + typename CallbackParamTraits<A3>::ForwardType a3, + typename CallbackParamTraits<A4>::ForwardType a4, + typename CallbackParamTraits<A5>::ForwardType a5, + typename CallbackParamTraits<A6>::ForwardType a6) { + return (object->*method_)(a1, a2, a3, a4, a5, a6); + } + private: + R (T::*method_)(A1, A2, A3, A4, A5, A6) const; }; -// InvokerN<> -// -// The InvokerN templates contain a static DoInvoke() function that is the key -// to implementing type erasure in the Callback() classes. -// -// DoInvoke() is a static function with a fixed signature that is independent -// of StorageType; its first argument is a pointer to the non-templated common -// baseclass of StorageType. This lets us store pointer to DoInvoke() in a -// function pointer that has knowledge of the specific StorageType, and thus -// no knowledge of the bound function and bound parameter types. -// -// As long as we ensure that DoInvoke() is only used with pointers there were -// upcasted from the correct StorageType, we can be sure that execution is -// safe. + +// FunctionTraits<> // -// The InvokerN templates are the only point that knows the number of bound -// and unbound arguments. This is intentional because it allows the other -// templates classes in the system to only have as many specializations as -// the max arity of function we wish to support. +// Breaks a function signature apart into typedefs for easier introspection. +template <typename Sig> +struct FunctionTraits; -template <bool IsWeak, typename StorageType, typename NormalizedSig> -struct Invoker0; +template <typename R> +struct FunctionTraits<R()> { + typedef R ReturnType; +}; -// Function: Arity 0 -> 0. -template <typename StorageType, typename R> -struct Invoker0<false, StorageType, R(*)()> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*); +template <typename R, typename A1> +struct FunctionTraits<R(A1)> { + typedef R ReturnType; + typedef A1 A1Type; +}; - static R DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(); - } +template <typename R, typename A1, typename A2> +struct FunctionTraits<R(A1, A2)> { + typedef R ReturnType; + typedef A1 A1Type; + typedef A2 A2Type; }; -// Function: Arity 1 -> 1. -template <typename StorageType, typename R,typename X1> -struct Invoker0<false, StorageType, R(*)(X1)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType); +template <typename R, typename A1, typename A2, typename A3> +struct FunctionTraits<R(A1, A2, A3)> { + typedef R ReturnType; + typedef A1 A1Type; + typedef A2 A2Type; + typedef A3 A3Type; +}; - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(x1); - } +template <typename R, typename A1, typename A2, typename A3, typename A4> +struct FunctionTraits<R(A1, A2, A3, A4)> { + typedef R ReturnType; + typedef A1 A1Type; + typedef A2 A2Type; + typedef A3 A3Type; + typedef A4 A4Type; }; -// Function: Arity 2 -> 2. -template <typename StorageType, typename R,typename X1, typename X2> -struct Invoker0<false, StorageType, R(*)(X1, X2)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType, - typename internal::ParamTraits<X2>::ForwardType); +template <typename R, typename A1, typename A2, typename A3, typename A4, + typename A5> +struct FunctionTraits<R(A1, A2, A3, A4, A5)> { + typedef R ReturnType; + typedef A1 A1Type; + typedef A2 A2Type; + typedef A3 A3Type; + typedef A4 A4Type; + typedef A5 A5Type; +}; - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1, - typename internal::ParamTraits<X2>::ForwardType x2) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(x1, x2); - } +template <typename R, typename A1, typename A2, typename A3, typename A4, + typename A5, typename A6> +struct FunctionTraits<R(A1, A2, A3, A4, A5, A6)> { + typedef R ReturnType; + typedef A1 A1Type; + typedef A2 A2Type; + typedef A3 A3Type; + typedef A4 A4Type; + typedef A5 A5Type; + typedef A6 A6Type; }; -// Function: Arity 3 -> 3. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3> -struct Invoker0<false, StorageType, R(*)(X1, X2, X3)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType); - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(x1, x2, x3); - } +// ForceVoidReturn<> +// +// Set of templates that support forcing the function return type to void. +template <typename Sig> +struct ForceVoidReturn; + +template <typename R> +struct ForceVoidReturn<R()> { + typedef void(RunType)(); }; -// Function: Arity 4 -> 4. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4> -struct Invoker0<false, StorageType, R(*)(X1, X2, X3, X4)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType); +template <typename R, typename A1> +struct ForceVoidReturn<R(A1)> { + typedef void(RunType)(A1); +}; - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(x1, x2, x3, x4); - } +template <typename R, typename A1, typename A2> +struct ForceVoidReturn<R(A1, A2)> { + typedef void(RunType)(A1, A2); }; -// Function: Arity 5 -> 5. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker0<false, StorageType, R(*)(X1, X2, X3, X4, X5)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(x1, x2, x3, x4, x5); - } -}; - -// Function: Arity 6 -> 6. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6> -struct Invoker0<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType, - typename internal::ParamTraits<X6>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5, - typename internal::ParamTraits<X6>::ForwardType x6) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(x1, x2, x3, x4, x5, x6); - } -}; - -template <bool IsWeak, typename StorageType, typename NormalizedSig> -struct Invoker1; - -// Function: Arity 1 -> 0. -template <typename StorageType, typename R,typename X1> -struct Invoker1<false, StorageType, R(*)(X1)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*); +template <typename R, typename A1, typename A2, typename A3> +struct ForceVoidReturn<R(A1, A2, A3)> { + typedef void(RunType)(A1, A2, A3); +}; - static R DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_)); - } +template <typename R, typename A1, typename A2, typename A3, typename A4> +struct ForceVoidReturn<R(A1, A2, A3, A4)> { + typedef void(RunType)(A1, A2, A3, A4); }; -// Method: Arity 0 -> 0. -template <typename StorageType, typename R, typename T> -struct Invoker1<false, StorageType, R(T::*)()> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*); +template <typename R, typename A1, typename A2, typename A3, typename A4, + typename A5> +struct ForceVoidReturn<R(A1, A2, A3, A4, A5)> { + typedef void(RunType)(A1, A2, A3, A4, A5); +}; - static R DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(); - } +template <typename R, typename A1, typename A2, typename A3, typename A4, + typename A5, typename A6> +struct ForceVoidReturn<R(A1, A2, A3, A4, A5, A6)> { + typedef void(RunType)(A1, A2, A3, A4, A5, A6); }; -// WeakPtr Method: Arity 0 -> 0. -template <typename StorageType, typename T> -struct Invoker1<true, StorageType, void(T::*)()> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*); - static void DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(); - } +// FunctorTraits<> +// +// See description at top of file. +template <typename T> +struct FunctorTraits { + typedef RunnableAdapter<T> RunnableType; + typedef typename RunnableType::RunType RunType; }; -// Function: Arity 2 -> 1. -template <typename StorageType, typename R,typename X1, typename X2> -struct Invoker1<false, StorageType, R(*)(X1, X2)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X2>::ForwardType); +template <typename T> +struct FunctorTraits<IgnoreResultHelper<T> > { + typedef typename FunctorTraits<T>::RunnableType RunnableType; + typedef typename ForceVoidReturn< + typename RunnableType::RunType>::RunType RunType; +}; - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X2>::ForwardType x2) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), x2); - } +template <typename T> +struct FunctorTraits<Callback<T> > { + typedef Callback<T> RunnableType; + typedef typename Callback<T>::RunType RunType; }; -// Method: Arity 1 -> 1. -template <typename StorageType, typename R, typename T, typename X1> -struct Invoker1<false, StorageType, R(T::*)(X1)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType); - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(x1); - } -}; +// MakeRunnable<> +// +// Converts a passed in functor to a RunnableType using type inference. -// WeakPtr Method: Arity 1 -> 1. -template <typename StorageType, typename T, typename X1> -struct Invoker1<true, StorageType, void(T::*)(X1)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType); +template <typename T> +typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) { + return RunnableAdapter<T>(t); +} - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(x1); +template <typename T> +typename FunctorTraits<T>::RunnableType +MakeRunnable(const IgnoreResultHelper<T>& t) { + return MakeRunnable(t.functor_); +} + +template <typename T> +const typename FunctorTraits<Callback<T> >::RunnableType& +MakeRunnable(const Callback<T>& t) { + return t; +} + + +// InvokeHelper<> +// +// There are 3 logical InvokeHelper<> specializations: normal, void-return, +// WeakCalls. +// +// The normal type just calls the underlying runnable. +// +// We need a InvokeHelper to handle void return types in order to support +// IgnoreResult(). Normally, if the Runnable's RunType had a void return, +// the template system would just accept "return functor.Run()" ignoring +// the fact that a void function is being used with return. This piece of +// sugar breaks though when the Runnable's RunType is not void. Thus, we +// need a partial specialization to change the syntax to drop the "return" +// from the invocation call. +// +// WeakCalls similarly need special syntax that is applied to the first +// argument to check if they should no-op themselves. +template <bool IsWeakCall, typename ReturnType, typename Runnable, + typename ArgsType> +struct InvokeHelper; + +template <typename ReturnType, typename Runnable> +struct InvokeHelper<false, ReturnType, Runnable, + void()> { + static ReturnType MakeItSo(Runnable runnable) { + return runnable.Run(); } }; -// Function: Arity 3 -> 2. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3> -struct Invoker1<false, StorageType, R(*)(X1, X2, X3)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), x2, x3); - } -}; - -// Method: Arity 2 -> 2. -template <typename StorageType, typename R, typename T, typename X1, - typename X2> -struct Invoker1<false, StorageType, R(T::*)(X1, X2)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType, - typename internal::ParamTraits<X2>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1, - typename internal::ParamTraits<X2>::ForwardType x2) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2); - } -}; - -// WeakPtr Method: Arity 2 -> 2. -template <typename StorageType, typename T, typename X1, typename X2> -struct Invoker1<true, StorageType, void(T::*)(X1, X2)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType, - typename internal::ParamTraits<X2>::ForwardType); - - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1, - typename internal::ParamTraits<X2>::ForwardType x2) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(x1, x2); +template <typename Runnable> +struct InvokeHelper<false, void, Runnable, + void()> { + static void MakeItSo(Runnable runnable) { + runnable.Run(); } }; -// Function: Arity 4 -> 3. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4> -struct Invoker1<false, StorageType, R(*)(X1, X2, X3, X4)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4); - } -}; - -// Method: Arity 3 -> 3. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3> -struct Invoker1<false, StorageType, R(T::*)(X1, X2, X3)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3); - } -}; - -// WeakPtr Method: Arity 3 -> 3. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3> -struct Invoker1<true, StorageType, void(T::*)(X1, X2, X3)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType); - - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(x1, x2, x3); +template <typename ReturnType, typename Runnable,typename A1> +struct InvokeHelper<false, ReturnType, Runnable, + void(A1)> { + static ReturnType MakeItSo(Runnable runnable, A1 a1) { + return runnable.Run(a1); } }; -// Function: Arity 5 -> 4. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker1<false, StorageType, R(*)(X1, X2, X3, X4, X5)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4, x5); - } -}; - -// Method: Arity 4 -> 4. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3, typename X4> -struct Invoker1<false, StorageType, R(T::*)(X1, X2, X3, X4)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3, x4); - } -}; - -// WeakPtr Method: Arity 4 -> 4. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3, typename X4> -struct Invoker1<true, StorageType, void(T::*)(X1, X2, X3, X4)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType); - - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(x1, x2, x3, x4); +template <typename Runnable,typename A1> +struct InvokeHelper<false, void, Runnable, + void(A1)> { + static void MakeItSo(Runnable runnable, A1 a1) { + runnable.Run(a1); } }; -// Function: Arity 6 -> 5. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6> -struct Invoker1<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType, - typename internal::ParamTraits<X6>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5, - typename internal::ParamTraits<X6>::ForwardType x6) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4, x5, x6); - } -}; - -// Method: Arity 5 -> 5. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3, typename X4, typename X5> -struct Invoker1<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3, x4, x5); - } -}; - -// WeakPtr Method: Arity 5 -> 5. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker1<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X1>::ForwardType, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType); - - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X1>::ForwardType x1, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { +template <typename Runnable, typename A1> +struct InvokeHelper<true, void, Runnable, + void(A1)> { + static void MakeItSo(Runnable runnable, A1 a1) { + if (!a1.get()) { return; } - (weak_ptr->*invoker->f_)(x1, x2, x3, x4, x5); + + runnable.Run(a1); } }; -template <bool IsWeak, typename StorageType, typename NormalizedSig> -struct Invoker2; - -// Function: Arity 2 -> 0. -template <typename StorageType, typename R,typename X1, typename X2> -struct Invoker2<false, StorageType, R(*)(X1, X2)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*); - - static R DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_)); +template <typename ReturnType, typename Runnable,typename A1, typename A2> +struct InvokeHelper<false, ReturnType, Runnable, + void(A1, A2)> { + static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2) { + return runnable.Run(a1, a2); } }; -// Method: Arity 1 -> 0. -template <typename StorageType, typename R, typename T, typename X1> -struct Invoker2<false, StorageType, R(T::*)(X1)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*); - - static R DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_)); +template <typename Runnable,typename A1, typename A2> +struct InvokeHelper<false, void, Runnable, + void(A1, A2)> { + static void MakeItSo(Runnable runnable, A1 a1, A2 a2) { + runnable.Run(a1, a2); } }; -// WeakPtr Method: Arity 1 -> 0. -template <typename StorageType, typename T, typename X1> -struct Invoker2<true, StorageType, void(T::*)(X1)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*); - - static void DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { +template <typename Runnable, typename A1, typename A2> +struct InvokeHelper<true, void, Runnable, + void(A1, A2)> { + static void MakeItSo(Runnable runnable, A1 a1, A2 a2) { + if (!a1.get()) { return; } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_)); + + runnable.Run(a1, a2); } }; -// Function: Arity 3 -> 1. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3> -struct Invoker2<false, StorageType, R(*)(X1, X2, X3)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X3>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X3>::ForwardType x3) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3); +template <typename ReturnType, typename Runnable,typename A1, typename A2, + typename A3> +struct InvokeHelper<false, ReturnType, Runnable, + void(A1, A2, A3)> { + static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3) { + return runnable.Run(a1, a2, a3); } }; -// Method: Arity 2 -> 1. -template <typename StorageType, typename R, typename T, typename X1, - typename X2> -struct Invoker2<false, StorageType, R(T::*)(X1, X2)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X2>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X2>::ForwardType x2) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2); +template <typename Runnable,typename A1, typename A2, typename A3> +struct InvokeHelper<false, void, Runnable, + void(A1, A2, A3)> { + static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3) { + runnable.Run(a1, a2, a3); } }; -// WeakPtr Method: Arity 2 -> 1. -template <typename StorageType, typename T, typename X1, typename X2> -struct Invoker2<true, StorageType, void(T::*)(X1, X2)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X2>::ForwardType); - - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X2>::ForwardType x2) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { +template <typename Runnable, typename A1, typename A2, typename A3> +struct InvokeHelper<true, void, Runnable, + void(A1, A2, A3)> { + static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3) { + if (!a1.get()) { return; } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), x2); - } -}; -// Function: Arity 4 -> 2. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4> -struct Invoker2<false, StorageType, R(*)(X1, X2, X3, X4)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4); + runnable.Run(a1, a2, a3); } }; -// Method: Arity 3 -> 2. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3> -struct Invoker2<false, StorageType, R(T::*)(X1, X2, X3)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3); +template <typename ReturnType, typename Runnable,typename A1, typename A2, + typename A3, typename A4> +struct InvokeHelper<false, ReturnType, Runnable, + void(A1, A2, A3, A4)> { + static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4) { + return runnable.Run(a1, a2, a3, a4); } }; -// WeakPtr Method: Arity 3 -> 2. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3> -struct Invoker2<true, StorageType, void(T::*)(X1, X2, X3)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType); - - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), x2, x3); +template <typename Runnable,typename A1, typename A2, typename A3, typename A4> +struct InvokeHelper<false, void, Runnable, + void(A1, A2, A3, A4)> { + static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4) { + runnable.Run(a1, a2, a3, a4); } }; -// Function: Arity 5 -> 3. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker2<false, StorageType, R(*)(X1, X2, X3, X4, X5)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4, x5); - } -}; - -// Method: Arity 4 -> 3. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3, typename X4> -struct Invoker2<false, StorageType, R(T::*)(X1, X2, X3, X4)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3, - x4); - } -}; - -// WeakPtr Method: Arity 4 -> 3. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3, typename X4> -struct Invoker2<true, StorageType, void(T::*)(X1, X2, X3, X4)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType); - - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { +template <typename Runnable, typename A1, typename A2, typename A3, typename A4> +struct InvokeHelper<true, void, Runnable, + void(A1, A2, A3, A4)> { + static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4) { + if (!a1.get()) { return; } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), x2, x3, x4); - } -}; -// Function: Arity 6 -> 4. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6> -struct Invoker2<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType, - typename internal::ParamTraits<X6>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5, - typename internal::ParamTraits<X6>::ForwardType x6) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4, x5, - x6); - } -}; - -// Method: Arity 5 -> 4. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3, typename X4, typename X5> -struct Invoker2<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3, - x4, x5); - } -}; - -// WeakPtr Method: Arity 5 -> 4. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker2<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X2>::ForwardType, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType); - - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X2>::ForwardType x2, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), x2, x3, x4, x5); + runnable.Run(a1, a2, a3, a4); } }; -template <bool IsWeak, typename StorageType, typename NormalizedSig> -struct Invoker3; - -// Function: Arity 3 -> 0. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3> -struct Invoker3<false, StorageType, R(*)(X1, X2, X3)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*); - - static R DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), - Unwrap(invoker->p3_)); +template <typename ReturnType, typename Runnable,typename A1, typename A2, + typename A3, typename A4, typename A5> +struct InvokeHelper<false, ReturnType, Runnable, + void(A1, A2, A3, A4, A5)> { + static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, + A5 a5) { + return runnable.Run(a1, a2, a3, a4, a5); } }; -// Method: Arity 2 -> 0. -template <typename StorageType, typename R, typename T, typename X1, - typename X2> -struct Invoker3<false, StorageType, R(T::*)(X1, X2)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*); - - static R DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), - Unwrap(invoker->p3_)); +template <typename Runnable,typename A1, typename A2, typename A3, typename A4, + typename A5> +struct InvokeHelper<false, void, Runnable, + void(A1, A2, A3, A4, A5)> { + static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + runnable.Run(a1, a2, a3, a4, a5); } }; -// WeakPtr Method: Arity 2 -> 0. -template <typename StorageType, typename T, typename X1, typename X2> -struct Invoker3<true, StorageType, void(T::*)(X1, X2)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*); - - static void DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { +template <typename Runnable, typename A1, typename A2, typename A3, + typename A4, typename A5> +struct InvokeHelper<true, void, Runnable, + void(A1, A2, A3, A4, A5)> { + static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!a1.get()) { return; } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_)); + + runnable.Run(a1, a2, a3, a4, a5); } }; -// Function: Arity 4 -> 1. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4> -struct Invoker3<false, StorageType, R(*)(X1, X2, X3, X4)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X4>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X4>::ForwardType x4) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), - Unwrap(invoker->p3_), x4); +template <typename ReturnType, typename Runnable,typename A1, typename A2, + typename A3, typename A4, typename A5, typename A6> +struct InvokeHelper<false, ReturnType, Runnable, + void(A1, A2, A3, A4, A5, A6)> { + static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, + A5 a5, A6 a6) { + return runnable.Run(a1, a2, a3, a4, a5, a6); } }; -// Method: Arity 3 -> 1. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3> -struct Invoker3<false, StorageType, R(T::*)(X1, X2, X3)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X3>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X3>::ForwardType x3) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), - Unwrap(invoker->p3_), x3); +template <typename Runnable,typename A1, typename A2, typename A3, typename A4, + typename A5, typename A6> +struct InvokeHelper<false, void, Runnable, + void(A1, A2, A3, A4, A5, A6)> { + static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, + A6 a6) { + runnable.Run(a1, a2, a3, a4, a5, a6); } }; -// WeakPtr Method: Arity 3 -> 1. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3> -struct Invoker3<true, StorageType, void(T::*)(X1, X2, X3)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X3>::ForwardType); - - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X3>::ForwardType x3) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { +template <typename Runnable, typename A1, typename A2, typename A3, + typename A4, typename A5, typename A6> +struct InvokeHelper<true, void, Runnable, + void(A1, A2, A3, A4, A5, A6)> { + static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, + A6 a6) { + if (!a1.get()) { return; } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), x3); - } -}; - -// Function: Arity 5 -> 2. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker3<false, StorageType, R(*)(X1, X2, X3, X4, X5)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType); - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), - Unwrap(invoker->p3_), x4, x5); + runnable.Run(a1, a2, a3, a4, a5, a6); } }; -// Method: Arity 4 -> 2. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3, typename X4> -struct Invoker3<false, StorageType, R(T::*)(X1, X2, X3, X4)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType); +#if !defined(_MSC_VER) - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), - Unwrap(invoker->p3_), x3, x4); - } +template <typename ReturnType, typename Runnable, typename ArgsType> +struct InvokeHelper<true, ReturnType, Runnable, ArgsType> { + // WeakCalls are only supported for functions with a void return type. + // Otherwise, the function result would be undefined if the the WeakPtr<> + // is invalidated. + COMPILE_ASSERT(is_void<ReturnType>::value, + weak_ptrs_can_only_bind_to_methods_without_return_values); }; -// WeakPtr Method: Arity 4 -> 2. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3, typename X4> -struct Invoker3<true, StorageType, void(T::*)(X1, X2, X3, X4)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType); - - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), x3, - x4); - } -}; +#endif -// Function: Arity 6 -> 3. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6> -struct Invoker3<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType, - typename internal::ParamTraits<X6>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5, - typename internal::ParamTraits<X6>::ForwardType x6) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), - Unwrap(invoker->p3_), x4, x5, x6); - } -}; - -// Method: Arity 5 -> 3. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3, typename X4, typename X5> -struct Invoker3<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType); - - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), - Unwrap(invoker->p3_), x3, x4, x5); - } -}; - -// WeakPtr Method: Arity 5 -> 3. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker3<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X3>::ForwardType, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType); - - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X3>::ForwardType x3, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), x3, - x4, x5); - } -}; +// Invoker<> +// +// See description at the top of the file. +template <int NumBound, typename Storage, typename RunType> +struct Invoker; -template <bool IsWeak, typename StorageType, typename NormalizedSig> -struct Invoker4; +// Arity 0 -> 0. +template <typename StorageType, typename R> +struct Invoker<0, StorageType, R()> { + typedef R(RunType)(BindStateBase*); -// Function: Arity 4 -> 0. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4> -struct Invoker4<false, StorageType, R(*)(X1, X2, X3, X4)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*); + typedef R(UnboundRunType)(); - static R DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), - Unwrap(invoker->p3_), Unwrap(invoker->p4_)); - } -}; + static R Run(BindStateBase* base) { + StorageType* storage = static_cast<StorageType*>(base); -// Method: Arity 3 -> 0. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3> -struct Invoker4<false, StorageType, R(T::*)(X1, X2, X3)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*); + // 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. - static R DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), - Unwrap(invoker->p3_), Unwrap(invoker->p4_)); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void()> + ::MakeItSo(storage->runnable_); } }; -// WeakPtr Method: Arity 3 -> 0. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3> -struct Invoker4<true, StorageType, void(T::*)(X1, X2, X3)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*); - - static void DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), - Unwrap(invoker->p4_)); - } -}; +// Arity 1 -> 1. +template <typename StorageType, typename R,typename X1> +struct Invoker<0, StorageType, R(X1)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X1>::ForwardType); -// Function: Arity 5 -> 1. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker4<false, StorageType, R(*)(X1, X2, X3, X4, X5)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X5>::ForwardType); + typedef R(UnboundRunType)(X1); - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), - Unwrap(invoker->p3_), Unwrap(invoker->p4_), x5); - } -}; + static R Run(BindStateBase* base, + typename CallbackParamTraits<X1>::ForwardType x1) { + StorageType* storage = static_cast<StorageType*>(base); -// Method: Arity 4 -> 1. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3, typename X4> -struct Invoker4<false, StorageType, R(T::*)(X1, X2, X3, X4)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X4>::ForwardType); + // 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. - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X4>::ForwardType x4) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), - Unwrap(invoker->p3_), Unwrap(invoker->p4_), x4); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename CallbackParamTraits<X1>::ForwardType x1)> + ::MakeItSo(storage->runnable_, x1); } }; -// WeakPtr Method: Arity 4 -> 1. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3, typename X4> -struct Invoker4<true, StorageType, void(T::*)(X1, X2, X3, X4)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X4>::ForwardType); - - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X4>::ForwardType x4) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), - Unwrap(invoker->p4_), x4); - } -}; +// Arity 1 -> 0. +template <typename StorageType, typename R,typename X1> +struct Invoker<1, StorageType, R(X1)> { + typedef R(RunType)(BindStateBase*); -// Function: Arity 6 -> 2. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6> -struct Invoker4<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X5>::ForwardType, - typename internal::ParamTraits<X6>::ForwardType); + typedef R(UnboundRunType)(); - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X5>::ForwardType x5, - typename internal::ParamTraits<X6>::ForwardType x6) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), - Unwrap(invoker->p3_), Unwrap(invoker->p4_), x5, x6); - } -}; + static R Run(BindStateBase* base) { + StorageType* storage = static_cast<StorageType*>(base); -// Method: Arity 5 -> 2. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3, typename X4, typename X5> -struct Invoker4<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType); + // 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), - Unwrap(invoker->p3_), Unwrap(invoker->p4_), x4, x5); + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType)> + ::MakeItSo(storage->runnable_, x1); } }; -// WeakPtr Method: Arity 5 -> 2. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker4<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X4>::ForwardType, - typename internal::ParamTraits<X5>::ForwardType); - - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X4>::ForwardType x4, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), - Unwrap(invoker->p4_), x4, x5); - } -}; +// Arity 2 -> 2. +template <typename StorageType, typename R,typename X1, typename X2> +struct Invoker<0, StorageType, R(X1, X2)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X1>::ForwardType, + typename CallbackParamTraits<X2>::ForwardType); -template <bool IsWeak, typename StorageType, typename NormalizedSig> -struct Invoker5; + typedef R(UnboundRunType)(X1, X2); -// Function: Arity 5 -> 0. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker5<false, StorageType, R(*)(X1, X2, X3, X4, X5)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*); + static R Run(BindStateBase* base, + typename CallbackParamTraits<X1>::ForwardType x1, + typename CallbackParamTraits<X2>::ForwardType x2) { + 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. - static R DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), - Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_)); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename CallbackParamTraits<X1>::ForwardType x1, + typename CallbackParamTraits<X2>::ForwardType x2)> + ::MakeItSo(storage->runnable_, x1, x2); } }; -// Method: Arity 4 -> 0. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3, typename X4> -struct Invoker5<false, StorageType, R(T::*)(X1, X2, X3, X4)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*); +// Arity 2 -> 1. +template <typename StorageType, typename R,typename X1, typename X2> +struct Invoker<1, StorageType, R(X1, X2)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X2>::ForwardType); - static R DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), - Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_)); - } -}; + typedef R(UnboundRunType)(X2); -// WeakPtr Method: Arity 4 -> 0. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3, typename X4> -struct Invoker5<true, StorageType, void(T::*)(X1, X2, X3, X4)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*); - - static void DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), - Unwrap(invoker->p4_), Unwrap(invoker->p5_)); - } -}; + static R Run(BindStateBase* base, + typename CallbackParamTraits<X2>::ForwardType x2) { + StorageType* storage = static_cast<StorageType*>(base); -// Function: Arity 6 -> 1. -template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6> -struct Invoker5<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X6>::ForwardType); + // 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X6>::ForwardType x6) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), - Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_), x6); + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename CallbackParamTraits<X2>::ForwardType x2)> + ::MakeItSo(storage->runnable_, x1, x2); } }; -// Method: Arity 5 -> 1. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3, typename X4, typename X5> -struct Invoker5<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X5>::ForwardType); +// Arity 2 -> 0. +template <typename StorageType, typename R,typename X1, typename X2> +struct Invoker<2, StorageType, R(X1, X2)> { + typedef R(RunType)(BindStateBase*); - static R DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), - Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_), x5); - } -}; + typedef R(UnboundRunType)(); -// WeakPtr Method: Arity 5 -> 1. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker5<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*, - typename internal::ParamTraits<X5>::ForwardType); - - static void DoInvoke(InvokerStorageBase* base, - typename internal::ParamTraits<X5>::ForwardType x5) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), - Unwrap(invoker->p4_), Unwrap(invoker->p5_), x5); + static R Run(BindStateBase* base) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType)> + ::MakeItSo(storage->runnable_, x1, x2); } }; -template <bool IsWeak, typename StorageType, typename NormalizedSig> -struct Invoker6; - -// Function: Arity 6 -> 0. +// Arity 3 -> 3. template <typename StorageType, typename R,typename X1, typename X2, - typename X3, typename X4, typename X5, typename X6> -struct Invoker6<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*); + typename X3> +struct Invoker<0, StorageType, R(X1, X2, X3)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X1>::ForwardType, + typename CallbackParamTraits<X2>::ForwardType, + typename CallbackParamTraits<X3>::ForwardType); - static R DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), - Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_), - Unwrap(invoker->p6_)); - } -}; + typedef R(UnboundRunType)(X1, X2, X3); -// Method: Arity 5 -> 0. -template <typename StorageType, typename R, typename T, typename X1, - typename X2, typename X3, typename X4, typename X5> -struct Invoker6<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> { - typedef R(*DoInvokeType)( - internal::InvokerStorageBase*); + static R Run(BindStateBase* base, + typename CallbackParamTraits<X1>::ForwardType x1, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3) { + StorageType* storage = static_cast<StorageType*>(base); - static R DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), - Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_), - Unwrap(invoker->p6_)); - } -}; + // 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. -// WeakPtr Method: Arity 5 -> 0. -template <typename StorageType, typename T, typename X1, typename X2, - typename X3, typename X4, typename X5> -struct Invoker6<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> { - typedef void(*DoInvokeType)( - internal::InvokerStorageBase*); - - static void DoInvoke(InvokerStorageBase* base) { - StorageType* invoker = static_cast<StorageType*>(base); - typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; - if (!weak_ptr.get()) { - return; - } - (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), - Unwrap(invoker->p4_), Unwrap(invoker->p5_), Unwrap(invoker->p6_)); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename CallbackParamTraits<X1>::ForwardType x1, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3)> + ::MakeItSo(storage->runnable_, x1, x2, x3); } }; -// BindMoreFuncN<> -// -// This set of functions help in fully binding the free parameters in a -// Callback<>. -template <typename Sig, typename P1> -void BindMoreFunc1(const base::Callback<Sig>& callback, const P1& p1) { - callback.Run(p1); -} +// Arity 3 -> 2. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3> +struct Invoker<1, StorageType, R(X1, X2, X3)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X2>::ForwardType, + typename CallbackParamTraits<X3>::ForwardType); -template <typename Sig, typename P1, typename P2> -void BindMoreFunc2(const base::Callback<Sig>& callback, const P1& p1, - const P2& p2) { - callback.Run(p1, p2); -} + typedef R(UnboundRunType)(X2, X3); -template <typename Sig, typename P1, typename P2, typename P3> -void BindMoreFunc3(const base::Callback<Sig>& callback, const P1& p1, - const P2& p2, const P3& p3) { - callback.Run(p1, p2, p3); -} + static R Run(BindStateBase* base, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3) { + StorageType* storage = static_cast<StorageType*>(base); -template <typename Sig, typename P1, typename P2, typename P3, typename P4> -void BindMoreFunc4(const base::Callback<Sig>& callback, const P1& p1, - const P2& p2, const P3& p3, const P4& p4) { - callback.Run(p1, p2, p3, p4); -} + // 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; -template <typename Sig, typename P1, typename P2, typename P3, typename P4, - typename P5> -void BindMoreFunc5(const base::Callback<Sig>& callback, const P1& p1, - const P2& p2, const P3& p3, const P4& p4, const P5& p5) { - callback.Run(p1, p2, p3, p4, p5); -} + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3)> + ::MakeItSo(storage->runnable_, x1, x2, x3); + } +}; -template <typename Sig, typename P1, typename P2, typename P3, typename P4, - typename P5, typename P6> -void BindMoreFunc6(const base::Callback<Sig>& callback, const P1& p1, - const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) { - callback.Run(p1, p2, p3, p4, p5, p6); -} +// Arity 3 -> 1. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3> +struct Invoker<2, StorageType, R(X1, X2, X3)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X3>::ForwardType); -// InvokerStorageN<> -// -// These are the actual storage classes for the Invokers. -// -// Though these types are "classes", they are being used as structs with -// all member variable public. We cannot make it a struct because it inherits -// from a class which causes a compiler warning. We cannot add a "Run()" method -// that forwards the unbound arguments because that would require we unwrap the -// Sig type like in InvokerN above to know the return type, and the arity -// of Run(). -// -// An alternate solution would be to merge InvokerN and InvokerStorageN, -// but the generated code seemed harder to read. - -template <typename Sig> -class InvokerStorage0 : public InvokerStorageBase { - public: - typedef InvokerStorage0 StorageType; - typedef FunctionTraits<Sig> TargetTraits; - typedef typename TargetTraits::IsMethod IsMethod; - typedef Sig Signature; - typedef Invoker0<false, StorageType, - typename TargetTraits::NormalizedSig> Invoker; + typedef R(UnboundRunType)(X3); + static R Run(BindStateBase* base, + typename CallbackParamTraits<X3>::ForwardType x3) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; - InvokerStorage0(Sig f) - : f_(f) { + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType, + typename CallbackParamTraits<X3>::ForwardType x3)> + ::MakeItSo(storage->runnable_, x1, x2, x3); } - - virtual ~InvokerStorage0() { } - - Sig f_; }; -template <typename Sig, typename P1> -class InvokerStorage1 : public InvokerStorageBase { - public: - typedef InvokerStorage1 StorageType; - typedef FunctionTraits<Sig> TargetTraits; - typedef typename TargetTraits::IsMethod IsMethod; - typedef Sig Signature; - typedef ParamTraits<P1> P1Traits; - typedef Invoker1<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 methods, we need to be careful for parameter 1. We skip the - // scoped_refptr check because the binder itself takes care of this. We also - // disallow binding of an array as the method's target object. - COMPILE_ASSERT(IsMethod::value || - internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P1>::StorageType>::value == 0, - p1_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value, - first_bound_argument_to_method_cannot_be_array); +// Arity 3 -> 0. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3> +struct Invoker<3, StorageType, R(X1, X2, X3)> { + typedef R(RunType)(BindStateBase*); - // Do not allow binding a non-const reference parameter. Non-const reference - // parameters are disallowed by the Google style guide. Also, binding a - // non-const reference parameter can make for subtle bugs because the - // invoked function will receive a reference to the stored copy of the - // argument and not the original. - COMPILE_ASSERT( - !( is_non_const_reference<typename TargetTraits::B1>::value ), - do_not_bind_functions_with_nonconst_ref); + typedef R(UnboundRunType)(); + static R Run(BindStateBase* base) { + StorageType* storage = static_cast<StorageType*>(base); - InvokerStorage1(Sig f, const P1& p1) - : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)) { - MaybeRefcount<IsMethod, P1>::AddRef(p1_); - } + // 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; + typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; - virtual ~InvokerStorage1() { - MaybeRefcount<IsMethod, P1>::Release(p1_); + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + typename Bound3UnwrapTraits::ForwardType x3 = + Bound3UnwrapTraits::Unwrap(storage->p3_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType, + typename Bound3UnwrapTraits::ForwardType)> + ::MakeItSo(storage->runnable_, x1, x2, x3); } - - Sig f_; - typename ParamTraits<P1>::StorageType p1_; }; -template <typename Sig, typename P1, typename P2> -class InvokerStorage2 : public InvokerStorageBase { - public: - typedef InvokerStorage2 StorageType; - typedef FunctionTraits<Sig> TargetTraits; - typedef typename TargetTraits::IsMethod IsMethod; - typedef Sig Signature; - typedef ParamTraits<P1> P1Traits; - typedef ParamTraits<P2> P2Traits; - typedef Invoker2<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); +// Arity 4 -> 4. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4> +struct Invoker<0, StorageType, R(X1, X2, X3, X4)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X1>::ForwardType, + typename CallbackParamTraits<X2>::ForwardType, + typename CallbackParamTraits<X3>::ForwardType, + typename CallbackParamTraits<X4>::ForwardType); - // For methods, we need to be careful for parameter 1. We skip the - // scoped_refptr check because the binder itself takes care of this. We also - // disallow binding of an array as the method's target object. - COMPILE_ASSERT(IsMethod::value || - internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P1>::StorageType>::value == 0, - p1_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value, - first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P2>::StorageType>::value == 0, - p2_is_refcounted_type_and_needs_scoped_refptr); + typedef R(UnboundRunType)(X1, X2, X3, X4); - // Do not allow binding a non-const reference parameter. Non-const reference - // parameters are disallowed by the Google style guide. Also, binding a - // non-const reference parameter can make for subtle bugs because the - // invoked function will receive a reference to the stored copy of the - // argument and not the original. - COMPILE_ASSERT( - !( is_non_const_reference<typename TargetTraits::B1>::value || - is_non_const_reference<typename TargetTraits::B2>::value ), - do_not_bind_functions_with_nonconst_ref); + static R Run(BindStateBase* base, + typename CallbackParamTraits<X1>::ForwardType x1, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4) { + 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. - InvokerStorage2(Sig f, const P1& p1, const P2& p2) - : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)), - p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)) { - MaybeRefcount<IsMethod, P1>::AddRef(p1_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename CallbackParamTraits<X1>::ForwardType x1, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4); } +}; - virtual ~InvokerStorage2() { - MaybeRefcount<IsMethod, P1>::Release(p1_); - } +// Arity 4 -> 3. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4> +struct Invoker<1, StorageType, R(X1, X2, X3, X4)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X2>::ForwardType, + typename CallbackParamTraits<X3>::ForwardType, + typename CallbackParamTraits<X4>::ForwardType); + + typedef R(UnboundRunType)(X2, X3, X4); + + static R Run(BindStateBase* base, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4); + } +}; + +// Arity 4 -> 2. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4> +struct Invoker<2, StorageType, R(X1, X2, X3, X4)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X3>::ForwardType, + typename CallbackParamTraits<X4>::ForwardType); + + typedef R(UnboundRunType)(X3, X4); + + static R Run(BindStateBase* base, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4); + } +}; + +// Arity 4 -> 1. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4> +struct Invoker<3, StorageType, R(X1, X2, X3, X4)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X4>::ForwardType); + + typedef R(UnboundRunType)(X4); + + static R Run(BindStateBase* base, + typename CallbackParamTraits<X4>::ForwardType x4) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; + typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + typename Bound3UnwrapTraits::ForwardType x3 = + Bound3UnwrapTraits::Unwrap(storage->p3_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType, + typename Bound3UnwrapTraits::ForwardType, + typename CallbackParamTraits<X4>::ForwardType x4)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4); + } +}; + +// Arity 4 -> 0. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4> +struct Invoker<4, StorageType, R(X1, X2, X3, X4)> { + typedef R(RunType)(BindStateBase*); + + typedef R(UnboundRunType)(); + + static R Run(BindStateBase* base) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; + typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; + typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + typename Bound3UnwrapTraits::ForwardType x3 = + Bound3UnwrapTraits::Unwrap(storage->p3_); + typename Bound4UnwrapTraits::ForwardType x4 = + Bound4UnwrapTraits::Unwrap(storage->p4_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType, + typename Bound3UnwrapTraits::ForwardType, + typename Bound4UnwrapTraits::ForwardType)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4); + } +}; + +// Arity 5 -> 5. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4, typename X5> +struct Invoker<0, StorageType, R(X1, X2, X3, X4, X5)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X1>::ForwardType, + typename CallbackParamTraits<X2>::ForwardType, + typename CallbackParamTraits<X3>::ForwardType, + typename CallbackParamTraits<X4>::ForwardType, + typename CallbackParamTraits<X5>::ForwardType); + + typedef R(UnboundRunType)(X1, X2, X3, X4, X5); + + static R Run(BindStateBase* base, + typename CallbackParamTraits<X1>::ForwardType x1, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5) { + 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 InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename CallbackParamTraits<X1>::ForwardType x1, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5); + } +}; + +// Arity 5 -> 4. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4, typename X5> +struct Invoker<1, StorageType, R(X1, X2, X3, X4, X5)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X2>::ForwardType, + typename CallbackParamTraits<X3>::ForwardType, + typename CallbackParamTraits<X4>::ForwardType, + typename CallbackParamTraits<X5>::ForwardType); + + typedef R(UnboundRunType)(X2, X3, X4, X5); + + static R Run(BindStateBase* base, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5); + } +}; + +// Arity 5 -> 3. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4, typename X5> +struct Invoker<2, StorageType, R(X1, X2, X3, X4, X5)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X3>::ForwardType, + typename CallbackParamTraits<X4>::ForwardType, + typename CallbackParamTraits<X5>::ForwardType); + + typedef R(UnboundRunType)(X3, X4, X5); + + static R Run(BindStateBase* base, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5); + } +}; + +// Arity 5 -> 2. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4, typename X5> +struct Invoker<3, StorageType, R(X1, X2, X3, X4, X5)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X4>::ForwardType, + typename CallbackParamTraits<X5>::ForwardType); + + typedef R(UnboundRunType)(X4, X5); + + static R Run(BindStateBase* base, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; + typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + typename Bound3UnwrapTraits::ForwardType x3 = + Bound3UnwrapTraits::Unwrap(storage->p3_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType, + typename Bound3UnwrapTraits::ForwardType, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5); + } +}; + +// Arity 5 -> 1. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4, typename X5> +struct Invoker<4, StorageType, R(X1, X2, X3, X4, X5)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X5>::ForwardType); + + typedef R(UnboundRunType)(X5); + + static R Run(BindStateBase* base, + typename CallbackParamTraits<X5>::ForwardType x5) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; + typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; + typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + typename Bound3UnwrapTraits::ForwardType x3 = + Bound3UnwrapTraits::Unwrap(storage->p3_); + typename Bound4UnwrapTraits::ForwardType x4 = + Bound4UnwrapTraits::Unwrap(storage->p4_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType, + typename Bound3UnwrapTraits::ForwardType, + typename Bound4UnwrapTraits::ForwardType, + typename CallbackParamTraits<X5>::ForwardType x5)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5); + } +}; + +// Arity 5 -> 0. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4, typename X5> +struct Invoker<5, StorageType, R(X1, X2, X3, X4, X5)> { + typedef R(RunType)(BindStateBase*); + + typedef R(UnboundRunType)(); + + static R Run(BindStateBase* base) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; + typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; + typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; + typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + typename Bound3UnwrapTraits::ForwardType x3 = + Bound3UnwrapTraits::Unwrap(storage->p3_); + typename Bound4UnwrapTraits::ForwardType x4 = + Bound4UnwrapTraits::Unwrap(storage->p4_); + typename Bound5UnwrapTraits::ForwardType x5 = + Bound5UnwrapTraits::Unwrap(storage->p5_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType, + typename Bound3UnwrapTraits::ForwardType, + typename Bound4UnwrapTraits::ForwardType, + typename Bound5UnwrapTraits::ForwardType)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5); + } +}; + +// Arity 6 -> 6. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4, typename X5, typename X6> +struct Invoker<0, StorageType, R(X1, X2, X3, X4, X5, X6)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X1>::ForwardType, + typename CallbackParamTraits<X2>::ForwardType, + typename CallbackParamTraits<X3>::ForwardType, + typename CallbackParamTraits<X4>::ForwardType, + typename CallbackParamTraits<X5>::ForwardType, + typename CallbackParamTraits<X6>::ForwardType); + + typedef R(UnboundRunType)(X1, X2, X3, X4, X5, X6); + + static R Run(BindStateBase* base, + typename CallbackParamTraits<X1>::ForwardType x1, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5, + typename CallbackParamTraits<X6>::ForwardType x6) { + 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 InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename CallbackParamTraits<X1>::ForwardType x1, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5, + typename CallbackParamTraits<X6>::ForwardType x6)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6); + } +}; + +// Arity 6 -> 5. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4, typename X5, typename X6> +struct Invoker<1, StorageType, R(X1, X2, X3, X4, X5, X6)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X2>::ForwardType, + typename CallbackParamTraits<X3>::ForwardType, + typename CallbackParamTraits<X4>::ForwardType, + typename CallbackParamTraits<X5>::ForwardType, + typename CallbackParamTraits<X6>::ForwardType); + + typedef R(UnboundRunType)(X2, X3, X4, X5, X6); + + static R Run(BindStateBase* base, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5, + typename CallbackParamTraits<X6>::ForwardType x6) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename CallbackParamTraits<X2>::ForwardType x2, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5, + typename CallbackParamTraits<X6>::ForwardType x6)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6); + } +}; + +// Arity 6 -> 4. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4, typename X5, typename X6> +struct Invoker<2, StorageType, R(X1, X2, X3, X4, X5, X6)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X3>::ForwardType, + typename CallbackParamTraits<X4>::ForwardType, + typename CallbackParamTraits<X5>::ForwardType, + typename CallbackParamTraits<X6>::ForwardType); + + typedef R(UnboundRunType)(X3, X4, X5, X6); + + static R Run(BindStateBase* base, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5, + typename CallbackParamTraits<X6>::ForwardType x6) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType, + typename CallbackParamTraits<X3>::ForwardType x3, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5, + typename CallbackParamTraits<X6>::ForwardType x6)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6); + } +}; + +// Arity 6 -> 3. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4, typename X5, typename X6> +struct Invoker<3, StorageType, R(X1, X2, X3, X4, X5, X6)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X4>::ForwardType, + typename CallbackParamTraits<X5>::ForwardType, + typename CallbackParamTraits<X6>::ForwardType); + + typedef R(UnboundRunType)(X4, X5, X6); + + static R Run(BindStateBase* base, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5, + typename CallbackParamTraits<X6>::ForwardType x6) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; + typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + typename Bound3UnwrapTraits::ForwardType x3 = + Bound3UnwrapTraits::Unwrap(storage->p3_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType, + typename Bound3UnwrapTraits::ForwardType, + typename CallbackParamTraits<X4>::ForwardType x4, + typename CallbackParamTraits<X5>::ForwardType x5, + typename CallbackParamTraits<X6>::ForwardType x6)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6); + } +}; + +// Arity 6 -> 2. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4, typename X5, typename X6> +struct Invoker<4, StorageType, R(X1, X2, X3, X4, X5, X6)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X5>::ForwardType, + typename CallbackParamTraits<X6>::ForwardType); + + typedef R(UnboundRunType)(X5, X6); + + static R Run(BindStateBase* base, + typename CallbackParamTraits<X5>::ForwardType x5, + typename CallbackParamTraits<X6>::ForwardType x6) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; + typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; + typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + typename Bound3UnwrapTraits::ForwardType x3 = + Bound3UnwrapTraits::Unwrap(storage->p3_); + typename Bound4UnwrapTraits::ForwardType x4 = + Bound4UnwrapTraits::Unwrap(storage->p4_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType, + typename Bound3UnwrapTraits::ForwardType, + typename Bound4UnwrapTraits::ForwardType, + typename CallbackParamTraits<X5>::ForwardType x5, + typename CallbackParamTraits<X6>::ForwardType x6)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6); + } +}; + +// Arity 6 -> 1. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4, typename X5, typename X6> +struct Invoker<5, StorageType, R(X1, X2, X3, X4, X5, X6)> { + typedef R(RunType)(BindStateBase*, + typename CallbackParamTraits<X6>::ForwardType); + + typedef R(UnboundRunType)(X6); + + static R Run(BindStateBase* base, + typename CallbackParamTraits<X6>::ForwardType x6) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; + typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; + typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; + typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + typename Bound3UnwrapTraits::ForwardType x3 = + Bound3UnwrapTraits::Unwrap(storage->p3_); + typename Bound4UnwrapTraits::ForwardType x4 = + Bound4UnwrapTraits::Unwrap(storage->p4_); + typename Bound5UnwrapTraits::ForwardType x5 = + Bound5UnwrapTraits::Unwrap(storage->p5_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType, + typename Bound3UnwrapTraits::ForwardType, + typename Bound4UnwrapTraits::ForwardType, + typename Bound5UnwrapTraits::ForwardType, + typename CallbackParamTraits<X6>::ForwardType x6)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6); + } +}; + +// Arity 6 -> 0. +template <typename StorageType, typename R,typename X1, typename X2, + typename X3, typename X4, typename X5, typename X6> +struct Invoker<6, StorageType, R(X1, X2, X3, X4, X5, X6)> { + typedef R(RunType)(BindStateBase*); + + typedef R(UnboundRunType)(); + + static R Run(BindStateBase* base) { + 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. + typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits; + typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits; + typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits; + typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits; + typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits; + typedef typename StorageType::Bound6UnwrapTraits Bound6UnwrapTraits; + + typename Bound1UnwrapTraits::ForwardType x1 = + Bound1UnwrapTraits::Unwrap(storage->p1_); + typename Bound2UnwrapTraits::ForwardType x2 = + Bound2UnwrapTraits::Unwrap(storage->p2_); + typename Bound3UnwrapTraits::ForwardType x3 = + Bound3UnwrapTraits::Unwrap(storage->p3_); + typename Bound4UnwrapTraits::ForwardType x4 = + Bound4UnwrapTraits::Unwrap(storage->p4_); + typename Bound5UnwrapTraits::ForwardType x5 = + Bound5UnwrapTraits::Unwrap(storage->p5_); + typename Bound6UnwrapTraits::ForwardType x6 = + Bound6UnwrapTraits::Unwrap(storage->p6_); + return InvokeHelper<StorageType::IsWeakCall::value, R, + typename StorageType::RunnableType, + void(typename Bound1UnwrapTraits::ForwardType, + typename Bound2UnwrapTraits::ForwardType, + typename Bound3UnwrapTraits::ForwardType, + typename Bound4UnwrapTraits::ForwardType, + typename Bound5UnwrapTraits::ForwardType, + typename Bound6UnwrapTraits::ForwardType)> + ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6); + } +}; + + +// 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. +// +// BoundArgsType contains the storage type for all the bound arguments by +// (ab)using a function type. +template <typename Runnable, typename RunType, typename BoundArgsType> +struct BindState; - Sig f_; - typename ParamTraits<P1>::StorageType p1_; - typename ParamTraits<P2>::StorageType p2_; -}; +template <typename Runnable, typename RunType> +struct BindState<Runnable, RunType, void()> : public BindStateBase { + typedef Runnable RunnableType; + typedef false_type IsWeakCall; + typedef Invoker<0, BindState, RunType> InvokerType; + typedef typename InvokerType::UnboundRunType UnboundRunType; + explicit BindState(const Runnable& runnable) + : runnable_(runnable) { + } -template <typename Sig, typename P1, typename P2, typename P3> -class InvokerStorage3 : public InvokerStorageBase { - public: - typedef InvokerStorage3 StorageType; - typedef FunctionTraits<Sig> TargetTraits; - typedef typename TargetTraits::IsMethod IsMethod; - typedef Sig Signature; - typedef ParamTraits<P1> P1Traits; - typedef ParamTraits<P2> P2Traits; - typedef ParamTraits<P3> P3Traits; - typedef Invoker3<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); + virtual ~BindState() { } - // For methods, we need to be careful for parameter 1. We skip the - // scoped_refptr check because the binder itself takes care of this. We also - // disallow binding of an array as the method's target object. - COMPILE_ASSERT(IsMethod::value || - internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P1>::StorageType>::value == 0, - p1_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value, - first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P2>::StorageType>::value == 0, - p2_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P3>::StorageType>::value == 0, - p3_is_refcounted_type_and_needs_scoped_refptr); - - // Do not allow binding a non-const reference parameter. Non-const reference - // parameters are disallowed by the Google style guide. Also, binding a - // non-const reference parameter can make for subtle bugs because the - // invoked function will receive a reference to the stored copy of the - // argument and not the original. - COMPILE_ASSERT( - !( is_non_const_reference<typename TargetTraits::B1>::value || - is_non_const_reference<typename TargetTraits::B2>::value || - is_non_const_reference<typename TargetTraits::B3>::value ), - do_not_bind_functions_with_nonconst_ref); - - - InvokerStorage3(Sig f, const P1& p1, const P2& p2, const P3& p3) - : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)), - p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)), - p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)) { - MaybeRefcount<IsMethod, P1>::AddRef(p1_); - } - - virtual ~InvokerStorage3() { - MaybeRefcount<IsMethod, P1>::Release(p1_); - } - - Sig f_; - typename ParamTraits<P1>::StorageType p1_; - typename ParamTraits<P2>::StorageType p2_; - typename ParamTraits<P3>::StorageType p3_; -}; - -template <typename Sig, typename P1, typename P2, typename P3, typename P4> -class InvokerStorage4 : public InvokerStorageBase { - public: - typedef InvokerStorage4 StorageType; - typedef FunctionTraits<Sig> TargetTraits; - typedef typename TargetTraits::IsMethod IsMethod; - typedef Sig Signature; - typedef ParamTraits<P1> P1Traits; - typedef ParamTraits<P2> P2Traits; - typedef ParamTraits<P3> P3Traits; - typedef ParamTraits<P4> P4Traits; - typedef Invoker4<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); + RunnableType runnable_; +}; + +template <typename Runnable, typename RunType, typename P1> +struct BindState<Runnable, RunType, void(P1)> : public BindStateBase { + typedef Runnable RunnableType; + typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; + typedef Invoker<1, BindState, RunType> InvokerType; + typedef typename InvokerType::UnboundRunType UnboundRunType; - // For methods, we need to be careful for parameter 1. We skip the - // scoped_refptr check because the binder itself takes care of this. We also - // disallow binding of an array as the method's target object. - COMPILE_ASSERT(IsMethod::value || - internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P1>::StorageType>::value == 0, - p1_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value, - first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P2>::StorageType>::value == 0, - p2_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P3>::StorageType>::value == 0, - p3_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P4>::StorageType>::value == 0, - p4_is_refcounted_type_and_needs_scoped_refptr); - - // Do not allow binding a non-const reference parameter. Non-const reference - // parameters are disallowed by the Google style guide. Also, binding a - // non-const reference parameter can make for subtle bugs because the - // invoked function will receive a reference to the stored copy of the - // argument and not the original. - COMPILE_ASSERT( - !( is_non_const_reference<typename TargetTraits::B1>::value || - is_non_const_reference<typename TargetTraits::B2>::value || - is_non_const_reference<typename TargetTraits::B3>::value || - is_non_const_reference<typename TargetTraits::B4>::value ), - do_not_bind_functions_with_nonconst_ref); - - - InvokerStorage4(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4) - : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)), - p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)), - p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)), - p4_(static_cast<typename ParamTraits<P4>::StorageType>(p4)) { - MaybeRefcount<IsMethod, P1>::AddRef(p1_); - } - - virtual ~InvokerStorage4() { - MaybeRefcount<IsMethod, P1>::Release(p1_); - } - - Sig f_; - typename ParamTraits<P1>::StorageType p1_; - typename ParamTraits<P2>::StorageType p2_; - typename ParamTraits<P3>::StorageType p3_; - typename ParamTraits<P4>::StorageType p4_; -}; - -template <typename Sig, typename P1, typename P2, typename P3, typename P4, - typename P5> -class InvokerStorage5 : public InvokerStorageBase { - public: - typedef InvokerStorage5 StorageType; - typedef FunctionTraits<Sig> TargetTraits; - typedef typename TargetTraits::IsMethod IsMethod; - typedef Sig Signature; - typedef ParamTraits<P1> P1Traits; - typedef ParamTraits<P2> P2Traits; - typedef ParamTraits<P3> P3Traits; - typedef ParamTraits<P4> P4Traits; - typedef ParamTraits<P5> P5Traits; - typedef Invoker5<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); + // Convenience typedefs for bound argument types. + typedef UnwrapTraits<P1> Bound1UnwrapTraits; - // For methods, we need to be careful for parameter 1. We skip the - // scoped_refptr check because the binder itself takes care of this. We also - // disallow binding of an array as the method's target object. - COMPILE_ASSERT(IsMethod::value || - internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P1>::StorageType>::value == 0, - p1_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value, - first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P2>::StorageType>::value == 0, - p2_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P3>::StorageType>::value == 0, - p3_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P4>::StorageType>::value == 0, - p4_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P5>::StorageType>::value == 0, - p5_is_refcounted_type_and_needs_scoped_refptr); - - // Do not allow binding a non-const reference parameter. Non-const reference - // parameters are disallowed by the Google style guide. Also, binding a - // non-const reference parameter can make for subtle bugs because the - // invoked function will receive a reference to the stored copy of the - // argument and not the original. - COMPILE_ASSERT( - !( is_non_const_reference<typename TargetTraits::B1>::value || - is_non_const_reference<typename TargetTraits::B2>::value || - is_non_const_reference<typename TargetTraits::B3>::value || - is_non_const_reference<typename TargetTraits::B4>::value || - is_non_const_reference<typename TargetTraits::B5>::value ), - do_not_bind_functions_with_nonconst_ref); - - - InvokerStorage5(Sig f, const P1& p1, const P2& p2, const P3& p3, - const P4& p4, const P5& p5) - : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)), - p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)), - p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)), - p4_(static_cast<typename ParamTraits<P4>::StorageType>(p4)), - p5_(static_cast<typename ParamTraits<P5>::StorageType>(p5)) { - MaybeRefcount<IsMethod, P1>::AddRef(p1_); + BindState(const Runnable& runnable, const P1& p1) + : runnable_(runnable), + p1_(p1) { + MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); } - virtual ~InvokerStorage5() { - MaybeRefcount<IsMethod, P1>::Release(p1_); - } + virtual ~BindState() { MaybeRefcount<HasIsMethodTag<Runnable>::value, + P1>::Release(p1_); } - Sig f_; - typename ParamTraits<P1>::StorageType p1_; - typename ParamTraits<P2>::StorageType p2_; - typename ParamTraits<P3>::StorageType p3_; - typename ParamTraits<P4>::StorageType p4_; - typename ParamTraits<P5>::StorageType p5_; -}; + RunnableType runnable_; + P1 p1_; +}; -template <typename Sig, typename P1, typename P2, typename P3, typename P4, - typename P5, typename P6> -class InvokerStorage6 : public InvokerStorageBase { - public: - typedef InvokerStorage6 StorageType; - typedef FunctionTraits<Sig> TargetTraits; - typedef typename TargetTraits::IsMethod IsMethod; - typedef Sig Signature; - typedef ParamTraits<P1> P1Traits; - typedef ParamTraits<P2> P2Traits; - typedef ParamTraits<P3> P3Traits; - typedef ParamTraits<P4> P4Traits; - typedef ParamTraits<P5> P5Traits; - typedef ParamTraits<P6> P6Traits; - typedef Invoker6<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); +template <typename Runnable, typename RunType, typename P1, typename P2> +struct BindState<Runnable, RunType, void(P1, P2)> : public BindStateBase { + typedef Runnable RunnableType; + typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; + typedef Invoker<2, BindState, RunType> InvokerType; + typedef typename InvokerType::UnboundRunType UnboundRunType; + + // Convenience typedefs for bound argument types. + typedef UnwrapTraits<P1> Bound1UnwrapTraits; + typedef UnwrapTraits<P2> Bound2UnwrapTraits; + + BindState(const Runnable& runnable, const P1& p1, const P2& p2) + : runnable_(runnable), + p1_(p1), + p2_(p2) { + MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); + } + + virtual ~BindState() { MaybeRefcount<HasIsMethodTag<Runnable>::value, + P1>::Release(p1_); } + + RunnableType runnable_; + P1 p1_; + P2 p2_; +}; + +template <typename Runnable, typename RunType, typename P1, typename P2, + typename P3> +struct BindState<Runnable, RunType, void(P1, P2, P3)> : public BindStateBase { + typedef Runnable RunnableType; + typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; + typedef Invoker<3, BindState, RunType> InvokerType; + typedef typename InvokerType::UnboundRunType UnboundRunType; + + // Convenience typedefs for bound argument types. + typedef UnwrapTraits<P1> Bound1UnwrapTraits; + typedef UnwrapTraits<P2> Bound2UnwrapTraits; + typedef UnwrapTraits<P3> Bound3UnwrapTraits; + + BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3) + : runnable_(runnable), + p1_(p1), + p2_(p2), + p3_(p3) { + MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); + } + + virtual ~BindState() { MaybeRefcount<HasIsMethodTag<Runnable>::value, + P1>::Release(p1_); } + + RunnableType runnable_; + P1 p1_; + P2 p2_; + P3 p3_; +}; + +template <typename Runnable, typename RunType, typename P1, typename P2, + typename P3, typename P4> +struct BindState<Runnable, RunType, void(P1, P2, P3, + P4)> : public BindStateBase { + typedef Runnable RunnableType; + typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; + typedef Invoker<4, BindState, RunType> InvokerType; + typedef typename InvokerType::UnboundRunType UnboundRunType; + + // Convenience typedefs for bound argument types. + typedef UnwrapTraits<P1> Bound1UnwrapTraits; + typedef UnwrapTraits<P2> Bound2UnwrapTraits; + typedef UnwrapTraits<P3> Bound3UnwrapTraits; + typedef UnwrapTraits<P4> Bound4UnwrapTraits; - // For methods, we need to be careful for parameter 1. We skip the - // scoped_refptr check because the binder itself takes care of this. We also - // disallow binding of an array as the method's target object. - COMPILE_ASSERT(IsMethod::value || - internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P1>::StorageType>::value == 0, - p1_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value, - first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P2>::StorageType>::value == 0, - p2_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P3>::StorageType>::value == 0, - p3_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P4>::StorageType>::value == 0, - p4_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P5>::StorageType>::value == 0, - p5_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< - typename ParamTraits<P6>::StorageType>::value == 0, - p6_is_refcounted_type_and_needs_scoped_refptr); - - // Do not allow binding a non-const reference parameter. Non-const reference - // parameters are disallowed by the Google style guide. Also, binding a - // non-const reference parameter can make for subtle bugs because the - // invoked function will receive a reference to the stored copy of the - // argument and not the original. - COMPILE_ASSERT( - !( is_non_const_reference<typename TargetTraits::B1>::value || - is_non_const_reference<typename TargetTraits::B2>::value || - is_non_const_reference<typename TargetTraits::B3>::value || - is_non_const_reference<typename TargetTraits::B4>::value || - is_non_const_reference<typename TargetTraits::B5>::value || - is_non_const_reference<typename TargetTraits::B6>::value ), - do_not_bind_functions_with_nonconst_ref); - - - InvokerStorage6(Sig f, const P1& p1, const P2& p2, const P3& p3, + BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3, + const P4& p4) + : runnable_(runnable), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) { + MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); + } + + virtual ~BindState() { MaybeRefcount<HasIsMethodTag<Runnable>::value, + P1>::Release(p1_); } + + RunnableType runnable_; + P1 p1_; + P2 p2_; + P3 p3_; + P4 p4_; +}; + +template <typename Runnable, typename RunType, typename P1, typename P2, + typename P3, typename P4, typename P5> +struct BindState<Runnable, RunType, void(P1, P2, P3, P4, + P5)> : public BindStateBase { + typedef Runnable RunnableType; + typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; + typedef Invoker<5, BindState, RunType> InvokerType; + typedef typename InvokerType::UnboundRunType UnboundRunType; + + // Convenience typedefs for bound argument types. + typedef UnwrapTraits<P1> Bound1UnwrapTraits; + typedef UnwrapTraits<P2> Bound2UnwrapTraits; + typedef UnwrapTraits<P3> Bound3UnwrapTraits; + typedef UnwrapTraits<P4> Bound4UnwrapTraits; + typedef UnwrapTraits<P5> Bound5UnwrapTraits; + + BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3, + const P4& p4, const P5& p5) + : runnable_(runnable), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) { + MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); + } + + virtual ~BindState() { MaybeRefcount<HasIsMethodTag<Runnable>::value, + P1>::Release(p1_); } + + RunnableType runnable_; + P1 p1_; + P2 p2_; + P3 p3_; + P4 p4_; + P5 p5_; +}; + +template <typename Runnable, typename RunType, typename P1, typename P2, + typename P3, typename P4, typename P5, typename P6> +struct BindState<Runnable, RunType, void(P1, P2, P3, P4, P5, + P6)> : public BindStateBase { + typedef Runnable RunnableType; + typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; + typedef Invoker<6, BindState, RunType> InvokerType; + typedef typename InvokerType::UnboundRunType UnboundRunType; + + // Convenience typedefs for bound argument types. + typedef UnwrapTraits<P1> Bound1UnwrapTraits; + typedef UnwrapTraits<P2> Bound2UnwrapTraits; + typedef UnwrapTraits<P3> Bound3UnwrapTraits; + typedef UnwrapTraits<P4> Bound4UnwrapTraits; + typedef UnwrapTraits<P5> Bound5UnwrapTraits; + typedef UnwrapTraits<P6> Bound6UnwrapTraits; + + BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) - : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)), - p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)), - p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)), - p4_(static_cast<typename ParamTraits<P4>::StorageType>(p4)), - p5_(static_cast<typename ParamTraits<P5>::StorageType>(p5)), - p6_(static_cast<typename ParamTraits<P6>::StorageType>(p6)) { - MaybeRefcount<IsMethod, P1>::AddRef(p1_); - } - - virtual ~InvokerStorage6() { - MaybeRefcount<IsMethod, P1>::Release(p1_); - } - - Sig f_; - typename ParamTraits<P1>::StorageType p1_; - typename ParamTraits<P2>::StorageType p2_; - typename ParamTraits<P3>::StorageType p3_; - typename ParamTraits<P4>::StorageType p4_; - typename ParamTraits<P5>::StorageType p5_; - typename ParamTraits<P6>::StorageType p6_; + : runnable_(runnable), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) { + MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); + } + + virtual ~BindState() { MaybeRefcount<HasIsMethodTag<Runnable>::value, + P1>::Release(p1_); } + + RunnableType runnable_; + P1 p1_; + P2 p2_; + P3 p3_; + P4 p4_; + P5 p5_; + P6 p6_; }; } // namespace internal |