Chromium Code Reviews| 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() and base::ConstRef(). | 9 // The public functions are base::Unretained(), base::ConstRef(), and |
| 10 // base::IgnoreReturn(). | |
| 11 // | |
| 10 // Unretained() allows Bind() to bind a non-refcounted class. | 12 // Unretained() allows Bind() to bind a non-refcounted class. |
| 11 // ConstRef() allows binding a constant reference to an argument rather | 13 // ConstRef() allows binding a constant reference to an argument rather |
| 12 // than a copy. | 14 // than a copy. |
| 15 // IgnoreReturn() is used to adapt a 0-argument Callback with a return type to | |
| 16 // a Closure. This is useful if you need to PostTask with a function that has | |
| 17 // a return value that you don't care about. | |
| 13 // | 18 // |
| 14 // | 19 // |
| 15 // EXAMPLE OF Unretained(): | 20 // EXAMPLE OF Unretained(): |
| 16 // | 21 // |
| 17 // class Foo { | 22 // class Foo { |
| 18 // public: | 23 // public: |
| 19 // void func() { cout << "Foo:f" << endl; | 24 // void func() { cout << "Foo:f" << endl; } |
| 20 // }; | 25 // }; |
| 21 // | 26 // |
| 22 // // In some function somewhere. | 27 // // In some function somewhere. |
| 23 // Foo foo; | 28 // Foo foo; |
| 24 // Callback<void(void)> foo_callback = | 29 // Callback<void(void)> foo_callback = |
| 25 // Bind(&Foo::func, Unretained(&foo)); | 30 // Bind(&Foo::func, Unretained(&foo)); |
| 26 // foo_callback.Run(); // Prints "Foo:f". | 31 // foo_callback.Run(); // Prints "Foo:f". |
| 27 // | 32 // |
| 28 // Without the Unretained() wrapper on |&foo|, the above call would fail | 33 // Without the Unretained() wrapper on |&foo|, the above call would fail |
| 29 // to compile because Foo does not support the AddRef() and Release() methods. | 34 // to compile because Foo does not support the AddRef() and Release() methods. |
| 30 // | 35 // |
| 31 // | 36 // |
| 32 // EXAMPLE OF ConstRef(); | 37 // EXAMPLE OF ConstRef(): |
| 33 // void foo(int arg) { cout << arg << endl } | 38 // void foo(int arg) { cout << arg << endl } |
| 34 // | 39 // |
| 35 // int n = 1; | 40 // int n = 1; |
| 36 // Callback<void(void)> no_ref = Bind(&foo, n); | 41 // Callback<void(void)> no_ref = Bind(&foo, n); |
| 37 // Callback<void(void)> has_ref = Bind(&foo, ConstRef(n)); | 42 // Callback<void(void)> has_ref = Bind(&foo, ConstRef(n)); |
| 38 // | 43 // |
| 39 // no_ref.Run(); // Prints "1" | 44 // no_ref.Run(); // Prints "1" |
| 40 // has_ref.Run(); // Prints "1" | 45 // has_ref.Run(); // Prints "1" |
| 41 // | 46 // |
| 42 // n = 2; | 47 // n = 2; |
| 43 // no_ref.Run(); // Prints "1" | 48 // no_ref.Run(); // Prints "1" |
| 44 // has_ref.Run(); // Prints "2" | 49 // has_ref.Run(); // Prints "2" |
| 45 // | 50 // |
| 46 // Note that because ConstRef() takes a reference on |n|, |n| must outlive all | 51 // Note that because ConstRef() takes a reference on |n|, |n| must outlive all |
| 47 // its bound callbacks. | 52 // its bound callbacks. |
| 48 // | 53 // |
| 54 // | |
| 55 // EXAMPLE OF IgnoreReturn(): | |
| 56 // int DoSomething(int arg) { cout << arg << end; } | |
|
darin (slow to review)
2011/09/27 16:48:01
nit: "end" -> "endl"
awong
2011/09/27 21:35:00
Done.
| |
| 57 // Callback <int(void)> cb = Bind(&DoSomething, 1); | |
|
darin (slow to review)
2011/09/27 16:48:01
nit: no space before "<"
awong
2011/09/27 21:35:00
Done.
| |
| 58 // Closure c = IgnoreReturn(cb); // Prints "1" | |
|
darin (slow to review)
2011/09/27 16:48:01
All of the use cases I can imagine would basically
| |
| 59 // or | |
| 60 // ml->PostTask(FROM_HERE, IgnoreReturn(cb)); // Prints "1" on |ml| | |
| 49 | 61 |
| 50 #ifndef BASE_BIND_HELPERS_H_ | 62 #ifndef BASE_BIND_HELPERS_H_ |
| 51 #define BASE_BIND_HELPERS_H_ | 63 #define BASE_BIND_HELPERS_H_ |
| 52 #pragma once | 64 #pragma once |
| 53 | 65 |
| 54 #include "base/basictypes.h" | 66 #include "base/basictypes.h" |
| 67 #include "base/bind.h" | |
| 68 #include "base/callback.h" | |
| 55 #include "base/memory/weak_ptr.h" | 69 #include "base/memory/weak_ptr.h" |
| 56 #include "base/template_util.h" | 70 #include "base/template_util.h" |
| 57 | 71 |
| 58 namespace base { | 72 namespace base { |
| 59 namespace internal { | 73 namespace internal { |
| 60 | 74 |
| 61 // Use the Substitution Failure Is Not An Error (SFINAE) trick to inspect T | 75 // Use the Substitution Failure Is Not An Error (SFINAE) trick to inspect T |
| 62 // for the existence of AddRef() and Release() functions of the correct | 76 // for the existence of AddRef() and Release() functions of the correct |
| 63 // signature. | 77 // signature. |
| 64 // | 78 // |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 248 static void AddRef(const T* o) { o->AddRef(); } | 262 static void AddRef(const T* o) { o->AddRef(); } |
| 249 static void Release(const T* o) { o->Release(); } | 263 static void Release(const T* o) { o->Release(); } |
| 250 }; | 264 }; |
| 251 | 265 |
| 252 template <typename T> | 266 template <typename T> |
| 253 struct MaybeRefcount<base::true_type, WeakPtr<T> > { | 267 struct MaybeRefcount<base::true_type, WeakPtr<T> > { |
| 254 static void AddRef(const WeakPtr<T>&) {} | 268 static void AddRef(const WeakPtr<T>&) {} |
| 255 static void Release(const WeakPtr<T>&) {} | 269 static void Release(const WeakPtr<T>&) {} |
| 256 }; | 270 }; |
| 257 | 271 |
| 272 template <typename R> | |
| 273 void VoidReturnAdapter(Callback<R(void)> callback) { | |
| 274 callback.Run(); | |
| 275 } | |
| 276 | |
| 258 } // namespace internal | 277 } // namespace internal |
| 259 | 278 |
| 260 template <typename T> | 279 template <typename T> |
| 261 inline internal::UnretainedWrapper<T> Unretained(T* o) { | 280 inline internal::UnretainedWrapper<T> Unretained(T* o) { |
| 262 return internal::UnretainedWrapper<T>(o); | 281 return internal::UnretainedWrapper<T>(o); |
| 263 } | 282 } |
| 264 | 283 |
| 265 template <typename T> | 284 template <typename T> |
| 266 inline internal::ConstRefWrapper<T> ConstRef(const T& o) { | 285 inline internal::ConstRefWrapper<T> ConstRef(const T& o) { |
| 267 return internal::ConstRefWrapper<T>(o); | 286 return internal::ConstRefWrapper<T>(o); |
| 268 } | 287 } |
| 269 | 288 |
| 289 template <typename R> | |
| 290 Closure IgnoreReturn(Callback<R(void)> callback) { | |
| 291 return Bind(&internal::VoidReturnAdapter<R>, callback); | |
| 292 } | |
| 293 | |
| 270 } // namespace base | 294 } // namespace base |
| 271 | 295 |
| 272 #endif // BASE_BIND_HELPERS_H_ | 296 #endif // BASE_BIND_HELPERS_H_ |
| OLD | NEW |