blob: dafbc0cef5e167aaa1ef4472766f0087668da16a [file] [log] [blame]
[email protected]b38d3572011-02-15 01:27:381// This file was GENERATED by command:
2// pump.py callback.h.pump
3// DO NOT EDIT BY HAND!!!
4
5
[email protected]c18b1052011-03-24 02:02:176
[email protected]b38d3572011-02-15 01:27:387// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]2041cf342010-02-19 03:15:598// 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_
[email protected]32b76ef2010-07-26 23:08:2413#pragma once
[email protected]2041cf342010-02-19 03:15:5914
[email protected]59eff912011-02-18 23:29:3115#include "base/callback_internal.h"
[email protected]b38d3572011-02-15 01:27:3816#include "base/callback_old.h"
[email protected]2041cf342010-02-19 03:15:5917
[email protected]b38d3572011-02-15 01:27:3818// New, super-duper, unified Callback system. This will eventually replace
19// NewRunnableMethod, NewRunnableFunction, CreateFunctor, and CreateCallback
20// systems currently in the Chromium code base.
[email protected]2041cf342010-02-19 03:15:5921//
[email protected]b38d3572011-02-15 01:27:3822// WHAT IS THIS:
[email protected]2041cf342010-02-19 03:15:5923//
[email protected]b38d3572011-02-15 01:27:3824// The templated Callback class is a generalized function object. Together
25// with the Bind() function in bind.h, they provide a type-safe method for
26// performing currying of arguments, and creating a "closure."
[email protected]2041cf342010-02-19 03:15:5927//
[email protected]b38d3572011-02-15 01:27:3828// In programing languages, a closure is a first-class function where all its
29// parameters have been bound (usually via currying). Closures are well
30// suited for representing, and passing around a unit of delayed execution.
31// They are used in Chromium code to schedule tasks on different MessageLoops.
[email protected]2041cf342010-02-19 03:15:5932//
[email protected]2041cf342010-02-19 03:15:5933//
[email protected]b38d3572011-02-15 01:27:3834// MEMORY MANAGEMENT AND PASSING
[email protected]2041cf342010-02-19 03:15:5935//
[email protected]b38d3572011-02-15 01:27:3836// The Callback objects themselves should be passed by const-reference, and
37// stored by copy. They internally store their state via a refcounted class
38// and thus do not need to be deleted.
[email protected]2041cf342010-02-19 03:15:5939//
[email protected]b38d3572011-02-15 01:27:3840// The reason to pass via a const-reference is to avoid unnecessary
41// AddRef/Release pairs to the internal state.
42//
43//
44// EXAMPLE USAGE:
45//
46// /* Binding a normal function. */
47// int Return5() { return 5; }
[email protected]05f967492011-04-14 13:11:1748// base::Callback<int(void)> func_cb = base::Bind(&Return5);
49// LOG(INFO) << func_cb.Run(); // Prints 5.
[email protected]b38d3572011-02-15 01:27:3850//
51// void PrintHi() { LOG(INFO) << "hi."; }
52// base::Closure void_func_cb = base::Bind(&PrintHi);
53// LOG(INFO) << void_func_cb.Run(); // Prints: hi.
54//
55// /* Binding a class method. */
56// class Ref : public RefCountedThreadSafe<Ref> {
57// public:
58// int Foo() { return 3; }
59// void PrintBye() { LOG(INFO) << "bye."; }
60// };
61// scoped_refptr<Ref> ref = new Ref();
62// base::Callback<int(void)> ref_cb = base::Bind(&Ref::Foo, ref.get());
63// LOG(INFO) << ref_cb.Run(); // Prints out 3.
64//
65// base::Closure void_ref_cb = base::Bind(&Ref::PrintBye, ref.get());
66// void_ref_cb.Run(); // Prints: bye.
67//
68// /* Binding a class method in a non-refcounted class.
69// *
70// * WARNING: You must be sure the referee outlives the callback!
71// * This is particularly important if you post a closure to a
72// * MessageLoop because then it becomes hard to know what the
73// * lifetime of the referee needs to be.
74// */
75// class NoRef {
76// public:
77// int Foo() { return 4; }
78// void PrintWhy() { LOG(INFO) << "why???"; }
79// };
80// NoRef no_ref;
81// base::Callback<int(void)> base::no_ref_cb =
82// base::Bind(&NoRef::Foo, base::Unretained(&no_ref));
83// LOG(INFO) << ref_cb.Run(); // Prints out 4.
84//
85// base::Closure void_no_ref_cb =
86// base::Bind(&NoRef::PrintWhy, base::Unretained(no_ref));
87// void_no_ref_cb.Run(); // Prints: why???
88//
89// /* Binding a reference. */
90// int Identity(int n) { return n; }
91// int value = 1;
92// base::Callback<int(void)> bound_copy_cb = base::Bind(&Identity, value);
93// base::Callback<int(void)> bound_ref_cb =
94// base::Bind(&Identity, base::ConstRef(value));
95// LOG(INFO) << bound_copy_cb.Run(); // Prints 1.
96// LOG(INFO) << bound_ref_cb.Run(); // Prints 1.
97// value = 2;
98// LOG(INFO) << bound_copy_cb.Run(); // Prints 1.
99// LOG(INFO) << bound_ref_cb.Run(); // Prints 2.
100//
101//
102// WHERE IS THIS DESIGN FROM:
103//
104// The design Callback and Bind is heavily influenced by C++'s
105// tr1::function/tr1::bind, and by the "Google Callback" system used inside
106// Google.
107//
108//
109// HOW THE IMPLEMENTATION WORKS:
110//
111// There are three main components to the system:
112// 1) The Callback classes.
113// 2) The Bind() functions.
114// 3) The arguments wrappers (eg., Unretained() and ConstRef()).
115//
116// The Callback classes represent a generic function pointer. Internally,
117// it stores a refcounted piece of state that represents the target function
118// and all its bound parameters. Each Callback specialization has a templated
119// constructor that takes an InvokerStorageHolder<> object. In the context of
120// the constructor, the static type of this InvokerStorageHolder<> object
121// uniquely identifies the function it is representing, all its bound
122// parameters, and a DoInvoke() that is capable of invoking the target.
123//
124// Callback's constructor is takes the InvokerStorageHolder<> that has the
125// full static type and erases the target function type, and the bound
126// parameters. It does this by storing a pointer to the specific DoInvoke()
127// function, and upcasting the state of InvokerStorageHolder<> to a
128// InvokerStorageBase. This is safe as long as this InvokerStorageBase pointer
129// is only used with the stored DoInvoke() pointer.
130//
131// To create InvokerStorageHolder<> objects, we use the Bind() functions.
132// These functions, along with a set of internal templates, are reponsible for
133//
134// - Unwrapping the function signature into return type, and parameters
135// - Determining the number of parameters that are bound
136// - Creating the storage for the bound parameters
137// - Performing compile-time asserts to avoid error-prone behavior
138// - Returning an InvokerStorageHolder<> with an DoInvoke() that has an arity
139// matching the number of unbound parameters, and knows the correct
140// refcounting semantics for the target object if we are binding a class
141// method.
142//
143// The Bind functions do the above using type-inference, and template
144// specializations.
145//
146// By default Bind() will store copies of all bound parameters, and attempt
147// to refcount a target object if the function being bound is a class method.
148//
149// To change this behavior, we introduce a set of argument wrappers
150// (eg. Unretained(), and ConstRef()). These are simple container templates
151// that are passed by value, and wrap a pointer to argument. See the
152// file-level comment in base/bind_helpers.h for more info.
153//
154// These types are passed to the Unwrap() functions, and the MaybeRefcount()
155// functions respectively to modify the behavior of Bind(). The Unwrap()
156// and MaybeRefcount() functions change behavior by doing partial
157// specialization based on whether or not a parameter is a wrapper type.
158//
159// ConstRef() is similar to tr1::cref. Unretained() is specific to Chromium.
160//
161//
162// WHY NOT TR1 FUNCTION/BIND?
163//
164// Direct use of tr1::function and tr1::bind was considered, but ultimately
165// rejected because of the number of copy constructors invocations involved
166// in the binding of arguments during construction, and the forwarding of
167// arguments during invocation. These copies will no longer be an issue in
168// C++0x because C++0x will support rvalue reference allowing for the compiler
169// to avoid these copies. However, waiting for C++0x is not an option.
170//
171// Measured with valgrind on gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5), the
172// tr1::bind call itself will invoke a non-trivial copy constructor three times
173// for each bound parameter. Also, each when passing a tr1::function, each
174// bound argument will be copied again.
175//
176// In addition to the copies taken at binding and invocation, copying a
177// tr1::function causes a copy to be made of all the bound parameters and
178// state.
179//
180// Furthermore, in Chromium, it is desirable for the Callback to take a
181// reference on a target object when representing a class method call. This
182// is not supported by tr1.
183//
184// Lastly, tr1::function and tr1::bind has a more general and flexible API.
185// This includes things like argument reordering by use of
186// tr1::bind::placeholder, support for non-const reference parameters, and some
187// limited amount of subtyping of the tr1::function object (eg.,
188// tr1::function<int(int)> is convertible to tr1::function<void(int)>).
189//
190// These are not features that are required in Chromium. Some of them, such as
191// allowing for reference parameters, and subtyping of functions, may actually
[email protected]9f6c5292011-04-19 18:22:00192// become a source of errors. Removing support for these features actually
[email protected]b38d3572011-02-15 01:27:38193// allows for a simpler implementation, and a terser Currying API.
194//
195//
196// WHY NOT GOOGLE CALLBACKS?
197//
198// The Google callback system also does not support refcounting. Furthermore,
199// its implementation has a number of strange edge cases with respect to type
200// conversion of its arguments. In particular, the argument's constness must
201// at times match exactly the function signature, or the type-inference might
202// break. Given the above, writing a custom solution was easier.
203//
204//
205// MISSING FUNCTIONALITY
206// - Invoking the return of Bind. Bind(&foo).Run() does not work;
207// - Binding arrays to functions that take a non-const pointer.
208// Example:
209// void Foo(const char* ptr);
210// void Bar(char* ptr);
211// Bind(&Foo, "test");
212// Bind(&Bar, "test"); // This fails because ptr is not const.
[email protected]2041cf342010-02-19 03:15:59213
[email protected]b38d3572011-02-15 01:27:38214namespace base {
215
216// First, we forward declare the Callback class template. This informs the
217// compiler that the template only has 1 type parameter which is the function
218// signature that the Callback is representing.
219//
220// After this, create template specializations for 0-6 parameters. Note that
221// even though the template typelist grows, the specialization still
222// only has one type: the function signature.
223template <typename Sig>
224class Callback;
[email protected]4346ef912011-02-19 00:52:15225
[email protected]b38d3572011-02-15 01:27:38226template <typename R>
[email protected]15fcb6592011-02-18 04:05:14227class Callback<R(void)> : public internal::CallbackBase {
[email protected]2041cf342010-02-19 03:15:59228 public:
[email protected]c18b1052011-03-24 02:02:17229 typedef R(*PolymorphicInvoke)(
230 internal::InvokerStorageBase*);
[email protected]b38d3572011-02-15 01:27:38231
[email protected]15fcb6592011-02-18 04:05:14232 Callback() : CallbackBase(NULL, NULL) { }
[email protected]b38d3572011-02-15 01:27:38233
234 // We pass InvokerStorageHolder by const ref to avoid incurring an
235 // unnecessary AddRef/Unref pair even though we will modify the object.
236 // We cannot use a normal reference because the compiler will warn
237 // since this is often used on a return value, which is a temporary.
238 //
239 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
240 // return the exact Callback<> type. See base/bind.h for details.
241 template <typename T>
242 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
[email protected]15fcb6592011-02-18 04:05:14243 : CallbackBase(
[email protected]4346ef912011-02-19 00:52:15244 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
[email protected]15fcb6592011-02-18 04:05:14245 &invoker_holder.invoker_storage_) {
[email protected]2041cf342010-02-19 03:15:59246 }
247
[email protected]15fcb6592011-02-18 04:05:14248 R Run() const {
249 PolymorphicInvoke f =
250 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
[email protected]2041cf342010-02-19 03:15:59251
[email protected]15fcb6592011-02-18 04:05:14252 return f(invoker_storage_.get());
253 }
[email protected]2041cf342010-02-19 03:15:59254};
255
[email protected]b38d3572011-02-15 01:27:38256template <typename R, typename A1>
[email protected]15fcb6592011-02-18 04:05:14257class Callback<R(A1)> : public internal::CallbackBase {
[email protected]2041cf342010-02-19 03:15:59258 public:
[email protected]c18b1052011-03-24 02:02:17259 typedef R(*PolymorphicInvoke)(
260 internal::InvokerStorageBase*,
261 typename internal::ParamTraits<A1>::ForwardType);
[email protected]2041cf342010-02-19 03:15:59262
[email protected]15fcb6592011-02-18 04:05:14263 Callback() : CallbackBase(NULL, NULL) { }
[email protected]b38d3572011-02-15 01:27:38264
265 // We pass InvokerStorageHolder by const ref to avoid incurring an
266 // unnecessary AddRef/Unref pair even though we will modify the object.
267 // We cannot use a normal reference because the compiler will warn
268 // since this is often used on a return value, which is a temporary.
269 //
270 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
271 // return the exact Callback<> type. See base/bind.h for details.
272 template <typename T>
273 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
[email protected]15fcb6592011-02-18 04:05:14274 : CallbackBase(
[email protected]4346ef912011-02-19 00:52:15275 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
[email protected]15fcb6592011-02-18 04:05:14276 &invoker_holder.invoker_storage_) {
[email protected]2041cf342010-02-19 03:15:59277 }
278
[email protected]c18b1052011-03-24 02:02:17279 R Run(typename internal::ParamTraits<A1>::ForwardType a1) const {
[email protected]15fcb6592011-02-18 04:05:14280 PolymorphicInvoke f =
281 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
[email protected]b38d3572011-02-15 01:27:38282
[email protected]15fcb6592011-02-18 04:05:14283 return f(invoker_storage_.get(), a1);
284 }
[email protected]2041cf342010-02-19 03:15:59285};
286
[email protected]b38d3572011-02-15 01:27:38287template <typename R, typename A1, typename A2>
[email protected]15fcb6592011-02-18 04:05:14288class Callback<R(A1, A2)> : public internal::CallbackBase {
[email protected]b38d3572011-02-15 01:27:38289 public:
[email protected]c18b1052011-03-24 02:02:17290 typedef R(*PolymorphicInvoke)(
291 internal::InvokerStorageBase*,
292 typename internal::ParamTraits<A1>::ForwardType,
293 typename internal::ParamTraits<A2>::ForwardType);
[email protected]b38d3572011-02-15 01:27:38294
[email protected]15fcb6592011-02-18 04:05:14295 Callback() : CallbackBase(NULL, NULL) { }
[email protected]b38d3572011-02-15 01:27:38296
297 // We pass InvokerStorageHolder by const ref to avoid incurring an
298 // unnecessary AddRef/Unref pair even though we will modify the object.
299 // We cannot use a normal reference because the compiler will warn
300 // since this is often used on a return value, which is a temporary.
301 //
302 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
303 // return the exact Callback<> type. See base/bind.h for details.
304 template <typename T>
305 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
[email protected]15fcb6592011-02-18 04:05:14306 : CallbackBase(
[email protected]4346ef912011-02-19 00:52:15307 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
[email protected]15fcb6592011-02-18 04:05:14308 &invoker_holder.invoker_storage_) {
[email protected]b38d3572011-02-15 01:27:38309 }
310
[email protected]c18b1052011-03-24 02:02:17311 R Run(typename internal::ParamTraits<A1>::ForwardType a1,
312 typename internal::ParamTraits<A2>::ForwardType a2) const {
[email protected]15fcb6592011-02-18 04:05:14313 PolymorphicInvoke f =
314 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
[email protected]b38d3572011-02-15 01:27:38315
[email protected]15fcb6592011-02-18 04:05:14316 return f(invoker_storage_.get(), a1,
317 a2);
318 }
[email protected]b38d3572011-02-15 01:27:38319};
320
321template <typename R, typename A1, typename A2, typename A3>
[email protected]15fcb6592011-02-18 04:05:14322class Callback<R(A1, A2, A3)> : public internal::CallbackBase {
[email protected]b38d3572011-02-15 01:27:38323 public:
[email protected]c18b1052011-03-24 02:02:17324 typedef R(*PolymorphicInvoke)(
325 internal::InvokerStorageBase*,
326 typename internal::ParamTraits<A1>::ForwardType,
327 typename internal::ParamTraits<A2>::ForwardType,
328 typename internal::ParamTraits<A3>::ForwardType);
[email protected]b38d3572011-02-15 01:27:38329
[email protected]15fcb6592011-02-18 04:05:14330 Callback() : CallbackBase(NULL, NULL) { }
[email protected]b38d3572011-02-15 01:27:38331
332 // We pass InvokerStorageHolder by const ref to avoid incurring an
333 // unnecessary AddRef/Unref pair even though we will modify the object.
334 // We cannot use a normal reference because the compiler will warn
335 // since this is often used on a return value, which is a temporary.
336 //
337 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
338 // return the exact Callback<> type. See base/bind.h for details.
339 template <typename T>
340 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
[email protected]15fcb6592011-02-18 04:05:14341 : CallbackBase(
[email protected]4346ef912011-02-19 00:52:15342 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
[email protected]15fcb6592011-02-18 04:05:14343 &invoker_holder.invoker_storage_) {
[email protected]b38d3572011-02-15 01:27:38344 }
345
[email protected]c18b1052011-03-24 02:02:17346 R Run(typename internal::ParamTraits<A1>::ForwardType a1,
347 typename internal::ParamTraits<A2>::ForwardType a2,
348 typename internal::ParamTraits<A3>::ForwardType a3) const {
[email protected]15fcb6592011-02-18 04:05:14349 PolymorphicInvoke f =
350 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
[email protected]b38d3572011-02-15 01:27:38351
[email protected]15fcb6592011-02-18 04:05:14352 return f(invoker_storage_.get(), a1,
353 a2,
354 a3);
355 }
[email protected]b38d3572011-02-15 01:27:38356};
357
358template <typename R, typename A1, typename A2, typename A3, typename A4>
[email protected]15fcb6592011-02-18 04:05:14359class Callback<R(A1, A2, A3, A4)> : public internal::CallbackBase {
[email protected]b38d3572011-02-15 01:27:38360 public:
[email protected]c18b1052011-03-24 02:02:17361 typedef R(*PolymorphicInvoke)(
362 internal::InvokerStorageBase*,
363 typename internal::ParamTraits<A1>::ForwardType,
364 typename internal::ParamTraits<A2>::ForwardType,
365 typename internal::ParamTraits<A3>::ForwardType,
366 typename internal::ParamTraits<A4>::ForwardType);
[email protected]b38d3572011-02-15 01:27:38367
[email protected]15fcb6592011-02-18 04:05:14368 Callback() : CallbackBase(NULL, NULL) { }
[email protected]b38d3572011-02-15 01:27:38369
370 // We pass InvokerStorageHolder by const ref to avoid incurring an
371 // unnecessary AddRef/Unref pair even though we will modify the object.
372 // We cannot use a normal reference because the compiler will warn
373 // since this is often used on a return value, which is a temporary.
374 //
375 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
376 // return the exact Callback<> type. See base/bind.h for details.
377 template <typename T>
378 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
[email protected]15fcb6592011-02-18 04:05:14379 : CallbackBase(
[email protected]4346ef912011-02-19 00:52:15380 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
[email protected]15fcb6592011-02-18 04:05:14381 &invoker_holder.invoker_storage_) {
[email protected]b38d3572011-02-15 01:27:38382 }
383
[email protected]c18b1052011-03-24 02:02:17384 R Run(typename internal::ParamTraits<A1>::ForwardType a1,
385 typename internal::ParamTraits<A2>::ForwardType a2,
386 typename internal::ParamTraits<A3>::ForwardType a3,
387 typename internal::ParamTraits<A4>::ForwardType a4) const {
[email protected]15fcb6592011-02-18 04:05:14388 PolymorphicInvoke f =
389 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
[email protected]b38d3572011-02-15 01:27:38390
[email protected]15fcb6592011-02-18 04:05:14391 return f(invoker_storage_.get(), a1,
392 a2,
393 a3,
394 a4);
395 }
[email protected]b38d3572011-02-15 01:27:38396};
397
398template <typename R, typename A1, typename A2, typename A3, typename A4,
399 typename A5>
[email protected]15fcb6592011-02-18 04:05:14400class Callback<R(A1, A2, A3, A4, A5)> : public internal::CallbackBase {
[email protected]b38d3572011-02-15 01:27:38401 public:
[email protected]c18b1052011-03-24 02:02:17402 typedef R(*PolymorphicInvoke)(
403 internal::InvokerStorageBase*,
404 typename internal::ParamTraits<A1>::ForwardType,
405 typename internal::ParamTraits<A2>::ForwardType,
406 typename internal::ParamTraits<A3>::ForwardType,
407 typename internal::ParamTraits<A4>::ForwardType,
408 typename internal::ParamTraits<A5>::ForwardType);
[email protected]b38d3572011-02-15 01:27:38409
[email protected]15fcb6592011-02-18 04:05:14410 Callback() : CallbackBase(NULL, NULL) { }
[email protected]b38d3572011-02-15 01:27:38411
412 // We pass InvokerStorageHolder by const ref to avoid incurring an
413 // unnecessary AddRef/Unref pair even though we will modify the object.
414 // We cannot use a normal reference because the compiler will warn
415 // since this is often used on a return value, which is a temporary.
416 //
417 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
418 // return the exact Callback<> type. See base/bind.h for details.
419 template <typename T>
420 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
[email protected]15fcb6592011-02-18 04:05:14421 : CallbackBase(
[email protected]4346ef912011-02-19 00:52:15422 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
[email protected]15fcb6592011-02-18 04:05:14423 &invoker_holder.invoker_storage_) {
[email protected]b38d3572011-02-15 01:27:38424 }
425
[email protected]c18b1052011-03-24 02:02:17426 R Run(typename internal::ParamTraits<A1>::ForwardType a1,
427 typename internal::ParamTraits<A2>::ForwardType a2,
428 typename internal::ParamTraits<A3>::ForwardType a3,
429 typename internal::ParamTraits<A4>::ForwardType a4,
430 typename internal::ParamTraits<A5>::ForwardType a5) const {
[email protected]15fcb6592011-02-18 04:05:14431 PolymorphicInvoke f =
432 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
[email protected]b38d3572011-02-15 01:27:38433
[email protected]15fcb6592011-02-18 04:05:14434 return f(invoker_storage_.get(), a1,
435 a2,
436 a3,
437 a4,
438 a5);
439 }
[email protected]b38d3572011-02-15 01:27:38440};
441
442template <typename R, typename A1, typename A2, typename A3, typename A4,
443 typename A5, typename A6>
[email protected]15fcb6592011-02-18 04:05:14444class Callback<R(A1, A2, A3, A4, A5, A6)> : public internal::CallbackBase {
[email protected]b38d3572011-02-15 01:27:38445 public:
[email protected]c18b1052011-03-24 02:02:17446 typedef R(*PolymorphicInvoke)(
447 internal::InvokerStorageBase*,
448 typename internal::ParamTraits<A1>::ForwardType,
449 typename internal::ParamTraits<A2>::ForwardType,
450 typename internal::ParamTraits<A3>::ForwardType,
451 typename internal::ParamTraits<A4>::ForwardType,
452 typename internal::ParamTraits<A5>::ForwardType,
453 typename internal::ParamTraits<A6>::ForwardType);
[email protected]b38d3572011-02-15 01:27:38454
[email protected]15fcb6592011-02-18 04:05:14455 Callback() : CallbackBase(NULL, NULL) { }
[email protected]b38d3572011-02-15 01:27:38456
457 // We pass InvokerStorageHolder by const ref to avoid incurring an
458 // unnecessary AddRef/Unref pair even though we will modify the object.
459 // We cannot use a normal reference because the compiler will warn
460 // since this is often used on a return value, which is a temporary.
461 //
462 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
463 // return the exact Callback<> type. See base/bind.h for details.
464 template <typename T>
465 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
[email protected]15fcb6592011-02-18 04:05:14466 : CallbackBase(
[email protected]4346ef912011-02-19 00:52:15467 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
[email protected]15fcb6592011-02-18 04:05:14468 &invoker_holder.invoker_storage_) {
[email protected]b38d3572011-02-15 01:27:38469 }
470
[email protected]c18b1052011-03-24 02:02:17471 R Run(typename internal::ParamTraits<A1>::ForwardType a1,
472 typename internal::ParamTraits<A2>::ForwardType a2,
473 typename internal::ParamTraits<A3>::ForwardType a3,
474 typename internal::ParamTraits<A4>::ForwardType a4,
475 typename internal::ParamTraits<A5>::ForwardType a5,
476 typename internal::ParamTraits<A6>::ForwardType a6) const {
[email protected]15fcb6592011-02-18 04:05:14477 PolymorphicInvoke f =
478 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
[email protected]b38d3572011-02-15 01:27:38479
[email protected]15fcb6592011-02-18 04:05:14480 return f(invoker_storage_.get(), a1,
481 a2,
482 a3,
483 a4,
484 a5,
485 a6);
486 }
[email protected]b38d3572011-02-15 01:27:38487};
488
489
490// Syntactic sugar to make Callbacks<void(void)> easier to declare since it
491// will be used in a lot of APIs with delayed execution.
492typedef Callback<void(void)> Closure;
493
494} // namespace base
[email protected]2041cf342010-02-19 03:15:59495
496#endif // BASE_CALLBACK_H