blob: 7f9b54843b2e77326347f5f95fb2de01f295505d [file] [log] [blame]
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001// This file was GENERATED by command:
2// pump.py callback.h.pump
3// DO NOT EDIT BY HAND!!!
4
5
ajwong@chromium.orga7e74822011-03-24 11:02:17 +09006
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09007// Copyright (c) 2011 The Chromium Authors. All rights reserved.
akalin@chromium.org6ed4f882010-02-19 12:15:59 +09008// Use of this source code is governed by a BSD-style license that can be
9// found in the LICENSE file.
10
11#ifndef BASE_CALLBACK_H_
12#define BASE_CALLBACK_H_
thakis@chromium.org01d14522010-07-27 08:08:24 +090013#pragma once
akalin@chromium.org6ed4f882010-02-19 12:15:59 +090014
ajwong@chromium.orgfa0ff432011-02-19 08:29:31 +090015#include "base/callback_internal.h"
akalin@chromium.org6ed4f882010-02-19 12:15:59 +090016
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090017// New, super-duper, unified Callback system. This will eventually replace
18// NewRunnableMethod, NewRunnableFunction, CreateFunctor, and CreateCallback
19// systems currently in the Chromium code base.
akalin@chromium.org6ed4f882010-02-19 12:15:59 +090020//
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090021// WHAT IS THIS:
akalin@chromium.org6ed4f882010-02-19 12:15:59 +090022//
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090023// The templated Callback class is a generalized function object. Together
24// with the Bind() function in bind.h, they provide a type-safe method for
25// performing currying of arguments, and creating a "closure."
akalin@chromium.org6ed4f882010-02-19 12:15:59 +090026//
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090027// In programing languages, a closure is a first-class function where all its
28// parameters have been bound (usually via currying). Closures are well
29// suited for representing, and passing around a unit of delayed execution.
30// They are used in Chromium code to schedule tasks on different MessageLoops.
akalin@chromium.org6ed4f882010-02-19 12:15:59 +090031//
akalin@chromium.org6ed4f882010-02-19 12:15:59 +090032//
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090033// MEMORY MANAGEMENT AND PASSING
akalin@chromium.org6ed4f882010-02-19 12:15:59 +090034//
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090035// The Callback objects themselves should be passed by const-reference, and
36// stored by copy. They internally store their state via a refcounted class
37// and thus do not need to be deleted.
akalin@chromium.org6ed4f882010-02-19 12:15:59 +090038//
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090039// The reason to pass via a const-reference is to avoid unnecessary
40// AddRef/Release pairs to the internal state.
41//
42//
43// EXAMPLE USAGE:
44//
45// /* Binding a normal function. */
46// int Return5() { return 5; }
dilmah@chromium.org1d0d1d62011-04-14 22:11:17 +090047// base::Callback<int(void)> func_cb = base::Bind(&Return5);
48// LOG(INFO) << func_cb.Run(); // Prints 5.
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090049//
50// void PrintHi() { LOG(INFO) << "hi."; }
51// base::Closure void_func_cb = base::Bind(&PrintHi);
ajwong@chromium.orgc711b822011-05-17 07:35:14 +090052// void_func_cb.Run(); // Prints: hi.
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090053//
54// /* Binding a class method. */
55// class Ref : public RefCountedThreadSafe<Ref> {
56// public:
57// int Foo() { return 3; }
58// void PrintBye() { LOG(INFO) << "bye."; }
59// };
60// scoped_refptr<Ref> ref = new Ref();
61// base::Callback<int(void)> ref_cb = base::Bind(&Ref::Foo, ref.get());
62// LOG(INFO) << ref_cb.Run(); // Prints out 3.
63//
64// base::Closure void_ref_cb = base::Bind(&Ref::PrintBye, ref.get());
65// void_ref_cb.Run(); // Prints: bye.
66//
67// /* Binding a class method in a non-refcounted class.
68// *
69// * WARNING: You must be sure the referee outlives the callback!
70// * This is particularly important if you post a closure to a
71// * MessageLoop because then it becomes hard to know what the
72// * lifetime of the referee needs to be.
73// */
74// class NoRef {
75// public:
76// int Foo() { return 4; }
77// void PrintWhy() { LOG(INFO) << "why???"; }
78// };
79// NoRef no_ref;
80// base::Callback<int(void)> base::no_ref_cb =
81// base::Bind(&NoRef::Foo, base::Unretained(&no_ref));
82// LOG(INFO) << ref_cb.Run(); // Prints out 4.
83//
84// base::Closure void_no_ref_cb =
85// base::Bind(&NoRef::PrintWhy, base::Unretained(no_ref));
86// void_no_ref_cb.Run(); // Prints: why???
87//
88// /* Binding a reference. */
89// int Identity(int n) { return n; }
90// int value = 1;
91// base::Callback<int(void)> bound_copy_cb = base::Bind(&Identity, value);
92// base::Callback<int(void)> bound_ref_cb =
93// base::Bind(&Identity, base::ConstRef(value));
94// LOG(INFO) << bound_copy_cb.Run(); // Prints 1.
95// LOG(INFO) << bound_ref_cb.Run(); // Prints 1.
96// value = 2;
97// LOG(INFO) << bound_copy_cb.Run(); // Prints 1.
98// LOG(INFO) << bound_ref_cb.Run(); // Prints 2.
99//
ajwong@chromium.org97d22e32011-05-19 05:21:12 +0900100// /* Currying parameters. This also works for methods. */
101// int Sum(int a, int b, int c) {
102// return a + b + c;
103// }
104// base::Callback<int(int, int)> sum3_cb = base::Bind(&Sum, 3);
105// LOG(INFO) << sum3_cb.Run(4, 5); // Prints 12.
106//
107// base::Callback<int(int)> sum7_cb = base::Bind(&Sum, 3, 4);
108// LOG(INFO) << sum7_cb.Run(10); // Prints 17.
109//
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900110//
111// WHERE IS THIS DESIGN FROM:
112//
113// The design Callback and Bind is heavily influenced by C++'s
114// tr1::function/tr1::bind, and by the "Google Callback" system used inside
115// Google.
116//
117//
118// HOW THE IMPLEMENTATION WORKS:
119//
120// There are three main components to the system:
121// 1) The Callback classes.
122// 2) The Bind() functions.
123// 3) The arguments wrappers (eg., Unretained() and ConstRef()).
124//
125// The Callback classes represent a generic function pointer. Internally,
126// it stores a refcounted piece of state that represents the target function
127// and all its bound parameters. Each Callback specialization has a templated
128// constructor that takes an InvokerStorageHolder<> object. In the context of
129// the constructor, the static type of this InvokerStorageHolder<> object
130// uniquely identifies the function it is representing, all its bound
131// parameters, and a DoInvoke() that is capable of invoking the target.
132//
133// Callback's constructor is takes the InvokerStorageHolder<> that has the
134// full static type and erases the target function type, and the bound
135// parameters. It does this by storing a pointer to the specific DoInvoke()
136// function, and upcasting the state of InvokerStorageHolder<> to a
137// InvokerStorageBase. This is safe as long as this InvokerStorageBase pointer
138// is only used with the stored DoInvoke() pointer.
139//
140// To create InvokerStorageHolder<> objects, we use the Bind() functions.
141// These functions, along with a set of internal templates, are reponsible for
142//
143// - Unwrapping the function signature into return type, and parameters
144// - Determining the number of parameters that are bound
145// - Creating the storage for the bound parameters
146// - Performing compile-time asserts to avoid error-prone behavior
147// - Returning an InvokerStorageHolder<> with an DoInvoke() that has an arity
148// matching the number of unbound parameters, and knows the correct
149// refcounting semantics for the target object if we are binding a class
150// method.
151//
152// The Bind functions do the above using type-inference, and template
153// specializations.
154//
155// By default Bind() will store copies of all bound parameters, and attempt
156// to refcount a target object if the function being bound is a class method.
157//
158// To change this behavior, we introduce a set of argument wrappers
159// (eg. Unretained(), and ConstRef()). These are simple container templates
160// that are passed by value, and wrap a pointer to argument. See the
161// file-level comment in base/bind_helpers.h for more info.
162//
163// These types are passed to the Unwrap() functions, and the MaybeRefcount()
164// functions respectively to modify the behavior of Bind(). The Unwrap()
165// and MaybeRefcount() functions change behavior by doing partial
166// specialization based on whether or not a parameter is a wrapper type.
167//
168// ConstRef() is similar to tr1::cref. Unretained() is specific to Chromium.
169//
170//
171// WHY NOT TR1 FUNCTION/BIND?
172//
173// Direct use of tr1::function and tr1::bind was considered, but ultimately
174// rejected because of the number of copy constructors invocations involved
175// in the binding of arguments during construction, and the forwarding of
176// arguments during invocation. These copies will no longer be an issue in
177// C++0x because C++0x will support rvalue reference allowing for the compiler
178// to avoid these copies. However, waiting for C++0x is not an option.
179//
180// Measured with valgrind on gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5), the
181// tr1::bind call itself will invoke a non-trivial copy constructor three times
182// for each bound parameter. Also, each when passing a tr1::function, each
183// bound argument will be copied again.
184//
185// In addition to the copies taken at binding and invocation, copying a
186// tr1::function causes a copy to be made of all the bound parameters and
187// state.
188//
189// Furthermore, in Chromium, it is desirable for the Callback to take a
190// reference on a target object when representing a class method call. This
191// is not supported by tr1.
192//
193// Lastly, tr1::function and tr1::bind has a more general and flexible API.
194// This includes things like argument reordering by use of
195// tr1::bind::placeholder, support for non-const reference parameters, and some
196// limited amount of subtyping of the tr1::function object (eg.,
197// tr1::function<int(int)> is convertible to tr1::function<void(int)>).
198//
199// These are not features that are required in Chromium. Some of them, such as
200// allowing for reference parameters, and subtyping of functions, may actually
thakis@chromium.org21cbe222011-04-20 03:22:00 +0900201// become a source of errors. Removing support for these features actually
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900202// allows for a simpler implementation, and a terser Currying API.
203//
204//
205// WHY NOT GOOGLE CALLBACKS?
206//
207// The Google callback system also does not support refcounting. Furthermore,
208// its implementation has a number of strange edge cases with respect to type
209// conversion of its arguments. In particular, the argument's constness must
210// at times match exactly the function signature, or the type-inference might
211// break. Given the above, writing a custom solution was easier.
212//
213//
214// MISSING FUNCTIONALITY
215// - Invoking the return of Bind. Bind(&foo).Run() does not work;
216// - Binding arrays to functions that take a non-const pointer.
217// Example:
218// void Foo(const char* ptr);
219// void Bar(char* ptr);
220// Bind(&Foo, "test");
221// Bind(&Bar, "test"); // This fails because ptr is not const.
akalin@chromium.org6ed4f882010-02-19 12:15:59 +0900222
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900223namespace base {
224
225// First, we forward declare the Callback class template. This informs the
226// compiler that the template only has 1 type parameter which is the function
227// signature that the Callback is representing.
228//
229// After this, create template specializations for 0-6 parameters. Note that
230// even though the template typelist grows, the specialization still
231// only has one type: the function signature.
232template <typename Sig>
233class Callback;
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900234
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900235template <typename R>
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900236class Callback<R(void)> : public internal::CallbackBase {
akalin@chromium.org6ed4f882010-02-19 12:15:59 +0900237 public:
ajwong@chromium.orga7e74822011-03-24 11:02:17 +0900238 typedef R(*PolymorphicInvoke)(
239 internal::InvokerStorageBase*);
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900240
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900241 Callback() : CallbackBase(NULL, NULL) { }
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900242
243 // We pass InvokerStorageHolder by const ref to avoid incurring an
244 // unnecessary AddRef/Unref pair even though we will modify the object.
245 // We cannot use a normal reference because the compiler will warn
246 // since this is often used on a return value, which is a temporary.
247 //
248 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
249 // return the exact Callback<> type. See base/bind.h for details.
250 template <typename T>
251 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900252 : CallbackBase(
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900253 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900254 &invoker_holder.invoker_storage_) {
akalin@chromium.org6ed4f882010-02-19 12:15:59 +0900255 }
256
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900257 R Run() const {
258 PolymorphicInvoke f =
259 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
akalin@chromium.org6ed4f882010-02-19 12:15:59 +0900260
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900261 return f(invoker_storage_.get());
262 }
akalin@chromium.org6ed4f882010-02-19 12:15:59 +0900263};
264
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900265template <typename R, typename A1>
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900266class Callback<R(A1)> : public internal::CallbackBase {
akalin@chromium.org6ed4f882010-02-19 12:15:59 +0900267 public:
ajwong@chromium.orga7e74822011-03-24 11:02:17 +0900268 typedef R(*PolymorphicInvoke)(
269 internal::InvokerStorageBase*,
270 typename internal::ParamTraits<A1>::ForwardType);
akalin@chromium.org6ed4f882010-02-19 12:15:59 +0900271
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900272 Callback() : CallbackBase(NULL, NULL) { }
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900273
274 // We pass InvokerStorageHolder by const ref to avoid incurring an
275 // unnecessary AddRef/Unref pair even though we will modify the object.
276 // We cannot use a normal reference because the compiler will warn
277 // since this is often used on a return value, which is a temporary.
278 //
279 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
280 // return the exact Callback<> type. See base/bind.h for details.
281 template <typename T>
282 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900283 : CallbackBase(
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900284 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900285 &invoker_holder.invoker_storage_) {
akalin@chromium.org6ed4f882010-02-19 12:15:59 +0900286 }
287
ajwong@chromium.orga7e74822011-03-24 11:02:17 +0900288 R Run(typename internal::ParamTraits<A1>::ForwardType a1) const {
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900289 PolymorphicInvoke f =
290 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900291
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900292 return f(invoker_storage_.get(), a1);
293 }
akalin@chromium.org6ed4f882010-02-19 12:15:59 +0900294};
295
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900296template <typename R, typename A1, typename A2>
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900297class Callback<R(A1, A2)> : public internal::CallbackBase {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900298 public:
ajwong@chromium.orga7e74822011-03-24 11:02:17 +0900299 typedef R(*PolymorphicInvoke)(
300 internal::InvokerStorageBase*,
301 typename internal::ParamTraits<A1>::ForwardType,
302 typename internal::ParamTraits<A2>::ForwardType);
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900303
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900304 Callback() : CallbackBase(NULL, NULL) { }
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900305
306 // We pass InvokerStorageHolder by const ref to avoid incurring an
307 // unnecessary AddRef/Unref pair even though we will modify the object.
308 // We cannot use a normal reference because the compiler will warn
309 // since this is often used on a return value, which is a temporary.
310 //
311 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
312 // return the exact Callback<> type. See base/bind.h for details.
313 template <typename T>
314 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900315 : CallbackBase(
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900316 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900317 &invoker_holder.invoker_storage_) {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900318 }
319
ajwong@chromium.orga7e74822011-03-24 11:02:17 +0900320 R Run(typename internal::ParamTraits<A1>::ForwardType a1,
321 typename internal::ParamTraits<A2>::ForwardType a2) const {
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900322 PolymorphicInvoke f =
323 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900324
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900325 return f(invoker_storage_.get(), a1,
326 a2);
327 }
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900328};
329
330template <typename R, typename A1, typename A2, typename A3>
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900331class Callback<R(A1, A2, A3)> : public internal::CallbackBase {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900332 public:
ajwong@chromium.orga7e74822011-03-24 11:02:17 +0900333 typedef R(*PolymorphicInvoke)(
334 internal::InvokerStorageBase*,
335 typename internal::ParamTraits<A1>::ForwardType,
336 typename internal::ParamTraits<A2>::ForwardType,
337 typename internal::ParamTraits<A3>::ForwardType);
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900338
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900339 Callback() : CallbackBase(NULL, NULL) { }
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900340
341 // We pass InvokerStorageHolder by const ref to avoid incurring an
342 // unnecessary AddRef/Unref pair even though we will modify the object.
343 // We cannot use a normal reference because the compiler will warn
344 // since this is often used on a return value, which is a temporary.
345 //
346 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
347 // return the exact Callback<> type. See base/bind.h for details.
348 template <typename T>
349 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900350 : CallbackBase(
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900351 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900352 &invoker_holder.invoker_storage_) {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900353 }
354
ajwong@chromium.orga7e74822011-03-24 11:02:17 +0900355 R Run(typename internal::ParamTraits<A1>::ForwardType a1,
356 typename internal::ParamTraits<A2>::ForwardType a2,
357 typename internal::ParamTraits<A3>::ForwardType a3) const {
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900358 PolymorphicInvoke f =
359 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900360
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900361 return f(invoker_storage_.get(), a1,
362 a2,
363 a3);
364 }
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900365};
366
367template <typename R, typename A1, typename A2, typename A3, typename A4>
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900368class Callback<R(A1, A2, A3, A4)> : public internal::CallbackBase {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900369 public:
ajwong@chromium.orga7e74822011-03-24 11:02:17 +0900370 typedef R(*PolymorphicInvoke)(
371 internal::InvokerStorageBase*,
372 typename internal::ParamTraits<A1>::ForwardType,
373 typename internal::ParamTraits<A2>::ForwardType,
374 typename internal::ParamTraits<A3>::ForwardType,
375 typename internal::ParamTraits<A4>::ForwardType);
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900376
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900377 Callback() : CallbackBase(NULL, NULL) { }
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900378
379 // We pass InvokerStorageHolder by const ref to avoid incurring an
380 // unnecessary AddRef/Unref pair even though we will modify the object.
381 // We cannot use a normal reference because the compiler will warn
382 // since this is often used on a return value, which is a temporary.
383 //
384 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
385 // return the exact Callback<> type. See base/bind.h for details.
386 template <typename T>
387 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900388 : CallbackBase(
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900389 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900390 &invoker_holder.invoker_storage_) {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900391 }
392
ajwong@chromium.orga7e74822011-03-24 11:02:17 +0900393 R Run(typename internal::ParamTraits<A1>::ForwardType a1,
394 typename internal::ParamTraits<A2>::ForwardType a2,
395 typename internal::ParamTraits<A3>::ForwardType a3,
396 typename internal::ParamTraits<A4>::ForwardType a4) const {
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900397 PolymorphicInvoke f =
398 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900399
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900400 return f(invoker_storage_.get(), a1,
401 a2,
402 a3,
403 a4);
404 }
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900405};
406
407template <typename R, typename A1, typename A2, typename A3, typename A4,
408 typename A5>
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900409class Callback<R(A1, A2, A3, A4, A5)> : public internal::CallbackBase {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900410 public:
ajwong@chromium.orga7e74822011-03-24 11:02:17 +0900411 typedef R(*PolymorphicInvoke)(
412 internal::InvokerStorageBase*,
413 typename internal::ParamTraits<A1>::ForwardType,
414 typename internal::ParamTraits<A2>::ForwardType,
415 typename internal::ParamTraits<A3>::ForwardType,
416 typename internal::ParamTraits<A4>::ForwardType,
417 typename internal::ParamTraits<A5>::ForwardType);
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900418
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900419 Callback() : CallbackBase(NULL, NULL) { }
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900420
421 // We pass InvokerStorageHolder by const ref to avoid incurring an
422 // unnecessary AddRef/Unref pair even though we will modify the object.
423 // We cannot use a normal reference because the compiler will warn
424 // since this is often used on a return value, which is a temporary.
425 //
426 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
427 // return the exact Callback<> type. See base/bind.h for details.
428 template <typename T>
429 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900430 : CallbackBase(
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900431 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900432 &invoker_holder.invoker_storage_) {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900433 }
434
ajwong@chromium.orga7e74822011-03-24 11:02:17 +0900435 R Run(typename internal::ParamTraits<A1>::ForwardType a1,
436 typename internal::ParamTraits<A2>::ForwardType a2,
437 typename internal::ParamTraits<A3>::ForwardType a3,
438 typename internal::ParamTraits<A4>::ForwardType a4,
439 typename internal::ParamTraits<A5>::ForwardType a5) const {
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900440 PolymorphicInvoke f =
441 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900442
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900443 return f(invoker_storage_.get(), a1,
444 a2,
445 a3,
446 a4,
447 a5);
448 }
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900449};
450
451template <typename R, typename A1, typename A2, typename A3, typename A4,
452 typename A5, typename A6>
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900453class Callback<R(A1, A2, A3, A4, A5, A6)> : public internal::CallbackBase {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900454 public:
ajwong@chromium.orga7e74822011-03-24 11:02:17 +0900455 typedef R(*PolymorphicInvoke)(
456 internal::InvokerStorageBase*,
457 typename internal::ParamTraits<A1>::ForwardType,
458 typename internal::ParamTraits<A2>::ForwardType,
459 typename internal::ParamTraits<A3>::ForwardType,
460 typename internal::ParamTraits<A4>::ForwardType,
461 typename internal::ParamTraits<A5>::ForwardType,
462 typename internal::ParamTraits<A6>::ForwardType);
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900463
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900464 Callback() : CallbackBase(NULL, NULL) { }
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900465
466 // We pass InvokerStorageHolder by const ref to avoid incurring an
467 // unnecessary AddRef/Unref pair even though we will modify the object.
468 // We cannot use a normal reference because the compiler will warn
469 // since this is often used on a return value, which is a temporary.
470 //
471 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
472 // return the exact Callback<> type. See base/bind.h for details.
473 template <typename T>
474 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900475 : CallbackBase(
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900476 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900477 &invoker_holder.invoker_storage_) {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900478 }
479
ajwong@chromium.orga7e74822011-03-24 11:02:17 +0900480 R Run(typename internal::ParamTraits<A1>::ForwardType a1,
481 typename internal::ParamTraits<A2>::ForwardType a2,
482 typename internal::ParamTraits<A3>::ForwardType a3,
483 typename internal::ParamTraits<A4>::ForwardType a4,
484 typename internal::ParamTraits<A5>::ForwardType a5,
485 typename internal::ParamTraits<A6>::ForwardType a6) const {
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900486 PolymorphicInvoke f =
487 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900488
ajwong@chromium.org62fb0a02011-02-18 13:05:14 +0900489 return f(invoker_storage_.get(), a1,
490 a2,
491 a3,
492 a4,
493 a5,
494 a6);
495 }
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900496};
497
498
499// Syntactic sugar to make Callbacks<void(void)> easier to declare since it
500// will be used in a lot of APIs with delayed execution.
501typedef Callback<void(void)> Closure;
502
503} // namespace base
akalin@chromium.org6ed4f882010-02-19 12:15:59 +0900504
505#endif // BASE_CALLBACK_H