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 << endl; } |
| 57 // Callback<int(void)> cb = Bind(&DoSomething, 1); |
| 58 // Closure c = IgnoreReturn(cb); // Prints "1" |
| 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 |