OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_CALLBACK_H_ | 5 #ifndef BASE_CALLBACK_H_ |
6 #define BASE_CALLBACK_H_ | 6 #define BASE_CALLBACK_H_ |
7 | 7 |
8 #include "base/callback_forward.h" | 8 #include "base/callback_forward.h" |
9 #include "base/callback_internal.h" | 9 #include "base/callback_internal.h" |
10 #include "base/template_util.h" | 10 #include "base/template_util.h" |
11 | 11 |
12 // NOTE: Header files that do not require the full definition of Callback or | 12 // NOTE: Header files that do not require the full definition of Callback or |
13 // Closure should #include "base/callback_forward.h" instead of this file. | 13 // Closure should #include "base/callback_forward.h" instead of this file. |
14 | 14 |
15 // ----------------------------------------------------------------------------- | 15 // ----------------------------------------------------------------------------- |
16 // Introduction | 16 // Introduction |
17 // ----------------------------------------------------------------------------- | 17 // ----------------------------------------------------------------------------- |
18 // | 18 // |
19 // The templated Callback class is a generalized function object. Together | 19 // The templated Callback class is a generalized function object. Together |
20 // with the Bind() function in bind.h, they provide a type-safe method for | 20 // with the Bind() function in bind.h, they provide a type-safe method for |
21 // performing partial application of functions. | 21 // performing partial application of functions. |
22 // | 22 // |
23 // Partial application (or "currying") is the process of binding a subset of | 23 // Partial application (or "currying") is the process of binding a subset of |
24 // a function's arguments to produce another function that takes fewer | 24 // a function's arguments to produce another function that takes fewer |
25 // arguments. This can be used to pass around a unit of delayed execution, | 25 // arguments. This can be used to pass around a unit of delayed execution, |
26 // much like lexical closures are used in other languages. For example, it | 26 // much like lexical closures are used in other languages. For example, it |
27 // is used in Chromium code to schedule tasks on different MessageLoops. | 27 // is used in Chromium code to schedule tasks on different MessageLoops. |
28 // | 28 // |
29 // A callback with no unbound input parameters (base::Callback<void(void)>) | 29 // A callback with no unbound input parameters (base::Callback<void()>) |
30 // is called a base::Closure. Note that this is NOT the same as what other | 30 // is called a base::Closure. Note that this is NOT the same as what other |
31 // languages refer to as a closure -- it does not retain a reference to its | 31 // languages refer to as a closure -- it does not retain a reference to its |
32 // enclosing environment. | 32 // enclosing environment. |
33 // | 33 // |
34 // MEMORY MANAGEMENT AND PASSING | 34 // MEMORY MANAGEMENT AND PASSING |
35 // | 35 // |
36 // The Callback objects themselves should be passed by const-reference, and | 36 // The Callback objects themselves should be passed by const-reference, and |
37 // stored by copy. They internally store their state via a refcounted class | 37 // stored by copy. They internally store their state via a refcounted class |
38 // and thus do not need to be deleted. | 38 // and thus do not need to be deleted. |
39 // | 39 // |
40 // The reason to pass via a const-reference is to avoid unnecessary | 40 // The reason to pass via a const-reference is to avoid unnecessary |
41 // AddRef/Release pairs to the internal state. | 41 // AddRef/Release pairs to the internal state. |
42 // | 42 // |
43 // | 43 // |
44 // ----------------------------------------------------------------------------- | 44 // ----------------------------------------------------------------------------- |
45 // Quick reference for basic stuff | 45 // Quick reference for basic stuff |
46 // ----------------------------------------------------------------------------- | 46 // ----------------------------------------------------------------------------- |
47 // | 47 // |
48 // BINDING A BARE FUNCTION | 48 // BINDING A BARE FUNCTION |
49 // | 49 // |
50 // int Return5() { return 5; } | 50 // int Return5() { return 5; } |
51 // base::Callback<int(void)> func_cb = base::Bind(&Return5); | 51 // base::Callback<int()> func_cb = base::Bind(&Return5); |
52 // LOG(INFO) << func_cb.Run(); // Prints 5. | 52 // LOG(INFO) << func_cb.Run(); // Prints 5. |
53 // | 53 // |
54 // BINDING A CLASS METHOD | 54 // BINDING A CLASS METHOD |
55 // | 55 // |
56 // The first argument to bind is the member function to call, the second is | 56 // The first argument to bind is the member function to call, the second is |
57 // the object on which to call it. | 57 // the object on which to call it. |
58 // | 58 // |
59 // class Ref : public base::RefCountedThreadSafe<Ref> { | 59 // class Ref : public base::RefCountedThreadSafe<Ref> { |
60 // public: | 60 // public: |
61 // int Foo() { return 3; } | 61 // int Foo() { return 3; } |
62 // void PrintBye() { LOG(INFO) << "bye."; } | 62 // void PrintBye() { LOG(INFO) << "bye."; } |
63 // }; | 63 // }; |
64 // scoped_refptr<Ref> ref = new Ref(); | 64 // scoped_refptr<Ref> ref = new Ref(); |
65 // base::Callback<void(void)> ref_cb = base::Bind(&Ref::Foo, ref); | 65 // base::Callback<void()> ref_cb = base::Bind(&Ref::Foo, ref); |
66 // LOG(INFO) << ref_cb.Run(); // Prints out 3. | 66 // LOG(INFO) << ref_cb.Run(); // Prints out 3. |
67 // | 67 // |
68 // By default the object must support RefCounted or you will get a compiler | 68 // By default the object must support RefCounted or you will get a compiler |
69 // error. If you're passing between threads, be sure it's | 69 // error. If you're passing between threads, be sure it's |
70 // RefCountedThreadSafe! See "Advanced binding of member functions" below if | 70 // RefCountedThreadSafe! See "Advanced binding of member functions" below if |
71 // you don't want to use reference counting. | 71 // you don't want to use reference counting. |
72 // | 72 // |
73 // RUNNING A CALLBACK | 73 // RUNNING A CALLBACK |
74 // | 74 // |
75 // Callbacks can be run with their "Run" method, which has the same | 75 // Callbacks can be run with their "Run" method, which has the same |
(...skipping 21 matching lines...) Expand all Loading... |
97 // cb.Run(23, "hello, world"); | 97 // cb.Run(23, "hello, world"); |
98 // | 98 // |
99 // PASSING BOUND INPUT PARAMETERS | 99 // PASSING BOUND INPUT PARAMETERS |
100 // | 100 // |
101 // Bound parameters are specified when you create thee callback as arguments | 101 // Bound parameters are specified when you create thee callback as arguments |
102 // to Bind(). They will be passed to the function and the Run()ner of the | 102 // to Bind(). They will be passed to the function and the Run()ner of the |
103 // callback doesn't see those values or even know that the function it's | 103 // callback doesn't see those values or even know that the function it's |
104 // calling. | 104 // calling. |
105 // | 105 // |
106 // void MyFunc(int i, const std::string& str) {} | 106 // void MyFunc(int i, const std::string& str) {} |
107 // base::Callback<void(void)> cb = base::Bind(&MyFunc, 23, "hello world"); | 107 // base::Callback<void()> cb = base::Bind(&MyFunc, 23, "hello world"); |
108 // cb.Run(); | 108 // cb.Run(); |
109 // | 109 // |
110 // A callback with no unbound input parameters (base::Callback<void(void)>) | 110 // A callback with no unbound input parameters (base::Callback<void()>) |
111 // is called a base::Closure. So we could have also written: | 111 // is called a base::Closure. So we could have also written: |
112 // | 112 // |
113 // base::Closure cb = base::Bind(&MyFunc, 23, "hello world"); | 113 // base::Closure cb = base::Bind(&MyFunc, 23, "hello world"); |
114 // | 114 // |
115 // When calling member functions, bound parameters just go after the object | 115 // When calling member functions, bound parameters just go after the object |
116 // pointer. | 116 // pointer. |
117 // | 117 // |
118 // base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world"); | 118 // base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world"); |
119 // | 119 // |
120 // PARTIAL BINDING OF PARAMETERS | 120 // PARTIAL BINDING OF PARAMETERS |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 // base::Callback<void(int)> cb = | 168 // base::Callback<void(int)> cb = |
169 // base::Bind(base::IgnoreResult(&DoSomething)); | 169 // base::Bind(base::IgnoreResult(&DoSomething)); |
170 // | 170 // |
171 // | 171 // |
172 // ----------------------------------------------------------------------------- | 172 // ----------------------------------------------------------------------------- |
173 // Quick reference for binding parameters to Bind() | 173 // Quick reference for binding parameters to Bind() |
174 // ----------------------------------------------------------------------------- | 174 // ----------------------------------------------------------------------------- |
175 // | 175 // |
176 // Bound parameters are specified as arguments to Bind() and are passed to the | 176 // Bound parameters are specified as arguments to Bind() and are passed to the |
177 // function. A callback with no parameters or no unbound parameters is called a | 177 // function. A callback with no parameters or no unbound parameters is called a |
178 // Closure (base::Callback<void(void)> and base::Closure are the same thing). | 178 // Closure (base::Callback<void()> and base::Closure are the same thing). |
179 // | 179 // |
180 // PASSING PARAMETERS OWNED BY THE CALLBACK | 180 // PASSING PARAMETERS OWNED BY THE CALLBACK |
181 // | 181 // |
182 // void Foo(int* arg) { cout << *arg << endl; } | 182 // void Foo(int* arg) { cout << *arg << endl; } |
183 // int* pn = new int(1); | 183 // int* pn = new int(1); |
184 // base::Closure foo_callback = base::Bind(&foo, base::Owned(pn)); | 184 // base::Closure foo_callback = base::Bind(&foo, base::Owned(pn)); |
185 // | 185 // |
186 // The parameter will be deleted when the callback is destroyed, even if it's | 186 // The parameter will be deleted when the callback is destroyed, even if it's |
187 // not run (like if you post a task during shutdown). | 187 // not run (like if you post a task during shutdown). |
188 // | 188 // |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 // please include "base/callback_forward.h" instead. | 356 // please include "base/callback_forward.h" instead. |
357 | 357 |
358 namespace internal { | 358 namespace internal { |
359 template <typename Runnable, typename RunType, typename... BoundArgsType> | 359 template <typename Runnable, typename RunType, typename... BoundArgsType> |
360 struct BindState; | 360 struct BindState; |
361 } // namespace internal | 361 } // namespace internal |
362 | 362 |
363 template <typename R, typename... Args> | 363 template <typename R, typename... Args> |
364 class Callback<R(Args...)> : public internal::CallbackBase { | 364 class Callback<R(Args...)> : public internal::CallbackBase { |
365 public: | 365 public: |
366 typedef R(RunType)(Args...); | 366 // MSVC 2013 doesn't support Type Alias of function types. |
| 367 // Revisit this after we update it to newer version. |
| 368 typedef R RunType(Args...); |
367 | 369 |
368 Callback() : CallbackBase(nullptr) { } | 370 Callback() : CallbackBase(nullptr) { } |
369 | 371 |
370 template <typename Runnable, typename BindRunType, typename... BoundArgsType> | 372 template <typename Runnable, typename BindRunType, typename... BoundArgsType> |
371 explicit Callback( | 373 explicit Callback( |
372 internal::BindState<Runnable, BindRunType, BoundArgsType...>* bind_state) | 374 internal::BindState<Runnable, BindRunType, BoundArgsType...>* bind_state) |
373 : CallbackBase(bind_state) { | 375 : CallbackBase(bind_state) { |
374 // Force the assignment to a local variable of PolymorphicInvoke | 376 // Force the assignment to a local variable of PolymorphicInvoke |
375 // so the compiler will typecheck that the passed in Run() method has | 377 // so the compiler will typecheck that the passed in Run() method has |
376 // the correct type. | 378 // the correct type. |
377 PolymorphicInvoke invoke_func = | 379 PolymorphicInvoke invoke_func = |
378 &internal::BindState<Runnable, BindRunType, BoundArgsType...> | 380 &internal::BindState<Runnable, BindRunType, BoundArgsType...> |
379 ::InvokerType::Run; | 381 ::InvokerType::Run; |
380 polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func); | 382 polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func); |
381 } | 383 } |
382 | 384 |
383 bool Equals(const Callback& other) const { | 385 bool Equals(const Callback& other) const { |
384 return CallbackBase::Equals(other); | 386 return CallbackBase::Equals(other); |
385 } | 387 } |
386 | 388 |
387 R Run(typename internal::CallbackParamTraits<Args>::ForwardType... args) | 389 R Run(typename internal::CallbackParamTraits<Args>::ForwardType... args) |
388 const { | 390 const { |
389 PolymorphicInvoke f = | 391 PolymorphicInvoke f = |
390 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_); | 392 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_); |
391 | 393 |
392 return f(bind_state_.get(), internal::CallbackForward(args)...); | 394 return f(bind_state_.get(), internal::CallbackForward(args)...); |
393 } | 395 } |
394 | 396 |
395 private: | 397 private: |
396 typedef R(*PolymorphicInvoke)( | 398 using PolymorphicInvoke = |
397 internal::BindStateBase*, | 399 R(*)(internal::BindStateBase*, |
398 typename internal::CallbackParamTraits<Args>::ForwardType...); | 400 typename internal::CallbackParamTraits<Args>::ForwardType...); |
399 }; | 401 }; |
400 | 402 |
401 } // namespace base | 403 } // namespace base |
402 | 404 |
403 #endif // BASE_CALLBACK_H_ | 405 #endif // BASE_CALLBACK_H_ |
OLD | NEW |