| 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(), | 9 // The public functions are base::Unretained(), base::Owned(), bass::Passed(), | 
| 10 // base::ConstRef(), and base::IgnoreReturn(). | 10 // base::ConstRef(), and base::IgnoreResult(). | 
| 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 // | 
| 14 // Owned() transfers ownership of an object to the Callback resulting from | 15 // Owned() transfers ownership of an object to the Callback resulting from | 
| 15 // bind; the object will be deleted when the Callback is deleted. | 16 // 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 // | 
| 16 // ConstRef() allows binding a constant reference to an argument rather | 25 // ConstRef() allows binding a constant reference to an argument rather | 
| 17 // than a copy. | 26 // 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. |  | 
| 21 // | 27 // | 
|  | 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. | 
| 22 // | 32 // | 
| 23 // EXAMPLE OF Unretained(): | 33 // EXAMPLE OF Unretained(): | 
| 24 // | 34 // | 
| 25 //   class Foo { | 35 //   class Foo { | 
| 26 //    public: | 36 //    public: | 
| 27 //     void func() { cout << "Foo:f" << endl; } | 37 //     void func() { cout << "Foo:f" << endl; } | 
| 28 //   }; | 38 //   }; | 
| 29 // | 39 // | 
| 30 //   // In some function somewhere. | 40 //   // In some function somewhere. | 
| 31 //   Foo foo; | 41 //   Foo foo; | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 68 //   has_ref.Run();  // Prints "1" | 78 //   has_ref.Run();  // Prints "1" | 
| 69 // | 79 // | 
| 70 //   n = 2; | 80 //   n = 2; | 
| 71 //   no_ref.Run();  // Prints "1" | 81 //   no_ref.Run();  // Prints "1" | 
| 72 //   has_ref.Run();  // Prints "2" | 82 //   has_ref.Run();  // Prints "2" | 
| 73 // | 83 // | 
| 74 // Note that because ConstRef() takes a reference on |n|, |n| must outlive all | 84 // Note that because ConstRef() takes a reference on |n|, |n| must outlive all | 
| 75 // its bound callbacks. | 85 // its bound callbacks. | 
| 76 // | 86 // | 
| 77 // | 87 // | 
| 78 // EXAMPLE OF IgnoreReturn(): | 88 // EXAMPLE OF IgnoreResult(): | 
| 79 // | 89 // | 
| 80 //   int DoSomething(int arg) { cout << arg << endl; } | 90 //   int DoSomething(int arg) { cout << arg << endl; } | 
| 81 //   Callback<int(void)> cb = Bind(&DoSomething, 1); | 91 // | 
| 82 //   Closure c = IgnoreReturn(cb);  // Prints "1" | 92 //   // Assign to a Callback with a void return type. | 
| 83 //       or | 93 //   Callback<void(int)> cb = Bind(IgnoreResult(&DoSomething)); | 
| 84 //   ml->PostTask(FROM_HERE, IgnoreReturn(cb));  // Prints "1" on |ml| | 94 //   cb->Run(1);  // Prints "1". | 
|  | 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. | 
| 85 | 127 | 
| 86 #ifndef BASE_BIND_HELPERS_H_ | 128 #ifndef BASE_BIND_HELPERS_H_ | 
| 87 #define BASE_BIND_HELPERS_H_ | 129 #define BASE_BIND_HELPERS_H_ | 
| 88 #pragma once | 130 #pragma once | 
| 89 | 131 | 
| 90 #include "base/basictypes.h" | 132 #include "base/basictypes.h" | 
| 91 #include "base/bind.h" | 133 #include "base/bind.h" | 
| 92 #include "base/callback.h" | 134 #include "base/callback.h" | 
| 93 #include "base/memory/weak_ptr.h" | 135 #include "base/memory/weak_ptr.h" | 
| 94 #include "base/template_util.h" | 136 #include "base/template_util.h" | 
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 280   T* get() const { return ptr_; } | 322   T* get() const { return ptr_; } | 
| 281   OwnedWrapper(const OwnedWrapper& other) { | 323   OwnedWrapper(const OwnedWrapper& other) { | 
| 282     ptr_ = other.ptr_; | 324     ptr_ = other.ptr_; | 
| 283     other.ptr_ = NULL; | 325     other.ptr_ = NULL; | 
| 284   } | 326   } | 
| 285 | 327 | 
| 286  private: | 328  private: | 
| 287   mutable T* ptr_; | 329   mutable T* ptr_; | 
| 288 }; | 330 }; | 
| 289 | 331 | 
|  | 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 | 
| 290 // Unwrap the stored parameters for the wrappers above. | 371 // Unwrap the stored parameters for the wrappers above. | 
| 291 template <typename T> | 372 template <typename T> | 
| 292 struct UnwrapTraits { | 373 struct UnwrapTraits { | 
| 293   typedef const T& ForwardType; | 374   typedef const T& ForwardType; | 
| 294   static ForwardType Unwrap(const T& o) { return o; } | 375   static ForwardType Unwrap(const T& o) { return o; } | 
| 295 }; | 376 }; | 
| 296 | 377 | 
| 297 template <typename T> | 378 template <typename T> | 
| 298 struct UnwrapTraits<UnretainedWrapper<T> > { | 379 struct UnwrapTraits<UnretainedWrapper<T> > { | 
| 299   typedef T* ForwardType; | 380   typedef T* ForwardType; | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 323 }; | 404 }; | 
| 324 | 405 | 
| 325 template <typename T> | 406 template <typename T> | 
| 326 struct UnwrapTraits<OwnedWrapper<T> > { | 407 struct UnwrapTraits<OwnedWrapper<T> > { | 
| 327   typedef T* ForwardType; | 408   typedef T* ForwardType; | 
| 328   static ForwardType Unwrap(const OwnedWrapper<T>& o) { | 409   static ForwardType Unwrap(const OwnedWrapper<T>& o) { | 
| 329     return o.get(); | 410     return o.get(); | 
| 330   } | 411   } | 
| 331 }; | 412 }; | 
| 332 | 413 | 
|  | 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 | 
| 333 // Utility for handling different refcounting semantics in the Bind() | 422 // Utility for handling different refcounting semantics in the Bind() | 
| 334 // function. | 423 // function. | 
| 335 template <bool, typename T> | 424 template <bool is_method, typename T> | 
| 336 struct MaybeRefcount; | 425 struct MaybeRefcount; | 
| 337 | 426 | 
| 338 template <typename T> | 427 template <typename T> | 
| 339 struct MaybeRefcount<false, T> { | 428 struct MaybeRefcount<false, T> { | 
| 340   static void AddRef(const T&) {} | 429   static void AddRef(const T&) {} | 
| 341   static void Release(const T&) {} | 430   static void Release(const T&) {} | 
| 342 }; | 431 }; | 
| 343 | 432 | 
| 344 template <typename T, size_t n> | 433 template <typename T, size_t n> | 
| 345 struct MaybeRefcount<false, T[n]> { | 434 struct MaybeRefcount<false, T[n]> { | 
| 346   static void AddRef(const T*) {} | 435   static void AddRef(const T*) {} | 
| 347   static void Release(const T*) {} | 436   static void Release(const T*) {} | 
| 348 }; | 437 }; | 
| 349 | 438 | 
| 350 template <typename T> | 439 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> | 
| 351 struct MaybeRefcount<true, T*> { | 446 struct MaybeRefcount<true, T*> { | 
| 352   static void AddRef(T* o) { o->AddRef(); } | 447   static void AddRef(T* o) { o->AddRef(); } | 
| 353   static void Release(T* o) { o->Release(); } | 448   static void Release(T* o) { o->Release(); } | 
| 354 }; | 449 }; | 
| 355 | 450 | 
| 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 |  | 
| 368 // No need to additionally AddRef() and Release() since we are storing a | 451 // No need to additionally AddRef() and Release() since we are storing a | 
| 369 // scoped_refptr<> inside the storage object already. | 452 // scoped_refptr<> inside the storage object already. | 
| 370 template <typename T> | 453 template <typename T> | 
| 371 struct MaybeRefcount<true, scoped_refptr<T> > { | 454 struct MaybeRefcount<true, scoped_refptr<T> > { | 
| 372   static void AddRef(const scoped_refptr<T>& o) {} | 455   static void AddRef(const scoped_refptr<T>& o) {} | 
| 373   static void Release(const scoped_refptr<T>& o) {} | 456   static void Release(const scoped_refptr<T>& o) {} | 
| 374 }; | 457 }; | 
| 375 | 458 | 
| 376 template <typename T> | 459 template <typename T> | 
| 377 struct MaybeRefcount<true, const T*> { | 460 struct MaybeRefcount<true, const T*> { | 
| 378   static void AddRef(const T* o) { o->AddRef(); } | 461   static void AddRef(const T* o) { o->AddRef(); } | 
| 379   static void Release(const T* o) { o->Release(); } | 462   static void Release(const T* o) { o->Release(); } | 
| 380 }; | 463 }; | 
| 381 | 464 | 
| 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 |  | 
| 388 template <typename R> | 465 template <typename R> | 
| 389 void VoidReturnAdapter(Callback<R(void)> callback) { | 466 void VoidReturnAdapter(Callback<R(void)> callback) { | 
| 390   callback.Run(); | 467   callback.Run(); | 
| 391 } | 468 } | 
| 392 | 469 | 
| 393 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a | 470 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a | 
| 394 // method.  It is unsed internally by Bind() to select the correct | 471 // method.  It is used internally by Bind() to select the correct | 
| 395 // InvokeHelper that will no-op itself in the event the WeakPtr<> for | 472 // InvokeHelper that will no-op itself in the event the WeakPtr<> for | 
| 396 // the target object is invalidated. | 473 // the target object is invalidated. | 
| 397 // | 474 // | 
| 398 // P1 should be the type of the object that will be received of the method. | 475 // P1 should be the type of the object that will be received of the method. | 
| 399 template <bool IsMethod, typename P1> | 476 template <bool IsMethod, typename P1> | 
| 400 struct IsWeakMethod : public false_type {}; | 477 struct IsWeakMethod : public false_type {}; | 
| 401 | 478 | 
| 402 template <typename T> | 479 template <typename T> | 
| 403 struct IsWeakMethod<true, WeakPtr<T> > : public true_type {}; | 480 struct IsWeakMethod<true, WeakPtr<T> > : public true_type {}; | 
| 404 | 481 | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 415 template <typename T> | 492 template <typename T> | 
| 416 static inline internal::ConstRefWrapper<T> ConstRef(const T& o) { | 493 static inline internal::ConstRefWrapper<T> ConstRef(const T& o) { | 
| 417   return internal::ConstRefWrapper<T>(o); | 494   return internal::ConstRefWrapper<T>(o); | 
| 418 } | 495 } | 
| 419 | 496 | 
| 420 template <typename T> | 497 template <typename T> | 
| 421 static inline internal::OwnedWrapper<T> Owned(T* o) { | 498 static inline internal::OwnedWrapper<T> Owned(T* o) { | 
| 422   return internal::OwnedWrapper<T>(o); | 499   return internal::OwnedWrapper<T>(o); | 
| 423 } | 500 } | 
| 424 | 501 | 
|  | 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. | 
| 425 template <typename R> | 516 template <typename R> | 
| 426 static inline Closure IgnoreReturn(Callback<R(void)> callback) { | 517 static inline Closure IgnoreReturn(Callback<R(void)> callback) { | 
| 427   return Bind(&internal::VoidReturnAdapter<R>, callback); | 518   return Bind(&internal::VoidReturnAdapter<R>, callback); | 
| 428 } | 519 } | 
| 429 | 520 | 
| 430 template <typename T> | 521 template <typename T> | 
| 431 static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) { | 522 static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) { | 
| 432   return internal::IgnoreResultHelper<T>(data); | 523   return internal::IgnoreResultHelper<T>(data); | 
| 433 } | 524 } | 
| 434 | 525 | 
| 435 template <typename T> | 526 template <typename T> | 
| 436 static inline internal::IgnoreResultHelper<Callback<T> > | 527 static inline internal::IgnoreResultHelper<Callback<T> > | 
| 437 IgnoreResult(const Callback<T>& data) { | 528 IgnoreResult(const Callback<T>& data) { | 
| 438   return internal::IgnoreResultHelper<Callback<T> >(data); | 529   return internal::IgnoreResultHelper<Callback<T> >(data); | 
| 439 } | 530 } | 
| 440 | 531 | 
| 441 |  | 
| 442 }  // namespace base | 532 }  // namespace base | 
| 443 | 533 | 
| 444 #endif  // BASE_BIND_HELPERS_H_ | 534 #endif  // BASE_BIND_HELPERS_H_ | 
| OLD | NEW | 
|---|