• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1$$ This is a pump file for generating file templates.  Pump is a python
2$$ script that is part of the Google Test suite of utilities.  Description
3$$ can be found here:
4$$
5$$ http://code.google.com/p/googletest/wiki/PumpManual
6$$
7
8$var MAX_ARITY = 6
9
10// Copyright (c) 2011 The Chromium Authors. All rights reserved.
11// Use of this source code is governed by a BSD-style license that can be
12// found in the LICENSE file.
13
14#ifndef BASE_CALLBACK_H_
15#define BASE_CALLBACK_H_
16#pragma once
17
18#include "base/callback_internal.h"
19#include "base/callback_old.h"
20
21// New, super-duper, unified Callback system.  This will eventually replace
22// NewRunnableMethod, NewRunnableFunction, CreateFunctor, and CreateCallback
23// systems currently in the Chromium code base.
24//
25// WHAT IS THIS:
26//
27// The templated Callback class is a generalized function object. Together
28// with the Bind() function in bind.h, they provide a type-safe method for
29// performing currying of arguments, and creating a "closure."
30//
31// In programing languages, a closure is a first-class function where all its
32// parameters have been bound (usually via currying).  Closures are well
33// suited for representing, and passing around a unit of delayed execution.
34// They are used in Chromium code to schedule tasks on different MessageLoops.
35//
36//
37// MEMORY MANAGEMENT AND PASSING
38//
39// The Callback objects themselves should be passed by const-reference, and
40// stored by copy. They internally store their state via a refcounted class
41// and thus do not need to be deleted.
42//
43// The reason to pass via a const-reference is to avoid unnecessary
44// AddRef/Release pairs to the internal state.
45//
46//
47// EXAMPLE USAGE:
48//
49// /* Binding a normal function. */
50// int Return5() { return 5; }
51// base::Callback<int(int)> func_cb = base::Bind(&Return5);
52// LOG(INFO) << func_cb.Run(5);  // Prints 5.
53//
54// void PrintHi() { LOG(INFO) << "hi."; }
55// base::Closure void_func_cb = base::Bind(&PrintHi);
56// LOG(INFO) << void_func_cb.Run();  // Prints: hi.
57//
58// /* Binding a class method. */
59// class Ref : public RefCountedThreadSafe<Ref> {
60//  public:
61//   int Foo() { return 3; }
62//   void PrintBye() { LOG(INFO) << "bye."; }
63// };
64// scoped_refptr<Ref> ref = new Ref();
65// base::Callback<int(void)> ref_cb = base::Bind(&Ref::Foo, ref.get());
66// LOG(INFO) << ref_cb.Run();  // Prints out 3.
67//
68// base::Closure void_ref_cb = base::Bind(&Ref::PrintBye, ref.get());
69// void_ref_cb.Run();  // Prints: bye.
70//
71// /* Binding a class method in a non-refcounted class.
72//  *
73//  * WARNING: You must be sure the referee outlives the callback!
74//  *          This is particularly important if you post a closure to a
75//  *          MessageLoop because then it becomes hard to know what the
76//  *          lifetime of the referee needs to be.
77//  */
78// class NoRef {
79//  public:
80//   int Foo() { return 4; }
81//   void PrintWhy() { LOG(INFO) << "why???"; }
82// };
83// NoRef no_ref;
84// base::Callback<int(void)> base::no_ref_cb =
85//     base::Bind(&NoRef::Foo, base::Unretained(&no_ref));
86// LOG(INFO) << ref_cb.Run();  // Prints out 4.
87//
88// base::Closure void_no_ref_cb =
89//     base::Bind(&NoRef::PrintWhy, base::Unretained(no_ref));
90// void_no_ref_cb.Run();  // Prints: why???
91//
92// /* Binding a reference. */
93// int Identity(int n) { return n; }
94// int value = 1;
95// base::Callback<int(void)> bound_copy_cb = base::Bind(&Identity, value);
96// base::Callback<int(void)> bound_ref_cb =
97//     base::Bind(&Identity, base::ConstRef(value));
98// LOG(INFO) << bound_copy_cb.Run();  // Prints 1.
99// LOG(INFO) << bound_ref_cb.Run();  // Prints 1.
100// value = 2;
101// LOG(INFO) << bound_copy_cb.Run();  // Prints 1.
102// LOG(INFO) << bound_ref_cb.Run();  // Prints 2.
103//
104//
105// WHERE IS THIS DESIGN FROM:
106//
107// The design Callback and Bind is heavily influenced by C++'s
108// tr1::function/tr1::bind, and by the "Google Callback" system used inside
109// Google.
110//
111//
112// HOW THE IMPLEMENTATION WORKS:
113//
114// There are three main components to the system:
115//   1) The Callback classes.
116//   2) The Bind() functions.
117//   3) The arguments wrappers (eg., Unretained() and ConstRef()).
118//
119// The Callback classes represent a generic function pointer. Internally,
120// it stores a refcounted piece of state that represents the target function
121// and all its bound parameters.  Each Callback specialization has a templated
122// constructor that takes an InvokerStorageHolder<> object.  In the context of
123// the constructor, the static type of this InvokerStorageHolder<> object
124// uniquely identifies the function it is representing, all its bound
125// parameters, and a DoInvoke() that is capable of invoking the target.
126//
127// Callback's constructor is takes the InvokerStorageHolder<> that has the
128// full static type and erases the target function type, and the bound
129// parameters.  It does this by storing a pointer to the specific DoInvoke()
130// function, and upcasting the state of InvokerStorageHolder<> to a
131// InvokerStorageBase. This is safe as long as this InvokerStorageBase pointer
132// is only used with the stored DoInvoke() pointer.
133//
134// To create InvokerStorageHolder<> objects, we use the Bind() functions.
135// These functions, along with a set of internal templates, are reponsible for
136//
137//  - Unwrapping the function signature into return type, and parameters
138//  - Determining the number of parameters that are bound
139//  - Creating the storage for the bound parameters
140//  - Performing compile-time asserts to avoid error-prone behavior
141//  - Returning an InvokerStorageHolder<> with an DoInvoke() that has an arity
142//    matching the number of unbound parameters, and knows the correct
143//    refcounting semantics for the target object if we are binding a class
144//    method.
145//
146// The Bind functions do the above using type-inference, and template
147// specializations.
148//
149// By default Bind() will store copies of all bound parameters, and attempt
150// to refcount a target object if the function being bound is a class method.
151//
152// To change this behavior, we introduce a set of argument wrappers
153// (eg. Unretained(), and ConstRef()).  These are simple container templates
154// that are passed by value, and wrap a pointer to argument.  See the
155// file-level comment in base/bind_helpers.h for more info.
156//
157// These types are passed to the Unwrap() functions, and the MaybeRefcount()
158// functions respectively to modify the behavior of Bind().  The Unwrap()
159// and MaybeRefcount() functions change behavior by doing partial
160// specialization based on whether or not a parameter is a wrapper type.
161//
162// ConstRef() is similar to tr1::cref.  Unretained() is specific to Chromium.
163//
164//
165// WHY NOT TR1 FUNCTION/BIND?
166//
167// Direct use of tr1::function and tr1::bind was considered, but ultimately
168// rejected because of the number of copy constructors invocations involved
169// in the binding of arguments during construction, and the forwarding of
170// arguments during invocation.  These copies will no longer be an issue in
171// C++0x because C++0x will support rvalue reference allowing for the compiler
172// to avoid these copies.  However, waiting for C++0x is not an option.
173//
174// Measured with valgrind on gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5), the
175// tr1::bind call itself will invoke a non-trivial copy constructor three times
176// for each bound parameter.  Also, each when passing a tr1::function, each
177// bound argument will be copied again.
178//
179// In addition to the copies taken at binding and invocation, copying a
180// tr1::function causes a copy to be made of all the bound parameters and
181// state.
182//
183// Furthermore, in Chromium, it is desirable for the Callback to take a
184// reference on a target object when representing a class method call.  This
185// is not supported by tr1.
186//
187// Lastly, tr1::function and tr1::bind has a more general and flexible API.
188// This includes things like argument reordering by use of
189// tr1::bind::placeholder, support for non-const reference parameters, and some
190// limited amount of subtyping of the tr1::function object (eg.,
191// tr1::function<int(int)> is convertible to tr1::function<void(int)>).
192//
193// These are not features that are required in Chromium. Some of them, such as
194// allowing for reference parameters, and subtyping of functions, may actually
195// because a source of errors. Removing support for these features actually
196// allows for a simpler implementation, and a terser Currying API.
197//
198//
199// WHY NOT GOOGLE CALLBACKS?
200//
201// The Google callback system also does not support refcounting.  Furthermore,
202// its implementation has a number of strange edge cases with respect to type
203// conversion of its arguments.  In particular, the argument's constness must
204// at times match exactly the function signature, or the type-inference might
205// break.  Given the above, writing a custom solution was easier.
206//
207//
208// MISSING FUNCTIONALITY
209//  - Invoking the return of Bind.  Bind(&foo).Run() does not work;
210//  - Binding arrays to functions that take a non-const pointer.
211//    Example:
212//      void Foo(const char* ptr);
213//      void Bar(char* ptr);
214//      Bind(&Foo, "test");
215//      Bind(&Bar, "test");  // This fails because ptr is not const.
216
217namespace base {
218
219// First, we forward declare the Callback class template. This informs the
220// compiler that the template only has 1 type parameter which is the function
221// signature that the Callback is representing.
222//
223// After this, create template specializations for 0-$(MAX_ARITY) parameters. Note that
224// even though the template typelist grows, the specialization still
225// only has one type: the function signature.
226template <typename Sig>
227class Callback;
228
229
230$range ARITY 0..MAX_ARITY
231$for ARITY [[
232$range ARG 1..ARITY
233
234$if ARITY == 0 [[
235template <typename R>
236class Callback<R(void)> : public internal::CallbackBase {
237]] $else [[
238template <typename R, $for ARG , [[typename A$(ARG)]]>
239class Callback<R($for ARG , [[A$(ARG)]])> : public internal::CallbackBase {
240]]
241
242 public:
243  typedef R(*PolymorphicInvoke)(
244      internal::InvokerStorageBase*[[]]
245$if ARITY != 0 [[, ]]
246$for ARG , [[typename internal::ParamTraits<A$(ARG)>::ForwardType]]);
247
248  Callback() : CallbackBase(NULL, NULL) { }
249
250  // We pass InvokerStorageHolder by const ref to avoid incurring an
251  // unnecessary AddRef/Unref pair even though we will modify the object.
252  // We cannot use a normal reference because the compiler will warn
253  // since this is often used on a return value, which is a temporary.
254  //
255  // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
256  // return the exact Callback<> type.  See base/bind.h for details.
257  template <typename T>
258  Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
259      : CallbackBase(
260          reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
261          &invoker_holder.invoker_storage_) {
262  }
263
264  R Run($for ARG ,
265        [[typename internal::ParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) const {
266    PolymorphicInvoke f =
267        reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
268
269    return f(invoker_storage_.get()[[]]
270$if ARITY != 0 [[, ]]
271$for ARG ,
272             [[a$(ARG)]]);
273  }
274};
275
276
277]]  $$ for ARITY
278
279// Syntactic sugar to make Callbacks<void(void)> easier to declare since it
280// will be used in a lot of APIs with delayed execution.
281typedef Callback<void(void)> Closure;
282
283}  // namespace base
284
285#endif  // BASE_CALLBACK_H
286