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

Side by Side Diff: docs/callback.md

Issue 2318113002: Update //docs/callback.md for OnceCallback and RepeatingCallback (Closed)
Patch Set: . Created 4 years, 2 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # base::Callback<> and base::Bind() 1 # Callback<> and Bind()
2 2
3 ## Introduction 3 ## Introduction
4 4
5 The templated `Callback<>` class is a generalized function object. Together with 5 The templated `Callback<>` class is a generalized function object. Together with
6 the `Bind()` function in base/bind.h, they provide a type-safe method for 6 the `Bind()` function in base/bind.h, they provide a type-safe method for
7 performing partial application of functions. 7 performing partial application of functions.
8 8
9 Partial application (or "currying") is the process of binding a subset of a 9 Partial application (or "currying") is the process of binding a subset of a
10 function's arguments to produce another function that takes fewer arguments. 10 function's arguments to produce another function that takes fewer arguments.
11 This can be used to pass around a unit of delayed execution, much like lexical 11 This can be used to pass around a unit of delayed execution, much like lexical
12 closures are used in other languages. For example, it is used in Chromium code 12 closures are used in other languages. For example, it is used in Chromium code
13 to schedule tasks on different MessageLoops. 13 to schedule tasks on different MessageLoops.
14 14
15 A callback with no unbound input parameters (`Callback<void()>`) is called a 15 A callback with no unbound input parameters (`Callback<void()>`) is called a
16 `Closure`. Note that this is NOT the same as what other languages refer to as a 16 `Closure`. Note that this is NOT the same as what other languages refer to as a
17 closure -- it does not retain a reference to its enclosing environment. 17 closure -- it does not retain a reference to its enclosing environment.
18 18
19 ### OnceCallback<> And RepeatingCallback<>
20
21 `OnceCallback<>` and `RepeatingCallback<>` are next gen callback classes, which
22 are under development.
23
24 `OnceCallback<>` is created by `BindOnce()`. This is a callback variant that is
25 a move-only type and can be run only once. This moves out bound parameters from
26 its internal storage to the bound function by default, so it's easier to use
27 with movable types. This should be the preferred callback type: since the
28 lifetime of the callback is clear, it's simpler to reason about when a callback
29 that is passed between threads is destroyed.
30
31 `RepeatingCallback<>` is created by `BindRepeating()`. This is a callback
32 variant that is copyable that can be run multiple times. It uses internal
33 ref-counting to make copies cheap. However, since ownership is shared, it is
34 harder to reason about when the callback and the bound state are destroyed,
35 especially when the callback is passed between threads.
36
37 The legacy `Callback<>` is currently aliased to `RepeatingCallback<>`. In new
38 code, prefer to explicitly use `OnceCallback<>` where possible or
Yuta Kitamura 2016/10/05 06:15:53 "to explicitly use" => remove "or `RepeatingCallb
tzik 2016/10/05 08:04:21 Done.
39 `RepeatingCallback<>` otherwise. Once the migration is complete, the type alias
40 will be removed and `OnceCallback<>` will be renamed to `Callback<>` to
41 emphasize that it should be preferred.
42
43 `RepeatingCallback<>` is convertible to `OnceCallback<>` by the implicit
44 conversion.
45
19 ### Memory Management And Passing 46 ### Memory Management And Passing
20 47
21 The Callback objects themselves should be passed by const-reference, and stored 48 Pass `Callback` objects by value if ownership is transferred; otherwise, pass it
22 by copy. They internally store their state via a refcounted class and thus do 49 by const-reference.
23 not need to be deleted.
24 50
25 The reason to pass via a const-reference is to avoid unnecessary AddRef/Release 51 ```cpp
26 pairs to the internal state. 52 // |Foo| just refers to |cb| but doesn't store it nor consume it.
53 bool Foo(const OnceCallback<void(int)>& cb) {
54 return cb.is_null();
55 }
56
57 // |Bar| takes the ownership of |cb| and stores |cb| into |g_cb|.
58 OnceCallback<void(int)> g_cb;
59 void Bar(OnceCallback<void(int)> cb) {
60 g_cb = std::move(cb);
61 }
62
63 // |Baz| takes the ownership of |cb| and consumes |cb| by Run().
64 void Baz(OnceCallback<void(int)> cb) {
65 std::move(cb).Run(42);
66 }
67
68 // |Qux| takes the ownership of |cb| and transfers ownership to PostTask(),
69 // which also takes the ownership of |cb|.
70 void Qux(OnceCallback<void(int)> cb) {
71 PostTask(FROM_HERE, std::move(cb));
72 }
73 ```
74
75 When you pass a `Callback` object to a function parameter, use `std::move()` if
76 you don't need to keep a reference to it, otherwise, pass the object directly.
77 You may see a compile error when the function requires the exclusive ownership,
78 and you didn't pass the callback by move.
27 79
28 ## Quick reference for basic stuff 80 ## Quick reference for basic stuff
29 81
30 ### Binding A Bare Function 82 ### Binding A Bare Function
31 83
32 ```cpp 84 ```cpp
33 int Return5() { return 5; } 85 int Return5() { return 5; }
34 base::Callback<int()> func_cb = base::Bind(&Return5); 86 OnceCallback<int()> func_cb = BindOnce(&Return5);
87 LOG(INFO) << std::move(func_cb).Run(); // Prints 5.
88 ```
89
90 ```cpp
91 int Return5() { return 5; }
92 RepeatingCallback<int()> func_cb = BindRepeating(&Return5);
35 LOG(INFO) << func_cb.Run(); // Prints 5. 93 LOG(INFO) << func_cb.Run(); // Prints 5.
36 ``` 94 ```
37 95
96 ### Binding A Captureless Lambda
97
98 ```cpp
99 Callback<int()> lambda_cb = Bind([] { return 4; });
100 LOG(INFO) << lambda_cb.Run(); // Print 4.
101
102 OnceCallback<int()> lambda_cb2 = BindOnce([] { return 3; });
103 LOG(INFO) << std::move(lambda_cb2).Run(); // Print 3.
104 ```
105
38 ### Binding A Class Method 106 ### Binding A Class Method
39 107
40 The first argument to bind is the member function to call, the second is the 108 The first argument to bind is the member function to call, the second is the
41 object on which to call it. 109 object on which to call it.
42 110
43 ```cpp 111 ```cpp
44 class Ref : public base::RefCountedThreadSafe<Ref> { 112 class Ref : public RefCountedThreadSafe<Ref> {
45 public: 113 public:
46 int Foo() { return 3; } 114 int Foo() { return 3; }
47 void PrintBye() { LOG(INFO) << "bye."; }
48 }; 115 };
49 scoped_refptr<Ref> ref = new Ref(); 116 scoped_refptr<Ref> ref = new Ref();
50 base::Callback<void()> ref_cb = base::Bind(&Ref::Foo, ref); 117 Callback<void()> ref_cb = Bind(&Ref::Foo, ref);
51 LOG(INFO) << ref_cb.Run(); // Prints out 3. 118 LOG(INFO) << ref_cb.Run(); // Prints out 3.
52 ``` 119 ```
53 120
54 By default the object must support RefCounted or you will get a compiler 121 By default the object must support RefCounted or you will get a compiler
55 error. If you're passing between threads, be sure it's 122 error. If you're passing between threads, be sure it's RefCountedThreadSafe! See
56 RefCountedThreadSafe! See "Advanced binding of member functions" below if 123 "Advanced binding of member functions" below if you don't want to use reference
57 you don't want to use reference counting. 124 counting.
58 125
59 ### Running A Callback 126 ### Running A Callback
60 127
61 Callbacks can be run with their `Run` method, which has the same 128 Callbacks can be run with their `Run` method, which has the same signature as
62 signature as the template argument to the callback. 129 the template argument to the callback. Note that `OnceCallback::Run` consumes
130 the callback object and can only be invoked on a callback rvalue.
63 131
64 ```cpp 132 ```cpp
65 void DoSomething(const base::Callback<void(int, std::string)>& callback) { 133 void DoSomething(const Callback<void(int, std::string)>& callback) {
66 callback.Run(5, "hello"); 134 callback.Run(5, "hello");
67 } 135 }
136
137 void DoSomethingOther(OnceCallback<void(int, std::string)> callback) {
138 std::move(callback).Run(5, "hello");
139 }
68 ``` 140 ```
69 141
70 Callbacks can be run more than once (they don't get deleted or marked when 142 RepeatingCallbacks can be run more than once (they don't get deleted or marked
71 run). However, this precludes using base::Passed (see below). 143 when run). However, this precludes using Passed (see below).
72 144
73 ```cpp 145 ```cpp
74 void DoSomething(const base::Callback<double(double)>& callback) { 146 void DoSomething(const RepeatingCallback<double(double)>& callback) {
75 double myresult = callback.Run(3.14159); 147 double myresult = callback.Run(3.14159);
76 myresult += callback.Run(2.71828); 148 myresult += callback.Run(2.71828);
77 } 149 }
78 ``` 150 ```
79 151
80 ### Passing Unbound Input Parameters 152 ### Passing Unbound Input Parameters
81 153
82 Unbound parameters are specified at the time a callback is `Run()`. They are 154 Unbound parameters are specified at the time a callback is `Run()`. They are
83 specified in the `Callback` template type: 155 specified in the `Callback` template type:
84 156
85 ```cpp 157 ```cpp
86 void MyFunc(int i, const std::string& str) {} 158 void MyFunc(int i, const std::string& str) {}
87 base::Callback<void(int, const std::string&)> cb = base::Bind(&MyFunc); 159 Callback<void(int, const std::string&)> cb = Bind(&MyFunc);
88 cb.Run(23, "hello, world"); 160 cb.Run(23, "hello, world");
89 ``` 161 ```
90 162
91 ### Passing Bound Input Parameters 163 ### Passing Bound Input Parameters
92 164
93 Bound parameters are specified when you create the callback as arguments to 165 Bound parameters are specified when you create the callback as arguments to
94 `Bind()`. They will be passed to the function and the `Run()`ner of the callback 166 `Bind()`. They will be passed to the function and the `Run()`ner of the callback
95 doesn't see those values or even know that the function it's calling. 167 doesn't see those values or even know that the function it's calling.
96 168
97 ```cpp 169 ```cpp
98 void MyFunc(int i, const std::string& str) {} 170 void MyFunc(int i, const std::string& str) {}
99 base::Callback<void()> cb = base::Bind(&MyFunc, 23, "hello world"); 171 Callback<void()> cb = Bind(&MyFunc, 23, "hello world");
100 cb.Run(); 172 cb.Run();
101 ``` 173 ```
102 174
103 A callback with no unbound input parameters (`base::Callback<void()>`) is called 175 A callback with no unbound input parameters (`Callback<void()>`) is called a
104 a `base::Closure`. So we could have also written: 176 `Closure`. So we could have also written:
105 177
106 ```cpp 178 ```cpp
107 base::Closure cb = base::Bind(&MyFunc, 23, "hello world"); 179 Closure cb = Bind(&MyFunc, 23, "hello world");
108 ``` 180 ```
109 181
110 When calling member functions, bound parameters just go after the object 182 When calling member functions, bound parameters just go after the object
111 pointer. 183 pointer.
112 184
113 ```cpp 185 ```cpp
114 base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world"); 186 Closure cb = Bind(&MyClass::MyFunc, this, 23, "hello world");
115 ``` 187 ```
116 188
117 ### Partial Binding Of Parameters 189 ### Partial Binding Of Parameters
118 190
119 You can specify some parameters when you create the callback, and specify the 191 You can specify some parameters when you create the callback, and specify the
120 rest when you execute the callback. 192 rest when you execute the callback.
121 193
122 ```cpp 194 ```cpp
123 void MyFunc(int i, const std::string& str) {} 195 void MyFunc(int i, const std::string& str) {}
124 base::Callback<void(const std::string&)> cb = base::Bind(&MyFunc, 23); 196 Callback<void(const std::string&)> cb = Bind(&MyFunc, 23);
125 cb.Run("hello world"); 197 cb.Run("hello world");
126 ``` 198 ```
127 199
128 When calling a function bound parameters are first, followed by unbound 200 When calling a function bound parameters are first, followed by unbound
129 parameters. 201 parameters.
130 202
203 ### Move In and Move Out
dcheng 2016/10/04 22:26:25 Random thought: maybe title this section "Avoiding
tzik 2016/10/05 08:04:21 Done.
204
205 A parameter of `Bind()` is moved into its internal storage if it is passed as a
206 rvalue.
207
208 ```cpp
209 std::vector<int> v = {1, 2, 3};
210 // |v| is moved into the internal storage without copy.
211 Bind(&Foo, std::move(v));
212 ```
213
214 ```cpp
215 std::vector<int> v = {1, 2, 3};
216 // The vector is moved into the internal storage without copy.
217 Bind(&Foo, std::vector<int>({1, 2, 3}));
218 ```
219
220 A bound object is moved out to the target function if you use `Passed()` for
221 the parameter. If you use `BindOnce()`, the bound object is moved out even
222 without `Passed()`.
223
224 ```cpp
225 void Foo(std::unique_ptr<int>) {}
226 std::unique_ptr<int> p(new int(42));
227
228 // |p| is moved into the internal storage of Bind(), and moved out to |Foo|.
229 BindOnce(&Foo, std::move(p));
230 BindRepeating(&Foo, Passed(&p));
231 ```
232
131 ## Quick reference for advanced binding 233 ## Quick reference for advanced binding
132 234
133 ### Binding A Class Method With Weak Pointers 235 ### Binding A Class Method With Weak Pointers
134 236
135 ```cpp 237 ```cpp
136 base::Bind(&MyClass::Foo, GetWeakPtr()); 238 Bind(&MyClass::Foo, GetWeakPtr());
137 ``` 239 ```
138 240
139 The callback will not be run if the object has already been destroyed. 241 The callback will not be run if the object has already been destroyed.
140 **DANGER**: weak pointers are not threadsafe, so don't use this when passing bet ween 242 **DANGER**: weak pointers are not threadsafe, so don't use this when passing bet ween
141 threads! 243 threads!
142 244
143 ### Binding A Class Method With Manual Lifetime Management 245 ### Binding A Class Method With Manual Lifetime Management
144 246
145 ```cpp 247 ```cpp
146 base::Bind(&MyClass::Foo, base::Unretained(this)); 248 Bind(&MyClass::Foo, Unretained(this));
147 ``` 249 ```
148 250
149 This disables all lifetime management on the object. You're responsible for 251 This disables all lifetime management on the object. You're responsible for
150 making sure the object is alive at the time of the call. You break it, you own 252 making sure the object is alive at the time of the call. You break it, you own
151 it! 253 it!
152 254
153 ### Binding A Class Method And Having The Callback Own The Class 255 ### Binding A Class Method And Having The Callback Own The Class
154 256
155 ```cpp 257 ```cpp
156 MyClass* myclass = new MyClass; 258 MyClass* myclass = new MyClass;
157 base::Bind(&MyClass::Foo, base::Owned(myclass)); 259 Bind(&MyClass::Foo, Owned(myclass));
158 ``` 260 ```
159 261
160 The object will be deleted when the callback is destroyed, even if it's not run 262 The object will be deleted when the callback is destroyed, even if it's not run
161 (like if you post a task during shutdown). Potentially useful for "fire and 263 (like if you post a task during shutdown). Potentially useful for "fire and
162 forget" cases. 264 forget" cases.
163 265
266 Smart pointers (e.g. `std::unique_ptr<>`) are also supported as the receiver.
267
268 ```cpp
269 std::unique_ptr<MyClass> myclass(new MyClass);
270 Bind(&MyClass::Foo, std::move(myclass));
271 ```
272
164 ### Ignoring Return Values 273 ### Ignoring Return Values
165 274
166 Sometimes you want to call a function that returns a value in a callback that 275 Sometimes you want to call a function that returns a value in a callback that
167 doesn't expect a return value. 276 doesn't expect a return value.
168 277
169 ```cpp 278 ```cpp
170 int DoSomething(int arg) { cout << arg << endl; } 279 int DoSomething(int arg) { cout << arg << endl; }
171 base::Callback<void(int)> cb = 280 Callback<void(int)> cb =
172 base::Bind(base::IgnoreResult(&DoSomething)); 281 Bind(IgnoreResult(&DoSomething));
173 ``` 282 ```
174 283
175 ## Quick reference for binding parameters to Bind() 284 ## Quick reference for binding parameters to Bind()
176 285
177 Bound parameters are specified as arguments to `Bind()` and are passed to the 286 Bound parameters are specified as arguments to `Bind()` and are passed to the
178 function. A callback with no parameters or no unbound parameters is called a 287 function. A callback with no parameters or no unbound parameters is called a
179 `Closure` (`base::Callback<void()>` and `base::Closure` are the same thing). 288 `Closure` (`Callback<void()>` and `Closure` are the same thing).
180 289
181 ### Passing Parameters Owned By The Callback 290 ### Passing Parameters Owned By The Callback
182 291
183 ```cpp 292 ```cpp
184 void Foo(int* arg) { cout << *arg << endl; } 293 void Foo(int* arg) { cout << *arg << endl; }
185 int* pn = new int(1); 294 int* pn = new int(1);
186 base::Closure foo_callback = base::Bind(&foo, base::Owned(pn)); 295 Closure foo_callback = Bind(&foo, Owned(pn));
187 ``` 296 ```
188 297
189 The parameter will be deleted when the callback is destroyed, even if it's not 298 The parameter will be deleted when the callback is destroyed, even if it's not
190 run (like if you post a task during shutdown). 299 run (like if you post a task during shutdown).
191 300
192 ### Passing Parameters As A unique_ptr 301 ### Passing Parameters As A unique_ptr
193 302
194 ```cpp 303 ```cpp
195 void TakesOwnership(std::unique_ptr<Foo> arg) {} 304 void TakesOwnership(std::unique_ptr<Foo> arg) {}
196 std::unique_ptr<Foo> f(new Foo); 305 std::unique_ptr<Foo> f(new Foo);
197 // f becomes null during the following call. 306 // f becomes null during the following call.
198 base::Closure cb = base::Bind(&TakesOwnership, base::Passed(&f)); 307 RepeatingClosure cb = BindRepeating(&TakesOwnership, Passed(&f));
199 ``` 308 ```
200 309
201 Ownership of the parameter will be with the callback until the callback is run, 310 Ownership of the parameter will be with the callback until the callback is run,
202 and then ownership is passed to the callback function. This means the callback 311 and then ownership is passed to the callback function. This means the callback
203 can only be run once. If the callback is never run, it will delete the object 312 can only be run once. If the callback is never run, it will delete the object
204 when it's destroyed. 313 when it's destroyed.
205 314
206 ### Passing Parameters As A scoped_refptr 315 ### Passing Parameters As A scoped_refptr
207 316
208 ```cpp 317 ```cpp
209 void TakesOneRef(scoped_refptr<Foo> arg) {} 318 void TakesOneRef(scoped_refptr<Foo> arg) {}
210 scoped_refptr<Foo> f(new Foo) 319 scoped_refptr<Foo> f(new Foo);
211 base::Closure cb = base::Bind(&TakesOneRef, f); 320 Closure cb = Bind(&TakesOneRef, f);
212 ``` 321 ```
213 322
214 This should "just work." The closure will take a reference as long as it is 323 This should "just work." The closure will take a reference as long as it is
215 alive, and another reference will be taken for the called function. 324 alive, and another reference will be taken for the called function.
216 325
326 ```cpp
327 void DontTakeRef(Foo* arg) {}
328 scoped_refptr<Foo> f(new Foo);
329 Closure cb = Bind(&DontTakeRef, RetainedRef(f));
330 ```
331
332 `RetainedRef` holds a reference to the object and passes a raw pointer to
333 the object when the Callback is run.
334
217 ### Passing Parameters By Reference 335 ### Passing Parameters By Reference
218 336
219 Const references are *copied* unless `ConstRef` is used. Example: 337 Const references are *copied* unless `ConstRef` is used. Example:
220 338
221 ```cpp 339 ```cpp
222 void foo(const int& arg) { printf("%d %p\n", arg, &arg); } 340 void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
223 int n = 1; 341 int n = 1;
224 base::Closure has_copy = base::Bind(&foo, n); 342 Closure has_copy = Bind(&foo, n);
225 base::Closure has_ref = base::Bind(&foo, base::ConstRef(n)); 343 Closure has_ref = Bind(&foo, ConstRef(n));
226 n = 2; 344 n = 2;
227 foo(n); // Prints "2 0xaaaaaaaaaaaa" 345 foo(n); // Prints "2 0xaaaaaaaaaaaa"
228 has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb" 346 has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb"
229 has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa" 347 has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa"
230 ``` 348 ```
231 349
232 Normally parameters are copied in the closure. 350 Normally parameters are copied in the closure.
233 **DANGER**: ConstRef stores a const reference instead, referencing the original 351 **DANGER**: `ConstRef` stores a const reference instead, referencing the
234 parameter. This means that you must ensure the object outlives the callback! 352 original parameter. This means that you must ensure the object outlives the
353 callback!
235 354
236 ## Implementation notes 355 ## Implementation notes
237 356
238 ### Where Is This Design From: 357 ### Where Is This Design From:
239 358
240 The design `Callback` and Bind is heavily influenced by C++'s `tr1::function` / 359 The design `Callback` and Bind is heavily influenced by C++'s `tr1::function` /
241 `tr1::bind`, and by the "Google Callback" system used inside Google. 360 `tr1::bind`, and by the "Google Callback" system used inside Google.
242 361
362 ### Customizing the behavior
363
364 There are several injection points that controls `Bind` behavior from outside of
365 its implementation.
366
367 ```cpp
368 template <typename Receiver>
369 struct IsWeakReceiver {
370 static constexpr bool value = false;
371 };
372
373 template <typename Obj>
374 struct UnwrapTraits {
375 template <typename T>
376 T&& Unwrap(T&& obj) {
377 return std::forward<T>(obj);
378 }
379 };
380 ```
381
382 If `IsWeakReceiver<Receiver>::value` is true on a receiver of a method, `Bind`
383 checks if the receiver is evaluated to true and cancels the invocation if it's
384 evaluated to false. You can specialize `IsWeakReceiver` to make an external
385 smart pointer as a weak pointer.
386
387 `UnwrapTraits<BoundObject>::Unwrap()` is called for each bound arguments right
388 before `Callback` calls the target function. You can specialize this to define
389 an argument wrapper such as `Unretained`, `ConstRef`, `Owned`, `RetainedRef` and
390 `Passed`.
391
243 ### How The Implementation Works: 392 ### How The Implementation Works:
244 393
245 There are three main components to the system: 394 There are three main components to the system:
246 1) The Callback classes. 395 1) The `Callback<>` classes.
247 2) The `Bind()` functions. 396 2) The `Bind()` functions.
248 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`). 397 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`).
249 398
250 The Callback classes represent a generic function pointer. Internally, it stores 399 The Callback classes represent a generic function pointer. Internally, it stores
251 a refcounted piece of state that represents the target function and all its 400 a refcounted piece of state that represents the target function and all its
252 bound parameters. Each `Callback` specialization has a templated constructor 401 bound parameters. The `Callback` constructor takes a `BindStateBase*`, which is
253 that takes an `BindState<>*`. In the context of the constructor, the static 402 upcasted from a `BindState<>`. In the context of the constructor, the static
254 type of this `BindState<>` pointer uniquely identifies the function it is 403 type of this `BindState<>` pointer uniquely identifies the function it is
255 representing, all its bound parameters, and a `Run()` method that is capable of 404 representing, all its bound parameters, and a `Run()` method that is capable of
256 invoking the target. 405 invoking the target.
257 406
258 `Callback`'s constructor takes the `BindState<>*` that has the full static type 407 `Bind()` creates the `BindState<>` that has the full static type, and erases the
259 and erases the target function type as well as the types of the bound 408 target function type as well as the types of the bound parameters. It does this
260 parameters. It does this by storing a pointer to the specific `Run()` function, 409 by storing a pointer to the specific `Run()` function, and upcasting the state
261 and upcasting the state of `BindState<>*` to a `BindStateBase*`. This is safe as 410 of `BindState<>*` to a `BindStateBase*`. This is safe as long as this
262 long as this `BindStateBase` pointer is only used with the stored `Run()` 411 `BindStateBase` pointer is only used with the stored `Run()` pointer.
263 pointer.
264 412
265 To `BindState<>` objects are created inside the `Bind()` functions. 413 To `BindState<>` objects are created inside the `Bind()` functions.
266 These functions, along with a set of internal templates, are responsible for 414 These functions, along with a set of internal templates, are responsible for
267 415
268 - Unwrapping the function signature into return type, and parameters 416 - Unwrapping the function signature into return type, and parameters
269 - Determining the number of parameters that are bound 417 - Determining the number of parameters that are bound
270 - Creating the BindState storing the bound parameters 418 - Creating the BindState storing the bound parameters
271 - Performing compile-time asserts to avoid error-prone behavior 419 - Performing compile-time asserts to avoid error-prone behavior
272 - Returning an `Callback<>` with an arity matching the number of unbound 420 - Returning an `Callback<>` with an arity matching the number of unbound
273 parameters and that knows the correct refcounting semantics for the 421 parameters and that knows the correct refcounting semantics for the
274 target object if we are binding a method. 422 target object if we are binding a method.
275 423
276 The `Bind` functions do the above using type-inference, and template 424 The `Bind` functions do the above using type-inference and variadic templates.
277 specializations.
278 425
279 By default `Bind()` will store copies of all bound parameters, and attempt to 426 By default `Bind()` will store copies of all bound parameters, and attempt to
280 refcount a target object if the function being bound is a class method. These 427 refcount a target object if the function being bound is a class method. These
281 copies are created even if the function takes parameters as const 428 copies are created even if the function takes parameters as const
282 references. (Binding to non-const references is forbidden, see bind.h.) 429 references. (Binding to non-const references is forbidden, see bind.h.)
283 430
284 To change this behavior, we introduce a set of argument wrappers (e.g., 431 To change this behavior, we introduce a set of argument wrappers (e.g.,
285 `Unretained()`, and `ConstRef()`). These are simple container templates that 432 `Unretained()`, and `ConstRef()`). These are simple container templates that
286 are passed by value, and wrap a pointer to argument. See the file-level comment 433 are passed by value, and wrap a pointer to argument. See the file-level comment
287 in base/bind_helpers.h for more info. 434 in base/bind_helpers.h for more info.
288 435
289 These types are passed to the `Unwrap()` functions, and the `MaybeRefcount()` 436 These types are passed to the `Unwrap()` functions to modify the behavior of
290 functions respectively to modify the behavior of `Bind()`. The `Unwrap()` and 437 `Bind()`. The `Unwrap()` functions change behavior by doing partial
291 `MaybeRefcount()` functions change behavior by doing partial specialization 438 specialization based on whether or not a parameter is a wrapper type.
292 based on whether or not a parameter is a wrapper type.
293 439
294 `ConstRef()` is similar to `tr1::cref`. `Unretained()` is specific to Chromium. 440 `ConstRef()` is similar to `tr1::cref`. `Unretained()` is specific to Chromium.
295 441
296 ### Why Not Tr1 Function/Bind?
297
298 Direct use of `tr1::function` and `tr1::bind` was considered, but ultimately
299 rejected because of the number of copy constructors invocations involved in the
300 binding of arguments during construction, and the forwarding of arguments during
301 invocation. These copies will no longer be an issue in C++0x because C++0x will
302 support rvalue reference allowing for the compiler to avoid these copies.
303 However, waiting for C++0x is not an option.
304
305 Measured with valgrind on gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5), the
306 `tr1::bind` call itself will invoke a non-trivial copy constructor three times
307 for each bound parameter. Also, each when passing a `tr1::function`, each bound
308 argument will be copied again.
309
310 In addition to the copies taken at binding and invocation, copying a
311 `tr1::function` causes a copy to be made of all the bound parameters and state.
312
313 Furthermore, in Chromium, it is desirable for the `Callback` to take a reference
314 on a target object when representing a class method call. This is not supported
315 by tr1.
316
317 Lastly, `tr1::function` and `tr1::bind` has a more general and flexible
318 API. This includes things like argument reordering by use of
319 `tr1::bind::placeholder`, support for non-const reference parameters, and some
320 limited amount of subtyping of the `tr1::function` object (e.g.,
321 `tr1::function<int(int)>` is convertible to `tr1::function<void(int)>`).
322
323 These are not features that are required in Chromium. Some of them, such as
324 allowing for reference parameters, and subtyping of functions, may actually
325 become a source of errors. Removing support for these features actually allows
326 for a simpler implementation, and a terser Currying API.
327
328 ### Why Not Google Callbacks?
329
330 The Google callback system also does not support refcounting. Furthermore, its
331 implementation has a number of strange edge cases with respect to type
332 conversion of its arguments. In particular, the argument's constness must at
333 times match exactly the function signature, or the type-inference might
334 break. Given the above, writing a custom solution was easier.
335
336 ### Missing Functionality 442 ### Missing Functionality
337 - Invoking the return of `Bind`. `Bind(&foo).Run()` does not work;
338 - Binding arrays to functions that take a non-const pointer. 443 - Binding arrays to functions that take a non-const pointer.
339 Example: 444 Example:
340 ```cpp 445 ```cpp
341 void Foo(const char* ptr); 446 void Foo(const char* ptr);
342 void Bar(char* ptr); 447 void Bar(char* ptr);
343 Bind(&Foo, "test"); 448 Bind(&Foo, "test");
344 Bind(&Bar, "test"); // This fails because ptr is not const. 449 Bind(&Bar, "test"); // This fails because ptr is not const.
345 ``` 450 ```
346 451
347 If you are thinking of forward declaring `Callback` in your own header file, 452 If you are thinking of forward declaring `Callback` in your own header file,
348 please include "base/callback_forward.h" instead. 453 please include "base/callback_forward.h" instead.
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698