OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // 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 | 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 // This defines a set of argument wrappers and related factory methods that | 5 // This defines a set of argument wrappers and related factory methods that |
6 // can be used specify the refcounting and reference semantics of arguments | 6 // can be used specify the refcounting and reference semantics of arguments |
7 // that are bound by the Bind() function in base/bind.h. | 7 // that are bound by the Bind() function in base/bind.h. |
8 // | 8 // |
9 // The public functions are base::Unretained(), base::Owned(), bass::Passed(), | 9 // The public functions are base::Unretained(), base::Owned(), |
10 // base::ConstRef(), and base::IgnoreResult(). | 10 // base::ConstRef(), and base::IgnoreReturn(). |
11 // | 11 // |
12 // Unretained() allows Bind() to bind a non-refcounted class, and to disable | 12 // Unretained() allows Bind() to bind a non-refcounted class, and to disable |
13 // refcounting on arguments that are refcounted objects. | 13 // refcounting on arguments that are refcounted objects. |
14 // | |
15 // Owned() transfers ownership of an object to the Callback resulting from | 14 // Owned() transfers ownership of an object to the Callback resulting from |
16 // bind; the object will be deleted when the Callback is deleted. | 15 // bind; the object will be deleted when the Callback is deleted. |
17 // | |
18 // Passed() is for transferring movable-but-not-copyable types (eg. scoped_ptr) | |
19 // through a Callback. Logically, this signifies a destructive transfer of | |
20 // the state of the argument into the target function. Invoking | |
21 // Callback::Run() twice on a Callback that was created with a Passed() | |
22 // argument will CHECK() because the first invocation would have already | |
23 // transferred ownership to the target function. | |
24 // | |
25 // ConstRef() allows binding a constant reference to an argument rather | 16 // ConstRef() allows binding a constant reference to an argument rather |
26 // than a copy. | 17 // than a copy. |
| 18 // IgnoreReturn() is used to adapt a 0-argument Callback with a return type to |
| 19 // a Closure. This is useful if you need to PostTask with a function that has |
| 20 // a return value that you don't care about. |
27 // | 21 // |
28 // IgnoreResult() is used to adapt a function or Callback with a return type to | |
29 // one with a void return. This is most useful if you have a function with, | |
30 // say, a pesky ignorable bool return that you want to use with PostTask or | |
31 // something else that expect a Callback with a void return. | |
32 // | 22 // |
33 // EXAMPLE OF Unretained(): | 23 // EXAMPLE OF Unretained(): |
34 // | 24 // |
35 // class Foo { | 25 // class Foo { |
36 // public: | 26 // public: |
37 // void func() { cout << "Foo:f" << endl; } | 27 // void func() { cout << "Foo:f" << endl; } |
38 // }; | 28 // }; |
39 // | 29 // |
40 // // In some function somewhere. | 30 // // In some function somewhere. |
41 // Foo foo; | 31 // Foo foo; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 // has_ref.Run(); // Prints "1" | 68 // has_ref.Run(); // Prints "1" |
79 // | 69 // |
80 // n = 2; | 70 // n = 2; |
81 // no_ref.Run(); // Prints "1" | 71 // no_ref.Run(); // Prints "1" |
82 // has_ref.Run(); // Prints "2" | 72 // has_ref.Run(); // Prints "2" |
83 // | 73 // |
84 // Note that because ConstRef() takes a reference on |n|, |n| must outlive all | 74 // Note that because ConstRef() takes a reference on |n|, |n| must outlive all |
85 // its bound callbacks. | 75 // its bound callbacks. |
86 // | 76 // |
87 // | 77 // |
88 // EXAMPLE OF IgnoreResult(): | 78 // EXAMPLE OF IgnoreReturn(): |
89 // | 79 // |
90 // int DoSomething(int arg) { cout << arg << endl; } | 80 // int DoSomething(int arg) { cout << arg << endl; } |
91 // | 81 // Callback<int(void)> cb = Bind(&DoSomething, 1); |
92 // // Assign to a Callback with a void return type. | 82 // Closure c = IgnoreReturn(cb); // Prints "1" |
93 // Callback<void(int)> cb = Bind(IgnoreResult(&DoSomething)); | 83 // or |
94 // cb->Run(1); // Prints "1". | 84 // ml->PostTask(FROM_HERE, IgnoreReturn(cb)); // Prints "1" on |ml| |
95 // | |
96 // // Prints "1" on |ml|. | |
97 // ml->PostTask(FROM_HERE, Bind(IgnoreResult(&DoSomething), 1); | |
98 // | |
99 // | |
100 // EXAMPLE OF Passed(): | |
101 // | |
102 // void TakesOwnership(scoped_ptr<Foo> arg) { } | |
103 // scoped_ptr<Foo> CreateFoo() { return scoped_ptr<Foo>(new Foo()); } | |
104 // | |
105 // scoped_ptr<Foo> f(new Foo()); | |
106 // | |
107 // // |cb| is given ownership of Foo(). |f| is now NULL. | |
108 // // You can use f.Pass() in place of &f, but it's more verbose. | |
109 // Closure cb = Bind(&TakesOwnership, Passed(&f)); | |
110 // | |
111 // // Run was never called so |cb| still owns Foo() and deletes | |
112 // // it on Reset(). | |
113 // cb.Reset(); | |
114 // | |
115 // // |cb| is given a new Foo created by CreateFoo(). | |
116 // cb = Bind(&TakesOwnership, Passed(CreateFoo())); | |
117 // | |
118 // // |arg| in TakesOwnership() is given ownership of Foo(). |cb| | |
119 // // no longer owns Foo() and, if reset, would not delete Foo(). | |
120 // cb.Run(); // Foo() is now transferred to |arg| and deleted. | |
121 // cb.Run(); // This CHECK()s since Foo() already been used once. | |
122 // | |
123 // Passed() is particularly useful with PostTask() when you are transferring | |
124 // ownership of an argument into a task, but don't necessarily know if the | |
125 // task will always be executed. This can happen if the task is cancellable | |
126 // or if it is posted to a MessageLoopProxy. | |
127 | 85 |
128 #ifndef BASE_BIND_HELPERS_H_ | 86 #ifndef BASE_BIND_HELPERS_H_ |
129 #define BASE_BIND_HELPERS_H_ | 87 #define BASE_BIND_HELPERS_H_ |
130 #pragma once | 88 #pragma once |
131 | 89 |
132 #include "base/basictypes.h" | 90 #include "base/basictypes.h" |
133 #include "base/bind.h" | 91 #include "base/bind.h" |
134 #include "base/callback.h" | 92 #include "base/callback.h" |
135 #include "base/memory/weak_ptr.h" | 93 #include "base/memory/weak_ptr.h" |
136 #include "base/template_util.h" | 94 #include "base/template_util.h" |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 T* get() const { return ptr_; } | 280 T* get() const { return ptr_; } |
323 OwnedWrapper(const OwnedWrapper& other) { | 281 OwnedWrapper(const OwnedWrapper& other) { |
324 ptr_ = other.ptr_; | 282 ptr_ = other.ptr_; |
325 other.ptr_ = NULL; | 283 other.ptr_ = NULL; |
326 } | 284 } |
327 | 285 |
328 private: | 286 private: |
329 mutable T* ptr_; | 287 mutable T* ptr_; |
330 }; | 288 }; |
331 | 289 |
332 // PassedWrapper is a copyable adapter for a scoper that ignores const. | |
333 // | |
334 // It is needed to get around the fact that Bind() takes a const reference to | |
335 // all its arguments. Because Bind() takes a const reference to avoid | |
336 // unnecessary copies, it is incompatible with movable-but-not-copyable | |
337 // types; doing a destructive "move" of the type into Bind() would violate | |
338 // the const correctness. | |
339 // | |
340 // This conundrum cannot be solved without either C++11 rvalue references or | |
341 // a O(2^n) blowup of Bind() templates to handle each combination of regular | |
342 // types and movable-but-not-copyable types. Thus we introduce a wrapper type | |
343 // that is copyable to transmit the correct type information down into | |
344 // BindState<>. Ignoring const in this type makes sense because it is only | |
345 // created when we are explicitly trying to do a destructive move. | |
346 // | |
347 // Two notes: | |
348 // 1) PassedWrapper supports any type that has a "Pass()" function. | |
349 // This is intentional. The whitelisting of which specific types we | |
350 // support is maintained by CallbackParamTraits<>. | |
351 // 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL" | |
352 // scoper to a Callback and allow the Callback to execute once. | |
353 template <typename T> | |
354 class PassedWrapper { | |
355 public: | |
356 explicit PassedWrapper(T scoper) : is_valid_(true), scoper_(scoper.Pass()) {} | |
357 PassedWrapper(const PassedWrapper& other) | |
358 : is_valid_(other.is_valid_), scoper_(other.scoper_.Pass()) { | |
359 } | |
360 T Pass() const { | |
361 CHECK(is_valid_); | |
362 is_valid_ = false; | |
363 return scoper_.Pass(); | |
364 } | |
365 | |
366 private: | |
367 mutable bool is_valid_; | |
368 mutable T scoper_; | |
369 }; | |
370 | |
371 // Unwrap the stored parameters for the wrappers above. | 290 // Unwrap the stored parameters for the wrappers above. |
372 template <typename T> | 291 template <typename T> |
373 struct UnwrapTraits { | 292 struct UnwrapTraits { |
374 typedef const T& ForwardType; | 293 typedef const T& ForwardType; |
375 static ForwardType Unwrap(const T& o) { return o; } | 294 static ForwardType Unwrap(const T& o) { return o; } |
376 }; | 295 }; |
377 | 296 |
378 template <typename T> | 297 template <typename T> |
379 struct UnwrapTraits<UnretainedWrapper<T> > { | 298 struct UnwrapTraits<UnretainedWrapper<T> > { |
380 typedef T* ForwardType; | 299 typedef T* ForwardType; |
(...skipping 23 matching lines...) Expand all Loading... |
404 }; | 323 }; |
405 | 324 |
406 template <typename T> | 325 template <typename T> |
407 struct UnwrapTraits<OwnedWrapper<T> > { | 326 struct UnwrapTraits<OwnedWrapper<T> > { |
408 typedef T* ForwardType; | 327 typedef T* ForwardType; |
409 static ForwardType Unwrap(const OwnedWrapper<T>& o) { | 328 static ForwardType Unwrap(const OwnedWrapper<T>& o) { |
410 return o.get(); | 329 return o.get(); |
411 } | 330 } |
412 }; | 331 }; |
413 | 332 |
414 template <typename T> | |
415 struct UnwrapTraits<PassedWrapper<T> > { | |
416 typedef T ForwardType; | |
417 static T Unwrap(PassedWrapper<T>& o) { | |
418 return o.Pass(); | |
419 } | |
420 }; | |
421 | |
422 // Utility for handling different refcounting semantics in the Bind() | 333 // Utility for handling different refcounting semantics in the Bind() |
423 // function. | 334 // function. |
424 template <bool is_method, typename T> | 335 template <bool, typename T> |
425 struct MaybeRefcount; | 336 struct MaybeRefcount; |
426 | 337 |
427 template <typename T> | 338 template <typename T> |
428 struct MaybeRefcount<false, T> { | 339 struct MaybeRefcount<false, T> { |
429 static void AddRef(const T&) {} | 340 static void AddRef(const T&) {} |
430 static void Release(const T&) {} | 341 static void Release(const T&) {} |
431 }; | 342 }; |
432 | 343 |
433 template <typename T, size_t n> | 344 template <typename T, size_t n> |
434 struct MaybeRefcount<false, T[n]> { | 345 struct MaybeRefcount<false, T[n]> { |
435 static void AddRef(const T*) {} | 346 static void AddRef(const T*) {} |
436 static void Release(const T*) {} | 347 static void Release(const T*) {} |
437 }; | 348 }; |
438 | 349 |
439 template <typename T> | 350 template <typename T> |
440 struct MaybeRefcount<true, T> { | |
441 static void AddRef(const T&) {} | |
442 static void Release(const T&) {} | |
443 }; | |
444 | |
445 template <typename T> | |
446 struct MaybeRefcount<true, T*> { | 351 struct MaybeRefcount<true, T*> { |
447 static void AddRef(T* o) { o->AddRef(); } | 352 static void AddRef(T* o) { o->AddRef(); } |
448 static void Release(T* o) { o->Release(); } | 353 static void Release(T* o) { o->Release(); } |
449 }; | 354 }; |
450 | 355 |
| 356 template <typename T> |
| 357 struct MaybeRefcount<true, UnretainedWrapper<T> > { |
| 358 static void AddRef(const UnretainedWrapper<T>&) {} |
| 359 static void Release(const UnretainedWrapper<T>&) {} |
| 360 }; |
| 361 |
| 362 template <typename T> |
| 363 struct MaybeRefcount<true, OwnedWrapper<T> > { |
| 364 static void AddRef(const OwnedWrapper<T>&) {} |
| 365 static void Release(const OwnedWrapper<T>&) {} |
| 366 }; |
| 367 |
451 // No need to additionally AddRef() and Release() since we are storing a | 368 // No need to additionally AddRef() and Release() since we are storing a |
452 // scoped_refptr<> inside the storage object already. | 369 // scoped_refptr<> inside the storage object already. |
453 template <typename T> | 370 template <typename T> |
454 struct MaybeRefcount<true, scoped_refptr<T> > { | 371 struct MaybeRefcount<true, scoped_refptr<T> > { |
455 static void AddRef(const scoped_refptr<T>& o) {} | 372 static void AddRef(const scoped_refptr<T>& o) {} |
456 static void Release(const scoped_refptr<T>& o) {} | 373 static void Release(const scoped_refptr<T>& o) {} |
457 }; | 374 }; |
458 | 375 |
459 template <typename T> | 376 template <typename T> |
460 struct MaybeRefcount<true, const T*> { | 377 struct MaybeRefcount<true, const T*> { |
461 static void AddRef(const T* o) { o->AddRef(); } | 378 static void AddRef(const T* o) { o->AddRef(); } |
462 static void Release(const T* o) { o->Release(); } | 379 static void Release(const T* o) { o->Release(); } |
463 }; | 380 }; |
464 | 381 |
| 382 template <typename T> |
| 383 struct MaybeRefcount<true, WeakPtr<T> > { |
| 384 static void AddRef(const WeakPtr<T>&) {} |
| 385 static void Release(const WeakPtr<T>&) {} |
| 386 }; |
| 387 |
465 template <typename R> | 388 template <typename R> |
466 void VoidReturnAdapter(Callback<R(void)> callback) { | 389 void VoidReturnAdapter(Callback<R(void)> callback) { |
467 callback.Run(); | 390 callback.Run(); |
468 } | 391 } |
469 | 392 |
470 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a | 393 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a |
471 // method. It is used internally by Bind() to select the correct | 394 // method. It is unsed internally by Bind() to select the correct |
472 // InvokeHelper that will no-op itself in the event the WeakPtr<> for | 395 // InvokeHelper that will no-op itself in the event the WeakPtr<> for |
473 // the target object is invalidated. | 396 // the target object is invalidated. |
474 // | 397 // |
475 // P1 should be the type of the object that will be received of the method. | 398 // P1 should be the type of the object that will be received of the method. |
476 template <bool IsMethod, typename P1> | 399 template <bool IsMethod, typename P1> |
477 struct IsWeakMethod : public false_type {}; | 400 struct IsWeakMethod : public false_type {}; |
478 | 401 |
479 template <typename T> | 402 template <typename T> |
480 struct IsWeakMethod<true, WeakPtr<T> > : public true_type {}; | 403 struct IsWeakMethod<true, WeakPtr<T> > : public true_type {}; |
481 | 404 |
(...skipping 10 matching lines...) Expand all Loading... |
492 template <typename T> | 415 template <typename T> |
493 static inline internal::ConstRefWrapper<T> ConstRef(const T& o) { | 416 static inline internal::ConstRefWrapper<T> ConstRef(const T& o) { |
494 return internal::ConstRefWrapper<T>(o); | 417 return internal::ConstRefWrapper<T>(o); |
495 } | 418 } |
496 | 419 |
497 template <typename T> | 420 template <typename T> |
498 static inline internal::OwnedWrapper<T> Owned(T* o) { | 421 static inline internal::OwnedWrapper<T> Owned(T* o) { |
499 return internal::OwnedWrapper<T>(o); | 422 return internal::OwnedWrapper<T>(o); |
500 } | 423 } |
501 | 424 |
502 // We offer 2 syntaxes for calling Passed(). The first takes a temporary and | |
503 // is best suited for use with the return value of a function. The second | |
504 // takes a pointer to the scoper and is just syntactic sugar to avoid having | |
505 // to write Passed(scoper.Pass()). | |
506 template <typename T> | |
507 static inline internal::PassedWrapper<T> Passed(T scoper) { | |
508 return internal::PassedWrapper<T>(scoper.Pass()); | |
509 } | |
510 template <typename T> | |
511 static inline internal::PassedWrapper<T> Passed(T* scoper) { | |
512 return internal::PassedWrapper<T>(scoper->Pass()); | |
513 } | |
514 | |
515 // -- DEPRECATED -- Use IgnoreResult instead. | |
516 template <typename R> | 425 template <typename R> |
517 static inline Closure IgnoreReturn(Callback<R(void)> callback) { | 426 static inline Closure IgnoreReturn(Callback<R(void)> callback) { |
518 return Bind(&internal::VoidReturnAdapter<R>, callback); | 427 return Bind(&internal::VoidReturnAdapter<R>, callback); |
519 } | 428 } |
520 | 429 |
521 template <typename T> | 430 template <typename T> |
522 static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) { | 431 static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) { |
523 return internal::IgnoreResultHelper<T>(data); | 432 return internal::IgnoreResultHelper<T>(data); |
524 } | 433 } |
525 | 434 |
526 template <typename T> | 435 template <typename T> |
527 static inline internal::IgnoreResultHelper<Callback<T> > | 436 static inline internal::IgnoreResultHelper<Callback<T> > |
528 IgnoreResult(const Callback<T>& data) { | 437 IgnoreResult(const Callback<T>& data) { |
529 return internal::IgnoreResultHelper<Callback<T> >(data); | 438 return internal::IgnoreResultHelper<Callback<T> >(data); |
530 } | 439 } |
531 | 440 |
| 441 |
532 } // namespace base | 442 } // namespace base |
533 | 443 |
534 #endif // BASE_BIND_HELPERS_H_ | 444 #endif // BASE_BIND_HELPERS_H_ |
OLD | NEW |