Index: base/callback.h.pump |
diff --git a/base/callback.h.pump b/base/callback.h.pump |
index 9fc4b0b0ce9743e862defe7314fb6188919e4334..19b7987b6b7eedafc0f7cd83a39f54a25e62e6a2 100644 |
--- a/base/callback.h.pump |
+++ b/base/callback.h.pump |
@@ -216,6 +216,49 @@ $var MAX_ARITY = 6 |
namespace base { |
+namespace internal { |
+ |
+// Holds the methods that don't require specialization to reduce template bloat. |
+class CallbackBase { |
+ public: |
+ // Returns true if Callback is null (doesn't refer to anything). |
+ bool is_null() const { |
+ return invoker_storage_.get() == NULL; |
+ } |
+ |
+ // Returns the Callback into an uninitalized state. |
+ void Reset() { |
+ invoker_storage_ = NULL; |
+ polymorphic_invoke_ = NULL; |
+ } |
+ |
+ bool Equals(const CallbackBase& other) const { |
+ return invoker_storage_.get() == other.invoker_storage_.get() && |
+ polymorphic_invoke_ == other.polymorphic_invoke_; |
+ } |
+ |
+ protected: |
+ // In C++, it is safe to cast function pointers to function pointers of |
+ // another type. It is not okay to use void*. We create a InvokeFuncStorage |
+ // that that can store our function pointer, and then cast it back to |
+ // the original type on usage. |
+ typedef void(*InvokeFuncStorage)(void); |
+ |
+ CallbackBase(InvokeFuncStorage polymorphic_invoke, |
+ scoped_refptr<InvokerStorageBase>* invoker_storage) |
+ : polymorphic_invoke_(polymorphic_invoke) { |
+ if (invoker_storage) { |
+ invoker_storage_.swap(*invoker_storage); |
+ } |
+ } |
+ |
+ scoped_refptr<InvokerStorageBase> invoker_storage_; |
+ InvokeFuncStorage polymorphic_invoke_; |
+}; |
+ |
+} // namespace internal |
+ |
+ |
// First, we forward declare the Callback class template. This informs the |
// compiler that the template only has 1 type parameter which is the function |
// signature that the Callback is representing. |
@@ -226,17 +269,16 @@ namespace base { |
template <typename Sig> |
class Callback; |
- |
$range ARITY 0..MAX_ARITY |
$for ARITY [[ |
$range ARG 1..ARITY |
$if ARITY == 0 [[ |
template <typename R> |
-class Callback<R(void)> { |
+class Callback<R(void)> : public internal::CallbackBase { |
]] $else [[ |
template <typename R, $for ARG , [[typename A$(ARG)]]> |
-class Callback<R($for ARG , [[A$(ARG)]])> { |
+class Callback<R($for ARG , [[A$(ARG)]])> : public internal::CallbackBase { |
]] |
public: |
@@ -245,7 +287,7 @@ $if ARITY != 0 [[, ]] |
$for ARG , |
[[const A$(ARG)&]]); |
- Callback() : polymorphic_invoke_(NULL) { } |
+ Callback() : CallbackBase(NULL, NULL) { } |
// We pass InvokerStorageHolder by const ref to avoid incurring an |
// unnecessary AddRef/Unref pair even though we will modify the object. |
@@ -256,27 +298,21 @@ $for ARG , |
// return the exact Callback<> type. See base/bind.h for details. |
template <typename T> |
Callback(const internal::InvokerStorageHolder<T>& invoker_holder) |
- : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) { |
- invoker_storage_.swap(invoker_holder.invoker_storage_); |
+ : CallbackBase( |
+ reinterpret_cast<InvokeFuncStorage>(&T::FunctionTraits::DoInvoke), |
+ &invoker_holder.invoker_storage_) { |
} |
- |
-$if ARITY == 0 [[ |
- R Run(void) const { |
-]] $else [[ |
R Run($for ARG , |
[[const A$(ARG)& a$(ARG)]]) const { |
-]] |
+ PolymorphicInvoke f = |
+ reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_); |
- return polymorphic_invoke_(invoker_storage_.get()[[]] |
+ return f(invoker_storage_.get()[[]] |
$if ARITY != 0 [[, ]] |
$for ARG , |
- [[a$(ARG)]]); |
+ [[a$(ARG)]]); |
} |
- |
- private: |
- scoped_refptr<internal::InvokerStorageBase> invoker_storage_; |
- PolymorphicInvoke polymorphic_invoke_; |
}; |