Chromium Code Reviews| Index: base/callback.h |
| diff --git a/base/callback.h b/base/callback.h |
| index 16e3ee60c51971f87bb914e9e52bf5fd9ddd3091..bd481476d8b56e8e20041c6635d361cf38542da5 100644 |
| --- a/base/callback.h |
| +++ b/base/callback.h |
| @@ -125,29 +125,28 @@ |
| // The Callback classes represent a generic function pointer. Internally, |
| // it stores a refcounted piece of state that represents the target function |
| // and all its bound parameters. Each Callback specialization has a templated |
| -// constructor that takes an BindStateHolder<> object. In the context of |
| -// the constructor, the static type of this BindStateHolder<> object |
| -// uniquely identifies the function it is representing, all its bound |
| -// parameters, and a DoInvoke() that is capable of invoking the target. |
| -// |
| -// Callback's constructor is takes the BindStateHolder<> that has the |
| -// full static type and erases the target function type, and the bound |
| -// parameters. It does this by storing a pointer to the specific DoInvoke() |
| -// function, and upcasting the state of BindStateHolder<> to a |
| -// BindStateBase. This is safe as long as this BindStateBase pointer |
| -// is only used with the stored DoInvoke() pointer. |
| -// |
| -// To create BindStateHolder<> objects, we use the Bind() functions. |
| +// constructor that takes an BindState<>*. In the context of the constructor, |
| +// the static type of this BindState<> pointer uniquely identifies the |
| +// function it is representing, all its bound parameters, and a Run() method |
| +// that is capable of invoking the target. |
| +// |
| +// Callback's constructor takes the BindState<>* that has the full static type |
| +// and erases the target function type as well as the types of the bound |
| +// parameters. It does this by storing a pointer to the specific Run() |
| +// function, and upcasting the state of BindState<>* to a |
| +// BindStateBase*. This is safe as long as this BindStateBase pointer |
| +// is only used with the stored Run() pointer. |
| +// |
| +// To BindState<> objects are created inside the Bind() functions. |
| // These functions, along with a set of internal templates, are reponsible for |
|
akalin
2011/12/02 18:54:45
reponsible -> responsible
awong
2011/12/06 00:21:12
Done.
|
| // |
| // - Unwrapping the function signature into return type, and parameters |
| // - Determining the number of parameters that are bound |
| -// - Creating the storage for the bound parameters |
| +// - Creating the BindState storing the bound parameters |
| // - Performing compile-time asserts to avoid error-prone behavior |
| -// - Returning an BindStateHolder<> with an DoInvoke() that has an arity |
| -// matching the number of unbound parameters, and knows the correct |
| -// refcounting semantics for the target object if we are binding a class |
| -// method. |
| +// - Returning an Callback<> with an arity matching the number of unbound |
| +// parameters and that knows the correct refcounting semantics for the |
| +// target object if we are binding a method. |
| // |
| // The Bind functions do the above using type-inference, and template |
| // specializations. |
| @@ -232,27 +231,29 @@ namespace base { |
| template <typename Sig> |
| class Callback; |
| +namespace internal { |
| +template <typename Runnable, typename RunType, typename BoundArgsType> |
| +struct BindState; |
| +} // namespace internal |
| template <typename R> |
| class Callback<R(void)> : public internal::CallbackBase { |
| public: |
| typedef R(RunType)(); |
| - Callback() : CallbackBase(NULL, NULL) { } |
| + Callback() : CallbackBase(NULL) { } |
| - // We pass BindStateHolder by const ref to avoid incurring an |
| - // unnecessary AddRef/Unref pair even though we will modify the object. |
| - // We cannot use a normal reference because the compiler will warn |
| - // since this is often used on a return value, which is a temporary. |
| - // |
| // Note that this constructor CANNOT be explicit, and that Bind() CANNOT |
| // return the exact Callback<> type. See base/bind.h for details. |
| - template <typename T> |
| - Callback(const internal::BindStateHolder<T>& bind_state_holder) |
| - : CallbackBase(NULL, &bind_state_holder.bind_state_) { |
| - // Force the assignment to a location variable of PolymorphicInvoke |
| + template <typename Runnable, typename RunType, typename BoundArgsType> |
| + Callback(internal::BindState<Runnable, RunType, BoundArgsType>* bind_state) |
| + : CallbackBase(bind_state) { |
| + |
| + // Force the assignment to a local variable of PolymorphicInvoke |
| // so the compiler will typecheck that the passed in Run() method has |
| // the correct type. |
| - PolymorphicInvoke invoke_func = &T::InvokerType::Run; |
| + PolymorphicInvoke invoke_func = |
| + &internal::BindState<Runnable, RunType, BoundArgsType> |
| + ::InvokerType::Run; |
| polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func); |
| } |
| @@ -278,22 +279,20 @@ class Callback<R(A1)> : public internal::CallbackBase { |
| public: |
| typedef R(RunType)(A1); |
| - Callback() : CallbackBase(NULL, NULL) { } |
| + Callback() : CallbackBase(NULL) { } |
| - // We pass BindStateHolder by const ref to avoid incurring an |
| - // unnecessary AddRef/Unref pair even though we will modify the object. |
| - // We cannot use a normal reference because the compiler will warn |
| - // since this is often used on a return value, which is a temporary. |
| - // |
| // Note that this constructor CANNOT be explicit, and that Bind() CANNOT |
| // return the exact Callback<> type. See base/bind.h for details. |
| - template <typename T> |
| - Callback(const internal::BindStateHolder<T>& bind_state_holder) |
| - : CallbackBase(NULL, &bind_state_holder.bind_state_) { |
| - // Force the assignment to a location variable of PolymorphicInvoke |
| + template <typename Runnable, typename RunType, typename BoundArgsType> |
| + Callback(internal::BindState<Runnable, RunType, BoundArgsType>* bind_state) |
| + : CallbackBase(bind_state) { |
| + |
| + // Force the assignment to a local variable of PolymorphicInvoke |
| // so the compiler will typecheck that the passed in Run() method has |
| // the correct type. |
| - PolymorphicInvoke invoke_func = &T::InvokerType::Run; |
| + PolymorphicInvoke invoke_func = |
| + &internal::BindState<Runnable, RunType, BoundArgsType> |
| + ::InvokerType::Run; |
| polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func); |
| } |
| @@ -320,22 +319,20 @@ class Callback<R(A1, A2)> : public internal::CallbackBase { |
| public: |
| typedef R(RunType)(A1, A2); |
| - Callback() : CallbackBase(NULL, NULL) { } |
| + Callback() : CallbackBase(NULL) { } |
| - // We pass BindStateHolder by const ref to avoid incurring an |
| - // unnecessary AddRef/Unref pair even though we will modify the object. |
| - // We cannot use a normal reference because the compiler will warn |
| - // since this is often used on a return value, which is a temporary. |
| - // |
| // Note that this constructor CANNOT be explicit, and that Bind() CANNOT |
| // return the exact Callback<> type. See base/bind.h for details. |
| - template <typename T> |
| - Callback(const internal::BindStateHolder<T>& bind_state_holder) |
| - : CallbackBase(NULL, &bind_state_holder.bind_state_) { |
| - // Force the assignment to a location variable of PolymorphicInvoke |
| + template <typename Runnable, typename RunType, typename BoundArgsType> |
| + Callback(internal::BindState<Runnable, RunType, BoundArgsType>* bind_state) |
| + : CallbackBase(bind_state) { |
| + |
| + // Force the assignment to a local variable of PolymorphicInvoke |
| // so the compiler will typecheck that the passed in Run() method has |
| // the correct type. |
| - PolymorphicInvoke invoke_func = &T::InvokerType::Run; |
| + PolymorphicInvoke invoke_func = |
| + &internal::BindState<Runnable, RunType, BoundArgsType> |
| + ::InvokerType::Run; |
| polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func); |
| } |
| @@ -365,22 +362,20 @@ class Callback<R(A1, A2, A3)> : public internal::CallbackBase { |
| public: |
| typedef R(RunType)(A1, A2, A3); |
| - Callback() : CallbackBase(NULL, NULL) { } |
| + Callback() : CallbackBase(NULL) { } |
| - // We pass BindStateHolder by const ref to avoid incurring an |
| - // unnecessary AddRef/Unref pair even though we will modify the object. |
| - // We cannot use a normal reference because the compiler will warn |
| - // since this is often used on a return value, which is a temporary. |
| - // |
| // Note that this constructor CANNOT be explicit, and that Bind() CANNOT |
| // return the exact Callback<> type. See base/bind.h for details. |
| - template <typename T> |
| - Callback(const internal::BindStateHolder<T>& bind_state_holder) |
| - : CallbackBase(NULL, &bind_state_holder.bind_state_) { |
| - // Force the assignment to a location variable of PolymorphicInvoke |
| + template <typename Runnable, typename RunType, typename BoundArgsType> |
| + Callback(internal::BindState<Runnable, RunType, BoundArgsType>* bind_state) |
| + : CallbackBase(bind_state) { |
| + |
| + // Force the assignment to a local variable of PolymorphicInvoke |
| // so the compiler will typecheck that the passed in Run() method has |
| // the correct type. |
| - PolymorphicInvoke invoke_func = &T::InvokerType::Run; |
| + PolymorphicInvoke invoke_func = |
| + &internal::BindState<Runnable, RunType, BoundArgsType> |
| + ::InvokerType::Run; |
| polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func); |
| } |
| @@ -413,22 +408,20 @@ class Callback<R(A1, A2, A3, A4)> : public internal::CallbackBase { |
| public: |
| typedef R(RunType)(A1, A2, A3, A4); |
| - Callback() : CallbackBase(NULL, NULL) { } |
| + Callback() : CallbackBase(NULL) { } |
| - // We pass BindStateHolder by const ref to avoid incurring an |
| - // unnecessary AddRef/Unref pair even though we will modify the object. |
| - // We cannot use a normal reference because the compiler will warn |
| - // since this is often used on a return value, which is a temporary. |
| - // |
| // Note that this constructor CANNOT be explicit, and that Bind() CANNOT |
| // return the exact Callback<> type. See base/bind.h for details. |
| - template <typename T> |
| - Callback(const internal::BindStateHolder<T>& bind_state_holder) |
| - : CallbackBase(NULL, &bind_state_holder.bind_state_) { |
| - // Force the assignment to a location variable of PolymorphicInvoke |
| + template <typename Runnable, typename RunType, typename BoundArgsType> |
| + Callback(internal::BindState<Runnable, RunType, BoundArgsType>* bind_state) |
| + : CallbackBase(bind_state) { |
| + |
| + // Force the assignment to a local variable of PolymorphicInvoke |
| // so the compiler will typecheck that the passed in Run() method has |
| // the correct type. |
| - PolymorphicInvoke invoke_func = &T::InvokerType::Run; |
| + PolymorphicInvoke invoke_func = |
| + &internal::BindState<Runnable, RunType, BoundArgsType> |
| + ::InvokerType::Run; |
| polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func); |
| } |
| @@ -465,22 +458,20 @@ class Callback<R(A1, A2, A3, A4, A5)> : public internal::CallbackBase { |
| public: |
| typedef R(RunType)(A1, A2, A3, A4, A5); |
| - Callback() : CallbackBase(NULL, NULL) { } |
| + Callback() : CallbackBase(NULL) { } |
| - // We pass BindStateHolder by const ref to avoid incurring an |
| - // unnecessary AddRef/Unref pair even though we will modify the object. |
| - // We cannot use a normal reference because the compiler will warn |
| - // since this is often used on a return value, which is a temporary. |
| - // |
| // Note that this constructor CANNOT be explicit, and that Bind() CANNOT |
| // return the exact Callback<> type. See base/bind.h for details. |
| - template <typename T> |
| - Callback(const internal::BindStateHolder<T>& bind_state_holder) |
| - : CallbackBase(NULL, &bind_state_holder.bind_state_) { |
| - // Force the assignment to a location variable of PolymorphicInvoke |
| + template <typename Runnable, typename RunType, typename BoundArgsType> |
| + Callback(internal::BindState<Runnable, RunType, BoundArgsType>* bind_state) |
| + : CallbackBase(bind_state) { |
| + |
| + // Force the assignment to a local variable of PolymorphicInvoke |
| // so the compiler will typecheck that the passed in Run() method has |
| // the correct type. |
| - PolymorphicInvoke invoke_func = &T::InvokerType::Run; |
| + PolymorphicInvoke invoke_func = |
| + &internal::BindState<Runnable, RunType, BoundArgsType> |
| + ::InvokerType::Run; |
| polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func); |
| } |
| @@ -520,22 +511,20 @@ class Callback<R(A1, A2, A3, A4, A5, A6)> : public internal::CallbackBase { |
| public: |
| typedef R(RunType)(A1, A2, A3, A4, A5, A6); |
| - Callback() : CallbackBase(NULL, NULL) { } |
| + Callback() : CallbackBase(NULL) { } |
| - // We pass BindStateHolder by const ref to avoid incurring an |
| - // unnecessary AddRef/Unref pair even though we will modify the object. |
| - // We cannot use a normal reference because the compiler will warn |
| - // since this is often used on a return value, which is a temporary. |
| - // |
| // Note that this constructor CANNOT be explicit, and that Bind() CANNOT |
| // return the exact Callback<> type. See base/bind.h for details. |
| - template <typename T> |
| - Callback(const internal::BindStateHolder<T>& bind_state_holder) |
| - : CallbackBase(NULL, &bind_state_holder.bind_state_) { |
| - // Force the assignment to a location variable of PolymorphicInvoke |
| + template <typename Runnable, typename RunType, typename BoundArgsType> |
| + Callback(internal::BindState<Runnable, RunType, BoundArgsType>* bind_state) |
| + : CallbackBase(bind_state) { |
| + |
| + // Force the assignment to a local variable of PolymorphicInvoke |
| // so the compiler will typecheck that the passed in Run() method has |
| // the correct type. |
| - PolymorphicInvoke invoke_func = &T::InvokerType::Run; |
| + PolymorphicInvoke invoke_func = |
| + &internal::BindState<Runnable, RunType, BoundArgsType> |
| + ::InvokerType::Run; |
| polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func); |
| } |
| @@ -578,22 +567,20 @@ class Callback<R(A1, A2, A3, A4, A5, A6, A7)> : public internal::CallbackBase { |
| public: |
| typedef R(RunType)(A1, A2, A3, A4, A5, A6, A7); |
| - Callback() : CallbackBase(NULL, NULL) { } |
| + Callback() : CallbackBase(NULL) { } |
| - // We pass BindStateHolder by const ref to avoid incurring an |
| - // unnecessary AddRef/Unref pair even though we will modify the object. |
| - // We cannot use a normal reference because the compiler will warn |
| - // since this is often used on a return value, which is a temporary. |
| - // |
| // Note that this constructor CANNOT be explicit, and that Bind() CANNOT |
| // return the exact Callback<> type. See base/bind.h for details. |
| - template <typename T> |
| - Callback(const internal::BindStateHolder<T>& bind_state_holder) |
| - : CallbackBase(NULL, &bind_state_holder.bind_state_) { |
| - // Force the assignment to a location variable of PolymorphicInvoke |
| + template <typename Runnable, typename RunType, typename BoundArgsType> |
| + Callback(internal::BindState<Runnable, RunType, BoundArgsType>* bind_state) |
| + : CallbackBase(bind_state) { |
| + |
| + // Force the assignment to a local variable of PolymorphicInvoke |
| // so the compiler will typecheck that the passed in Run() method has |
| // the correct type. |
| - PolymorphicInvoke invoke_func = &T::InvokerType::Run; |
| + PolymorphicInvoke invoke_func = |
| + &internal::BindState<Runnable, RunType, BoundArgsType> |
| + ::InvokerType::Run; |
| polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func); |
| } |