summaryrefslogtreecommitdiffstats
path: root/base/callback.h.pump
diff options
context:
space:
mode:
authorajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-21 19:23:44 +0000
committerajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-21 19:23:44 +0000
commit7296f2763bd40e560466f09836c7208c42d90f94 (patch)
tree142a03c36f75f42738206355a029707ad88cdffc /base/callback.h.pump
parent1fbbf963079bc977ea041b7e50ddf4666f6fec38 (diff)
downloadchromium_src-7296f2763bd40e560466f09836c7208c42d90f94.zip
chromium_src-7296f2763bd40e560466f09836c7208c42d90f94.tar.gz
chromium_src-7296f2763bd40e560466f09836c7208c42d90f94.tar.bz2
Callback API Change: Reimplement Bind(); support IgnoreResult, full currying, and use less types.
The main API change IgnoreResult() and fully currying. See unittest for what the new API looks like. The rest of the changes are done to support that. Previously, IgnoreReturn could not be used with WeakPtr<> Bind()s as it was applied after the fact to the Callback object. Now, IgnoreResult() wraps the function like Unretained(). As an incidental benefit, the new implementation gave us fully currying for free. Also, the new implementation scales better when supporting higher arities of functions. The new type growth is: (n^2 + 20n) / 2 as opposed to (3n^2 + 17n) / 2 where n == arity. For n = 6 and n=10, the new implementation has 81 and 155 templates respectively. The old implementation had 105 and 235 templates respectively. BUG=35233,98919,98542 TEST=existing unittests Review URL: http://codereview.chromium.org/8483003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110975 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/callback.h.pump')
-rw-r--r--base/callback.h.pump46
1 files changed, 25 insertions, 21 deletions
diff --git a/base/callback.h.pump b/base/callback.h.pump
index 8aecdc8..eee3371 100644
--- a/base/callback.h.pump
+++ b/base/callback.h.pump
@@ -129,26 +129,26 @@ $var MAX_ARITY = 6
// 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 InvokerStorageHolder<> object. In the context of
-// the constructor, the static type of this InvokerStorageHolder<> object
+// 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 InvokerStorageHolder<> that has the
+// 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 InvokerStorageHolder<> to a
-// InvokerStorageBase. This is safe as long as this InvokerStorageBase pointer
+// 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 InvokerStorageHolder<> objects, we use the Bind() functions.
+// To create BindStateHolder<> objects, we use the Bind() functions.
// These functions, along with a set of internal templates, are reponsible for
//
// - Unwrapping the function signature into return type, and parameters
// - Determining the number of parameters that are bound
// - Creating the storage for the bound parameters
// - Performing compile-time asserts to avoid error-prone behavior
-// - Returning an InvokerStorageHolder<> with an DoInvoke() that has an arity
+// - 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.
@@ -250,14 +250,11 @@ class Callback<R($for ARG , [[A$(ARG)]])> : public internal::CallbackBase {
]]
public:
- typedef R(*PolymorphicInvoke)(
- internal::InvokerStorageBase*[[]]
-$if ARITY != 0 [[, ]]
-$for ARG , [[typename internal::ParamTraits<A$(ARG)>::ForwardType]]);
+ typedef R(RunType)($for ARG , [[A$(ARG)]]);
Callback() : CallbackBase(NULL, NULL) { }
- // We pass InvokerStorageHolder by const ref to avoid incurring an
+ // 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.
@@ -265,13 +262,13 @@ $for ARG , [[typename internal::ParamTraits<A$(ARG)>::ForwardType]]);
// 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::InvokerStorageHolder<T>& invoker_holder)
- : CallbackBase(
- reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
- &invoker_holder.invoker_storage_) {
- COMPILE_ASSERT((is_same<PolymorphicInvoke,
- typename T::Invoker::DoInvokeType>::value),
- callback_type_does_not_match_bind_result);
+ Callback(const internal::BindStateHolder<T>& bind_state_holder)
+ : CallbackBase(NULL, &bind_state_holder.bind_state_) {
+ // Force the assignment to a location variable of PolymorphicInvoke
+ // so the compiler will typecheck that the passed in Run() method has
+ // the correct type.
+ PolymorphicInvoke invoke_func = &T::InvokerType::Run;
+ polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
}
bool Equals(const Callback& other) const {
@@ -279,15 +276,22 @@ $for ARG , [[typename internal::ParamTraits<A$(ARG)>::ForwardType]]);
}
R Run($for ARG ,
- [[typename internal::ParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) const {
+ [[typename internal::CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(invoker_storage_.get()[[]]
+ return f(bind_state_.get()[[]]
$if ARITY != 0 [[, ]]
$for ARG ,
[[a$(ARG)]]);
}
+
+ private:
+ typedef R(*PolymorphicInvoke)(
+ internal::BindStateBase*[[]]
+$if ARITY != 0 [[, ]]
+$for ARG , [[typename internal::CallbackParamTraits<A$(ARG)>::ForwardType]]);
+
};