Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: base/callback.h

Issue 6109007: Unified callback system. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/base
Patch Set: Address Will's comments. Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/bind_unittest.cc ('k') | base/callback.h.pump » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // This file was GENERATED by command:
2 // pump.py callback.h.pump
3 // DO NOT EDIT BY HAND!!!
4
5
6 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 7 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 8 // found in the LICENSE file.
4 9
5 #ifndef BASE_CALLBACK_H_ 10 #ifndef BASE_CALLBACK_H_
6 #define BASE_CALLBACK_H_ 11 #define BASE_CALLBACK_H_
7 #pragma once 12 #pragma once
8 13
9 #include "base/tuple.h" 14 #include "base/callback_helpers.h"
10 #include "base/raw_scoped_refptr_mismatch_checker.h" 15 #include "base/callback_old.h"
11 16
12 // Callback -------------------------------------------------------------------- 17 // New, super-duper, unified Callback system. This will eventually replace
13 // 18 // NewRunnableMethod, NewRunnableFunction, CreateFunctor, and CreateCallback
14 // A Callback is like a Task but with unbound parameters. It is basically an 19 // systems currently in the Chromium code base.
15 // object-oriented function pointer. 20 //
16 // 21 // WHAT IS THIS:
17 // Callbacks are designed to work with Tuples. A set of helper functions and 22 //
18 // classes is provided to hide the Tuple details from the consumer. Client 23 // The templated Callback class is a generalized function object. Together
19 // code will generally work with the CallbackRunner base class, which merely 24 // with the Bind() function in bind.h, they provide a type-safe method for
20 // provides a Run method and is returned by the New* functions. This allows 25 // performing currying of arguments, and creating a "closure."
21 // users to not care which type of class implements the callback, only that it 26 //
22 // has a certain number and type of arguments. 27 // In programing languages, a closure is a first-class function where all its
23 // 28 // parameters have been bound (usually via currying). Closures are well
24 // The implementation of this is done by CallbackImpl, which inherits 29 // suited for representing, and passing around a unit of delayed execution.
25 // CallbackStorage to store the data. This allows the storage of the data 30 // They are used in Chromium code to schedule tasks on different MessageLoops.
26 // (requiring the class type T) to be hidden from users, who will want to call 31 //
27 // this regardless of the implementor's type T. 32 //
28 // 33 // MEMORY MANAGEMENT AND PASSING
29 // Note that callbacks currently have no facility for cancelling or abandoning 34 //
30 // them. We currently handle this at a higher level for cases where this is 35 // The Callback objects themselves should be passed by const-reference, and
31 // necessary. The pointer in a callback must remain valid until the callback 36 // stored by copy. They internally store their state via a refcounted class
32 // is made. 37 // and thus do not need to be deleted.
33 // 38 //
34 // Like Task, the callback executor is responsible for deleting the callback 39 // The reason to pass via a const-reference is to avoid unnecessary
35 // pointer once the callback has executed. 40 // AddRef/Release pairs to the internal state.
36 // 41 //
37 // Example client usage: 42 //
38 // void Object::DoStuff(int, string); 43 // EXAMPLE USAGE:
39 // Callback2<int, string>::Type* callback = 44 //
40 // NewCallback(obj, &Object::DoStuff); 45 // /* Binding a normal function. */
41 // callback->Run(5, string("hello")); 46 // int Return5() { return 5; }
42 // delete callback; 47 // base::Callback<int(int)> func_cb = base::Bind(&Return5);
43 // or, equivalently, using tuples directly: 48 // LOG(INFO) << func_cb.Run(5); // Prints 5.
44 // CallbackRunner<Tuple2<int, string> >* callback = 49 //
45 // NewCallback(obj, &Object::DoStuff); 50 // void PrintHi() { LOG(INFO) << "hi."; }
46 // callback->RunWithParams(MakeTuple(5, string("hello"))); 51 // base::Closure void_func_cb = base::Bind(&PrintHi);
47 // 52 // LOG(INFO) << void_func_cb.Run(); // Prints: hi.
48 // There is also a 0-args version that returns a value. Example: 53 //
49 // int Object::GetNextInt(); 54 // /* Binding a class method. */
50 // CallbackWithReturnValue<int>::Type* callback = 55 // class Ref : public RefCountedThreadSafe<Ref> {
51 // NewCallbackWithReturnValue(obj, &Object::GetNextInt); 56 // public:
52 // int next_int = callback->Run(); 57 // int Foo() { return 3; }
53 // delete callback; 58 // void PrintBye() { LOG(INFO) << "bye."; }
54 59 // };
55 // Base for all Callbacks that handles storage of the pointers. 60 // scoped_refptr<Ref> ref = new Ref();
56 template <class T, typename Method> 61 // base::Callback<int(void)> ref_cb = base::Bind(&Ref::Foo, ref.get());
57 class CallbackStorage { 62 // LOG(INFO) << ref_cb.Run(); // Prints out 3.
58 public: 63 //
59 CallbackStorage(T* obj, Method meth) : obj_(obj), meth_(meth) { 64 // base::Closure void_ref_cb = base::Bind(&Ref::PrintBye, ref.get());
60 } 65 // void_ref_cb.Run(); // Prints: bye.
61 66 //
62 protected: 67 // /* Binding a class method in a non-refcounted class.
63 T* obj_; 68 // *
64 Method meth_; 69 // * WARNING: You must be sure the referee outlives the callback!
65 }; 70 // * This is particularly important if you post a closure to a
66 71 // * MessageLoop because then it becomes hard to know what the
67 // Interface that is exposed to the consumer, that does the actual calling 72 // * lifetime of the referee needs to be.
68 // of the method. 73 // */
69 template <typename Params> 74 // class NoRef {
70 class CallbackRunner { 75 // public:
71 public: 76 // int Foo() { return 4; }
72 typedef Params TupleType; 77 // void PrintWhy() { LOG(INFO) << "why???"; }
73 78 // };
74 virtual ~CallbackRunner() {} 79 // NoRef no_ref;
75 virtual void RunWithParams(const Params& params) = 0; 80 // base::Callback<int(void)> base::no_ref_cb =
76 81 // base::Bind(&NoRef::Foo, base::Unretained(&no_ref));
77 // Convenience functions so callers don't have to deal with Tuples. 82 // LOG(INFO) << ref_cb.Run(); // Prints out 4.
78 inline void Run() { 83 //
79 RunWithParams(Tuple0()); 84 // base::Closure void_no_ref_cb =
80 } 85 // base::Bind(&NoRef::PrintWhy, base::Unretained(no_ref));
81 86 // void_no_ref_cb.Run(); // Prints: why???
82 template <typename Arg1> 87 //
83 inline void Run(const Arg1& a) { 88 // /* Binding a reference. */
84 RunWithParams(Params(a)); 89 // int Identity(int n) { return n; }
85 } 90 // int value = 1;
86 91 // base::Callback<int(void)> bound_copy_cb = base::Bind(&Identity, value);
87 template <typename Arg1, typename Arg2> 92 // base::Callback<int(void)> bound_ref_cb =
88 inline void Run(const Arg1& a, const Arg2& b) { 93 // base::Bind(&Identity, base::ConstRef(value));
89 RunWithParams(Params(a, b)); 94 // LOG(INFO) << bound_copy_cb.Run(); // Prints 1.
90 } 95 // LOG(INFO) << bound_ref_cb.Run(); // Prints 1.
91 96 // value = 2;
92 template <typename Arg1, typename Arg2, typename Arg3> 97 // LOG(INFO) << bound_copy_cb.Run(); // Prints 1.
93 inline void Run(const Arg1& a, const Arg2& b, const Arg3& c) { 98 // LOG(INFO) << bound_ref_cb.Run(); // Prints 2.
94 RunWithParams(Params(a, b, c)); 99 //
95 } 100 //
96 101 // WHERE IS THIS DESIGN FROM:
97 template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> 102 //
98 inline void Run(const Arg1& a, const Arg2& b, const Arg3& c, const Arg4& d) { 103 // The design Callback and Bind is heavily influenced by C++'s
99 RunWithParams(Params(a, b, c, d)); 104 // tr1::function/tr1::bind, and by the "Google Callback" system used inside
100 } 105 // Google.
101 106 //
102 template <typename Arg1, typename Arg2, typename Arg3, 107 //
103 typename Arg4, typename Arg5> 108 // HOW THE IMPLEMENTATION WORKS:
104 inline void Run(const Arg1& a, const Arg2& b, const Arg3& c, 109 //
105 const Arg4& d, const Arg5& e) { 110 // There are three main components to the system:
106 RunWithParams(Params(a, b, c, d, e)); 111 // 1) The Callback classes.
107 } 112 // 2) The Bind() functions.
108 }; 113 // 3) The arguments wrappers (eg., Unretained() and ConstRef()).
109 114 //
110 template <class T, typename Method, typename Params> 115 // The Callback classes represent a generic function pointer. Internally,
111 class CallbackImpl : public CallbackStorage<T, Method>, 116 // it stores a refcounted piece of state that represents the target function
112 public CallbackRunner<Params> { 117 // and all its bound parameters. Each Callback specialization has a templated
113 public: 118 // constructor that takes an InvokerStorageHolder<> object. In the context of
114 CallbackImpl(T* obj, Method meth) : CallbackStorage<T, Method>(obj, meth) { 119 // the constructor, the static type of this InvokerStorageHolder<> object
115 } 120 // uniquely identifies the function it is representing, all its bound
116 virtual void RunWithParams(const Params& params) { 121 // parameters, and a DoInvoke() that is capable of invoking the target.
117 // use "this->" to force C++ to look inside our templatized base class; see 122 //
118 // Effective C++, 3rd Ed, item 43, p210 for details. 123 // Callback's constructor is takes the InvokerStorageHolder<> that has the
119 DispatchToMethod(this->obj_, this->meth_, params); 124 // full static type and erases the target function type, and the bound
120 } 125 // parameters. It does this by storing a pointer to the specific DoInvoke()
121 }; 126 // function, and upcasting the state of InvokerStorageHolder<> to a
122 127 // InvokerStorageBase. This is safe as long as this InvokerStorageBase pointer
123 // 0-arg implementation 128 // is only used with the stored DoInvoke() pointer.
124 struct Callback0 { 129 //
125 typedef CallbackRunner<Tuple0> Type; 130 // To create InvokerStorageHolder<> objects, we use the Bind() functions.
126 }; 131 // These functions, along with a set of internal templates, are reponsible for
127 132 //
128 template <class T> 133 // - Unwrapping the function signature into return type, and parameters
129 typename Callback0::Type* NewCallback(T* object, void (T::*method)()) { 134 // - Determining the number of parameters that are bound
130 return new CallbackImpl<T, void (T::*)(), Tuple0 >(object, method); 135 // - Creating the storage for the bound parameters
131 } 136 // - Performing compile-time asserts to avoid error-prone behavior
132 137 // - Returning an InvokerStorageHolder<> with an DoInvoke() that has an arity
133 // 1-arg implementation 138 // matching the number of unbound parameters, and knows the correct
134 template <typename Arg1> 139 // refcounting semantics for the target object if we are binding a class
135 struct Callback1 { 140 // method.
136 typedef CallbackRunner<Tuple1<Arg1> > Type; 141 //
137 }; 142 // The Bind functions do the above using type-inference, and template
138 143 // specializations.
139 template <class T, typename Arg1> 144 //
140 typename Callback1<Arg1>::Type* NewCallback(T* object, 145 // By default Bind() will store copies of all bound parameters, and attempt
141 void (T::*method)(Arg1)) { 146 // to refcount a target object if the function being bound is a class method.
142 return new CallbackImpl<T, void (T::*)(Arg1), Tuple1<Arg1> >(object, method); 147 //
143 } 148 // To change this behavior, we introduce a set of argument wrappers
144 149 // (eg. Unretained(), and ConstRef()). These are simple container templates
145 // 2-arg implementation 150 // that are passed by value, and wrap a pointer to argument. See the
146 template <typename Arg1, typename Arg2> 151 // file-level comment in base/bind_helpers.h for more info.
147 struct Callback2 { 152 //
148 typedef CallbackRunner<Tuple2<Arg1, Arg2> > Type; 153 // These types are passed to the Unwrap() functions, and the MaybeRefcount()
149 }; 154 // functions respectively to modify the behavior of Bind(). The Unwrap()
150 155 // and MaybeRefcount() functions change behavior by doing partial
151 template <class T, typename Arg1, typename Arg2> 156 // specialization based on whether or not a parameter is a wrapper type.
152 typename Callback2<Arg1, Arg2>::Type* NewCallback( 157 //
153 T* object, 158 // ConstRef() is similar to tr1::cref. Unretained() is specific to Chromium.
154 void (T::*method)(Arg1, Arg2)) { 159 //
155 return new CallbackImpl<T, void (T::*)(Arg1, Arg2), 160 //
156 Tuple2<Arg1, Arg2> >(object, method); 161 // WHY NOT TR1 FUNCTION/BIND?
157 } 162 //
158 163 // Direct use of tr1::function and tr1::bind was considered, but ultimately
159 // 3-arg implementation 164 // rejected because of the number of copy constructors invocations involved
160 template <typename Arg1, typename Arg2, typename Arg3> 165 // in the binding of arguments during construction, and the forwarding of
161 struct Callback3 { 166 // arguments during invocation. These copies will no longer be an issue in
162 typedef CallbackRunner<Tuple3<Arg1, Arg2, Arg3> > Type; 167 // C++0x because C++0x will support rvalue reference allowing for the compiler
163 }; 168 // to avoid these copies. However, waiting for C++0x is not an option.
164 169 //
165 template <class T, typename Arg1, typename Arg2, typename Arg3> 170 // Measured with valgrind on gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5), the
166 typename Callback3<Arg1, Arg2, Arg3>::Type* NewCallback( 171 // tr1::bind call itself will invoke a non-trivial copy constructor three times
167 T* object, 172 // for each bound parameter. Also, each when passing a tr1::function, each
168 void (T::*method)(Arg1, Arg2, Arg3)) { 173 // bound argument will be copied again.
169 return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3), 174 //
170 Tuple3<Arg1, Arg2, Arg3> >(object, method); 175 // In addition to the copies taken at binding and invocation, copying a
171 } 176 // tr1::function causes a copy to be made of all the bound parameters and
172 177 // state.
173 // 4-arg implementation 178 //
174 template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> 179 // Furthermore, in Chromium, it is desirable for the Callback to take a
175 struct Callback4 { 180 // reference on a target object when representing a class method call. This
176 typedef CallbackRunner<Tuple4<Arg1, Arg2, Arg3, Arg4> > Type; 181 // is not supported by tr1.
177 }; 182 //
178 183 // Lastly, tr1::function and tr1::bind has a more general and flexible API.
179 template <class T, typename Arg1, typename Arg2, typename Arg3, typename Arg4> 184 // This includes things like argument reordering by use of
180 typename Callback4<Arg1, Arg2, Arg3, Arg4>::Type* NewCallback( 185 // tr1::bind::placeholder, support for non-const reference parameters, and some
181 T* object, 186 // limited amount of subtyping of the tr1::function object (eg.,
182 void (T::*method)(Arg1, Arg2, Arg3, Arg4)) { 187 // tr1::function<int(int)> is convertible to tr1::function<void(int)>).
183 return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3, Arg4), 188 //
184 Tuple4<Arg1, Arg2, Arg3, Arg4> >(object, method); 189 // These are not features that are required in Chromium. Some of them, such as
185 } 190 // allowing for reference parameters, and subtyping of functions, may actually
186 191 // because a source of errors. Removing support for these features actually
187 // 5-arg implementation 192 // allows for a simpler implementation, and a terser Currying API.
188 template <typename Arg1, typename Arg2, typename Arg3, 193 //
189 typename Arg4, typename Arg5> 194 //
190 struct Callback5 { 195 // WHY NOT GOOGLE CALLBACKS?
191 typedef CallbackRunner<Tuple5<Arg1, Arg2, Arg3, Arg4, Arg5> > Type; 196 //
192 }; 197 // The Google callback system also does not support refcounting. Furthermore,
193 198 // its implementation has a number of strange edge cases with respect to type
194 template <class T, typename Arg1, typename Arg2, 199 // conversion of its arguments. In particular, the argument's constness must
195 typename Arg3, typename Arg4, typename Arg5> 200 // at times match exactly the function signature, or the type-inference might
196 typename Callback5<Arg1, Arg2, Arg3, Arg4, Arg5>::Type* NewCallback( 201 // break. Given the above, writing a custom solution was easier.
197 T* object, 202 //
198 void (T::*method)(Arg1, Arg2, Arg3, Arg4, Arg5)) { 203 //
199 return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3, Arg4, Arg5), 204 // MISSING FUNCTIONALITY
200 Tuple5<Arg1, Arg2, Arg3, Arg4, Arg5> >(object, method); 205 // - Invoking the return of Bind. Bind(&foo).Run() does not work;
201 } 206 // - Binding arrays to functions that take a non-const pointer.
202 207 // Example:
203 // An UnboundMethod is a wrapper for a method where the actual object is 208 // void Foo(const char* ptr);
204 // provided at Run dispatch time. 209 // void Bar(char* ptr);
205 template <class T, class Method, class Params> 210 // Bind(&Foo, "test");
206 class UnboundMethod { 211 // Bind(&Bar, "test"); // This fails because ptr is not const.
207 public: 212
208 UnboundMethod(Method m, const Params& p) : m_(m), p_(p) { 213 namespace base {
209 COMPILE_ASSERT( 214
210 (base::internal::ParamsUseScopedRefptrCorrectly<Params>::value), 215 // First, we forward declare the Callback class template. This informs the
211 badunboundmethodparams); 216 // compiler that the template only has 1 type parameter which is the function
212 } 217 // signature that the Callback is representing.
213 void Run(T* obj) const { 218 //
214 DispatchToMethod(obj, m_, p_); 219 // After this, create template specializations for 0-6 parameters. Note that
215 } 220 // even though the template typelist grows, the specialization still
216 private: 221 // only has one type: the function signature.
217 Method m_; 222 template <typename Sig>
218 Params p_; 223 class Callback;
219 }; 224
220 225 template <typename R>
221 // Return value implementation with no args. 226 class Callback<R(void)> {
222 template <typename ReturnValue> 227 public:
223 struct CallbackWithReturnValue { 228 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*);
224 class Type { 229
225 public: 230 Callback() : polymorphic_invoke_(NULL) { }
226 virtual ~Type() {} 231
227 virtual ReturnValue Run() = 0; 232 // We pass InvokerStorageHolder by const ref to avoid incurring an
228 }; 233 // unnecessary AddRef/Unref pair even though we will modify the object.
229 }; 234 // We cannot use a normal reference because the compiler will warn
230 235 // since this is often used on a return value, which is a temporary.
231 template <class T, typename Method, typename ReturnValue> 236 //
232 class CallbackWithReturnValueImpl 237 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
233 : public CallbackStorage<T, Method>, 238 // return the exact Callback<> type. See base/bind.h for details.
234 public CallbackWithReturnValue<ReturnValue>::Type { 239 template <typename T>
235 public: 240 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
236 CallbackWithReturnValueImpl(T* obj, Method meth) 241 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) {
237 : CallbackStorage<T, Method>(obj, meth) {} 242 invoker_storage_.swap(invoker_holder.invoker_storage_);
238 243 }
239 virtual ReturnValue Run() { 244
240 return (this->obj_->*(this->meth_))(); 245 R Run(void) const {
241 } 246 return polymorphic_invoke_(invoker_storage_.get());
242 247 }
243 protected: 248
244 virtual ~CallbackWithReturnValueImpl() {} 249 private:
245 }; 250 scoped_refptr<internal::InvokerStorageBase> invoker_storage_;
246 251 PolymorphicInvoke polymorphic_invoke_;
247 template <class T, typename ReturnValue> 252 };
248 typename CallbackWithReturnValue<ReturnValue>::Type* 253
249 NewCallbackWithReturnValue(T* object, ReturnValue (T::*method)()) { 254 template <typename R, typename A1>
250 return new CallbackWithReturnValueImpl<T, ReturnValue (T::*)(), ReturnValue>( 255 class Callback<R(A1)> {
251 object, method); 256 public:
252 } 257 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&);
258
259 Callback() : polymorphic_invoke_(NULL) { }
260
261 // We pass InvokerStorageHolder by const ref to avoid incurring an
262 // unnecessary AddRef/Unref pair even though we will modify the object.
263 // We cannot use a normal reference because the compiler will warn
264 // since this is often used on a return value, which is a temporary.
265 //
266 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
267 // return the exact Callback<> type. See base/bind.h for details.
268 template <typename T>
269 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
270 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) {
271 invoker_storage_.swap(invoker_holder.invoker_storage_);
272 }
273
274 R Run(const A1& a1) const {
275 return polymorphic_invoke_(invoker_storage_.get(), a1);
276 }
277
278 private:
279 scoped_refptr<internal::InvokerStorageBase> invoker_storage_;
280 PolymorphicInvoke polymorphic_invoke_;
281 };
282
283 template <typename R, typename A1, typename A2>
284 class Callback<R(A1, A2)> {
285 public:
286 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
287 const A2&);
288
289 Callback() : polymorphic_invoke_(NULL) { }
290
291 // We pass InvokerStorageHolder by const ref to avoid incurring an
292 // unnecessary AddRef/Unref pair even though we will modify the object.
293 // We cannot use a normal reference because the compiler will warn
294 // since this is often used on a return value, which is a temporary.
295 //
296 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
297 // return the exact Callback<> type. See base/bind.h for details.
298 template <typename T>
299 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
300 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) {
301 invoker_storage_.swap(invoker_holder.invoker_storage_);
302 }
303
304 R Run(const A1& a1,
305 const A2& a2) const {
306 return polymorphic_invoke_(invoker_storage_.get(), a1,
307 a2);
308 }
309
310 private:
311 scoped_refptr<internal::InvokerStorageBase> invoker_storage_;
312 PolymorphicInvoke polymorphic_invoke_;
313 };
314
315 template <typename R, typename A1, typename A2, typename A3>
316 class Callback<R(A1, A2, A3)> {
317 public:
318 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
319 const A2&,
320 const A3&);
321
322 Callback() : polymorphic_invoke_(NULL) { }
323
324 // We pass InvokerStorageHolder by const ref to avoid incurring an
325 // unnecessary AddRef/Unref pair even though we will modify the object.
326 // We cannot use a normal reference because the compiler will warn
327 // since this is often used on a return value, which is a temporary.
328 //
329 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
330 // return the exact Callback<> type. See base/bind.h for details.
331 template <typename T>
332 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
333 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) {
334 invoker_storage_.swap(invoker_holder.invoker_storage_);
335 }
336
337 R Run(const A1& a1,
338 const A2& a2,
339 const A3& a3) const {
340 return polymorphic_invoke_(invoker_storage_.get(), a1,
341 a2,
342 a3);
343 }
344
345 private:
346 scoped_refptr<internal::InvokerStorageBase> invoker_storage_;
347 PolymorphicInvoke polymorphic_invoke_;
348 };
349
350 template <typename R, typename A1, typename A2, typename A3, typename A4>
351 class Callback<R(A1, A2, A3, A4)> {
352 public:
353 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
354 const A2&,
355 const A3&,
356 const A4&);
357
358 Callback() : polymorphic_invoke_(NULL) { }
359
360 // We pass InvokerStorageHolder by const ref to avoid incurring an
361 // unnecessary AddRef/Unref pair even though we will modify the object.
362 // We cannot use a normal reference because the compiler will warn
363 // since this is often used on a return value, which is a temporary.
364 //
365 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
366 // return the exact Callback<> type. See base/bind.h for details.
367 template <typename T>
368 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
369 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) {
370 invoker_storage_.swap(invoker_holder.invoker_storage_);
371 }
372
373 R Run(const A1& a1,
374 const A2& a2,
375 const A3& a3,
376 const A4& a4) const {
377 return polymorphic_invoke_(invoker_storage_.get(), a1,
378 a2,
379 a3,
380 a4);
381 }
382
383 private:
384 scoped_refptr<internal::InvokerStorageBase> invoker_storage_;
385 PolymorphicInvoke polymorphic_invoke_;
386 };
387
388 template <typename R, typename A1, typename A2, typename A3, typename A4,
389 typename A5>
390 class Callback<R(A1, A2, A3, A4, A5)> {
391 public:
392 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
393 const A2&,
394 const A3&,
395 const A4&,
396 const A5&);
397
398 Callback() : polymorphic_invoke_(NULL) { }
399
400 // We pass InvokerStorageHolder by const ref to avoid incurring an
401 // unnecessary AddRef/Unref pair even though we will modify the object.
402 // We cannot use a normal reference because the compiler will warn
403 // since this is often used on a return value, which is a temporary.
404 //
405 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
406 // return the exact Callback<> type. See base/bind.h for details.
407 template <typename T>
408 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
409 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) {
410 invoker_storage_.swap(invoker_holder.invoker_storage_);
411 }
412
413 R Run(const A1& a1,
414 const A2& a2,
415 const A3& a3,
416 const A4& a4,
417 const A5& a5) const {
418 return polymorphic_invoke_(invoker_storage_.get(), a1,
419 a2,
420 a3,
421 a4,
422 a5);
423 }
424
425 private:
426 scoped_refptr<internal::InvokerStorageBase> invoker_storage_;
427 PolymorphicInvoke polymorphic_invoke_;
428 };
429
430 template <typename R, typename A1, typename A2, typename A3, typename A4,
431 typename A5, typename A6>
432 class Callback<R(A1, A2, A3, A4, A5, A6)> {
433 public:
434 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
435 const A2&,
436 const A3&,
437 const A4&,
438 const A5&,
439 const A6&);
440
441 Callback() : polymorphic_invoke_(NULL) { }
442
443 // We pass InvokerStorageHolder by const ref to avoid incurring an
444 // unnecessary AddRef/Unref pair even though we will modify the object.
445 // We cannot use a normal reference because the compiler will warn
446 // since this is often used on a return value, which is a temporary.
447 //
448 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
449 // return the exact Callback<> type. See base/bind.h for details.
450 template <typename T>
451 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
452 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) {
453 invoker_storage_.swap(invoker_holder.invoker_storage_);
454 }
455
456 R Run(const A1& a1,
457 const A2& a2,
458 const A3& a3,
459 const A4& a4,
460 const A5& a5,
461 const A6& a6) const {
462 return polymorphic_invoke_(invoker_storage_.get(), a1,
463 a2,
464 a3,
465 a4,
466 a5,
467 a6);
468 }
469
470 private:
471 scoped_refptr<internal::InvokerStorageBase> invoker_storage_;
472 PolymorphicInvoke polymorphic_invoke_;
473 };
474
475
476 // Syntactic sugar to make Callbacks<void(void)> easier to declare since it
477 // will be used in a lot of APIs with delayed execution.
478 typedef Callback<void(void)> Closure;
479
480 } // namespace base
253 481
254 #endif // BASE_CALLBACK_H 482 #endif // BASE_CALLBACK_H
OLDNEW
« no previous file with comments | « base/bind_unittest.cc ('k') | base/callback.h.pump » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698