Home | History | Annotate | Download | only in base
      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 
    217 namespace 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.
    226 template <typename Sig>
    227 class Callback;
    228 
    229 
    230 $range ARITY 0..MAX_ARITY
    231 $for ARITY [[
    232 $range ARG 1..ARITY
    233 
    234 $if ARITY == 0 [[
    235 template <typename R>
    236 class Callback<R(void)> : public internal::CallbackBase {
    237 ]] $else [[
    238 template <typename R, $for ARG , [[typename A$(ARG)]]>
    239 class 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.
    281 typedef Callback<void(void)> Closure;
    282 
    283 }  // namespace base
    284 
    285 #endif  // BASE_CALLBACK_H
    286