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::ConstRef(), and | 9 // The public functions are base::Unretained(), base::Owned(), |
10 // base::IgnoreReturn(). | 10 // base::ConstRef(), and base::IgnoreReturn(). |
11 // | 11 // |
12 // Unretained() allows Bind() to bind a non-refcounted class. | 12 // Unretained() allows Bind() to bind a non-refcounted class, and to disable |
13 // refcounting on arguments that are refcounted objects. | |
14 // Owned() transfers ownership of an object to the Callback resulting from | |
15 // bind; the object will be deleted when the Callback is deleted. | |
13 // ConstRef() allows binding a constant reference to an argument rather | 16 // ConstRef() allows binding a constant reference to an argument rather |
14 // than a copy. | 17 // than a copy. |
15 // IgnoreReturn() is used to adapt a 0-argument Callback with a return type to | 18 // 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 | 19 // 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. | 20 // a return value that you don't care about. |
18 // | 21 // |
19 // | 22 // |
20 // EXAMPLE OF Unretained(): | 23 // EXAMPLE OF Unretained(): |
21 // | 24 // |
22 // class Foo { | 25 // class Foo { |
23 // public: | 26 // public: |
24 // void func() { cout << "Foo:f" << endl; } | 27 // void func() { cout << "Foo:f" << endl; } |
25 // }; | 28 // }; |
26 // | 29 // |
27 // // In some function somewhere. | 30 // // In some function somewhere. |
28 // Foo foo; | 31 // Foo foo; |
29 // Callback<void(void)> foo_callback = | 32 // Closure foo_callback = |
30 // Bind(&Foo::func, Unretained(&foo)); | 33 // Bind(&Foo::func, Unretained(&foo)); |
31 // foo_callback.Run(); // Prints "Foo:f". | 34 // foo_callback.Run(); // Prints "Foo:f". |
32 // | 35 // |
33 // Without the Unretained() wrapper on |&foo|, the above call would fail | 36 // Without the Unretained() wrapper on |&foo|, the above call would fail |
34 // to compile because Foo does not support the AddRef() and Release() methods. | 37 // to compile because Foo does not support the AddRef() and Release() methods. |
35 // | 38 // |
36 // | 39 // |
40 // EXAMPLE OF Owned(): | |
darin (slow to review)
2011/10/14 21:53:07
nit: new line below this line as you did for Unret
awong
2011/10/15 00:19:16
Done. Also fixed ConstRef and IgnoreReturn.
| |
41 // void foo(int* arg) { cout << *arg << endl } | |
42 // | |
43 // int* pn = new int(1); | |
44 // Closure foo_callback = Bind(&foo, Owned(pn)); | |
45 // | |
46 // foo_callback.Run(); // Prints "1" | |
47 // foo_callback.Run(); // Prints "1" | |
48 // *n = 2; | |
49 // foo_callback.Run(); // Prints "2" | |
50 // | |
51 // foo_callback.Reset(); // |pn| is deleted. Also will happen when | |
52 // // |foo_callback| goes out of scope. | |
53 // | |
54 // Without Owned(), someone would have to know to delete |pn| when the last | |
55 // reference to the Callback is deleted. | |
56 // | |
57 // | |
37 // EXAMPLE OF ConstRef(): | 58 // EXAMPLE OF ConstRef(): |
38 // void foo(int arg) { cout << arg << endl } | 59 // void foo(int arg) { cout << arg << endl } |
39 // | 60 // |
40 // int n = 1; | 61 // int n = 1; |
41 // Callback<void(void)> no_ref = Bind(&foo, n); | 62 // Closure no_ref = Bind(&foo, n); |
42 // Callback<void(void)> has_ref = Bind(&foo, ConstRef(n)); | 63 // Closure has_ref = Bind(&foo, ConstRef(n)); |
43 // | 64 // |
44 // no_ref.Run(); // Prints "1" | 65 // no_ref.Run(); // Prints "1" |
45 // has_ref.Run(); // Prints "1" | 66 // has_ref.Run(); // Prints "1" |
46 // | 67 // |
47 // n = 2; | 68 // n = 2; |
48 // no_ref.Run(); // Prints "1" | 69 // no_ref.Run(); // Prints "1" |
49 // has_ref.Run(); // Prints "2" | 70 // has_ref.Run(); // Prints "2" |
50 // | 71 // |
51 // Note that because ConstRef() takes a reference on |n|, |n| must outlive all | 72 // Note that because ConstRef() takes a reference on |n|, |n| must outlive all |
52 // its bound callbacks. | 73 // its bound callbacks. |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
192 | 213 |
193 template <typename T> | 214 template <typename T> |
194 struct UnsafeBindtoRefCountedArg<T*> | 215 struct UnsafeBindtoRefCountedArg<T*> |
195 : UnsafeBindtoRefCountedArgHelper<is_class<T>::value, T> { | 216 : UnsafeBindtoRefCountedArgHelper<is_class<T>::value, T> { |
196 }; | 217 }; |
197 | 218 |
198 | 219 |
199 template <typename T> | 220 template <typename T> |
200 class UnretainedWrapper { | 221 class UnretainedWrapper { |
201 public: | 222 public: |
202 explicit UnretainedWrapper(T* o) : obj_(o) {} | 223 explicit UnretainedWrapper(T* o) : ptr_(o) {} |
203 T* get() { return obj_; } | 224 T* get() const { return ptr_; } |
204 private: | 225 private: |
205 T* obj_; | 226 T* ptr_; |
206 }; | 227 }; |
207 | 228 |
208 template <typename T> | 229 template <typename T> |
209 class ConstRefWrapper { | 230 class ConstRefWrapper { |
210 public: | 231 public: |
211 explicit ConstRefWrapper(const T& o) : ptr_(&o) {} | 232 explicit ConstRefWrapper(const T& o) : ptr_(&o) {} |
212 const T& get() { return *ptr_; } | 233 const T& get() const { return *ptr_; } |
213 private: | 234 private: |
214 const T* ptr_; | 235 const T* ptr_; |
215 }; | 236 }; |
216 | 237 |
238 // An alternate implementation is to avoid the destructive copy, and instead | |
239 // specialize ParamTraits<> for OwnedWrapper<> to change the StorageType to | |
240 // a class that is essentially a scoped_ptr<>. | |
241 // | |
242 // This has the benefit though of leaving ParamTrais<> fully in | |
darin (slow to review)
2011/10/14 21:53:07
nit: ParamTrais -> ParamTraits
awong
2011/10/15 00:19:16
Done.
| |
243 // callback_internal.h as well as avoiding type conversions during storage. | |
244 template <typename T> | |
245 class OwnedWrapper { | |
246 public: | |
247 explicit OwnedWrapper(T* o) : ptr_(o) {} | |
248 ~OwnedWrapper() { delete ptr_; } | |
249 T* get() const { return ptr_; } | |
250 OwnedWrapper(const OwnedWrapper& other) { | |
251 ptr_ = other.ptr_; | |
252 other.ptr_ = NULL; | |
253 } | |
254 | |
255 private: | |
256 mutable T* ptr_; | |
257 }; | |
258 | |
217 | 259 |
218 // Unwrap the stored parameters for the wrappers above. | 260 // Unwrap the stored parameters for the wrappers above. |
219 template <typename T> | 261 template <typename T> |
220 T Unwrap(T o) { return o; } | 262 T Unwrap(T o) { return o; } |
221 | 263 |
222 template <typename T> | 264 template <typename T> |
223 T* Unwrap(UnretainedWrapper<T> unretained) { return unretained.get(); } | 265 T* Unwrap(UnretainedWrapper<T> unretained) { return unretained.get(); } |
224 | 266 |
225 template <typename T> | 267 template <typename T> |
226 const T& Unwrap(ConstRefWrapper<T> const_ref) { | 268 const T& Unwrap(ConstRefWrapper<T> const_ref) { |
227 return const_ref.get(); | 269 return const_ref.get(); |
228 } | 270 } |
229 | 271 |
230 template <typename T> | 272 template <typename T> |
231 T* Unwrap(const scoped_refptr<T>& o) { return o.get(); } | 273 T* Unwrap(const scoped_refptr<T>& o) { return o.get(); } |
232 | 274 |
233 template <typename T> | 275 template <typename T> |
234 const WeakPtr<T>& Unwrap(const WeakPtr<T>& o) { return o; } | 276 const WeakPtr<T>& Unwrap(const WeakPtr<T>& o) { return o; } |
235 | 277 |
278 template <typename T> | |
279 T* Unwrap(const OwnedWrapper<T>& o) { | |
280 return o.get(); | |
281 } | |
282 | |
236 // Utility for handling different refcounting semantics in the Bind() | 283 // Utility for handling different refcounting semantics in the Bind() |
237 // function. | 284 // function. |
238 template <typename IsMethod, typename T> | 285 template <typename IsMethod, typename T> |
239 struct MaybeRefcount; | 286 struct MaybeRefcount; |
240 | 287 |
241 template <typename T> | 288 template <typename T> |
242 struct MaybeRefcount<base::false_type, T> { | 289 struct MaybeRefcount<base::false_type, T> { |
243 static void AddRef(const T&) {} | 290 static void AddRef(const T&) {} |
244 static void Release(const T&) {} | 291 static void Release(const T&) {} |
245 }; | 292 }; |
246 | 293 |
247 template <typename T, size_t n> | 294 template <typename T, size_t n> |
248 struct MaybeRefcount<base::false_type, T[n]> { | 295 struct MaybeRefcount<base::false_type, T[n]> { |
249 static void AddRef(const T*) {} | 296 static void AddRef(const T*) {} |
250 static void Release(const T*) {} | 297 static void Release(const T*) {} |
251 }; | 298 }; |
252 | 299 |
253 template <typename T> | 300 template <typename T> |
301 struct MaybeRefcount<base::true_type, T*> { | |
302 static void AddRef(T* o) { o->AddRef(); } | |
303 static void Release(T* o) { o->Release(); } | |
304 }; | |
305 | |
306 template <typename T> | |
254 struct MaybeRefcount<base::true_type, UnretainedWrapper<T> > { | 307 struct MaybeRefcount<base::true_type, UnretainedWrapper<T> > { |
255 static void AddRef(const UnretainedWrapper<T>&) {} | 308 static void AddRef(const UnretainedWrapper<T>&) {} |
256 static void Release(const UnretainedWrapper<T>&) {} | 309 static void Release(const UnretainedWrapper<T>&) {} |
257 }; | 310 }; |
258 | 311 |
259 template <typename T> | 312 template <typename T> |
260 struct MaybeRefcount<base::true_type, T*> { | 313 struct MaybeRefcount<base::true_type, OwnedWrapper<T> > { |
261 static void AddRef(T* o) { o->AddRef(); } | 314 static void AddRef(const OwnedWrapper<T>&) {} |
262 static void Release(T* o) { o->Release(); } | 315 static void Release(const OwnedWrapper<T>&) {} |
263 }; | 316 }; |
264 | 317 |
265 // No need to additionally AddRef() and Release() since we are storing a | 318 // No need to additionally AddRef() and Release() since we are storing a |
266 // scoped_refptr<> inside the storage object already. | 319 // scoped_refptr<> inside the storage object already. |
267 template <typename T> | 320 template <typename T> |
268 struct MaybeRefcount<base::true_type, scoped_refptr<T> > { | 321 struct MaybeRefcount<base::true_type, scoped_refptr<T> > { |
269 static void AddRef(const scoped_refptr<T>& o) {} | 322 static void AddRef(const scoped_refptr<T>& o) {} |
270 static void Release(const scoped_refptr<T>& o) {} | 323 static void Release(const scoped_refptr<T>& o) {} |
271 }; | 324 }; |
272 | 325 |
(...skipping 19 matching lines...) Expand all Loading... | |
292 template <typename T> | 345 template <typename T> |
293 inline internal::UnretainedWrapper<T> Unretained(T* o) { | 346 inline internal::UnretainedWrapper<T> Unretained(T* o) { |
294 return internal::UnretainedWrapper<T>(o); | 347 return internal::UnretainedWrapper<T>(o); |
295 } | 348 } |
296 | 349 |
297 template <typename T> | 350 template <typename T> |
298 inline internal::ConstRefWrapper<T> ConstRef(const T& o) { | 351 inline internal::ConstRefWrapper<T> ConstRef(const T& o) { |
299 return internal::ConstRefWrapper<T>(o); | 352 return internal::ConstRefWrapper<T>(o); |
300 } | 353 } |
301 | 354 |
355 template <typename T> | |
356 inline internal::OwnedWrapper<T> Owned(T* o) { | |
357 return internal::OwnedWrapper<T>(o); | |
358 } | |
359 | |
302 template <typename R> | 360 template <typename R> |
303 Closure IgnoreReturn(Callback<R(void)> callback) { | 361 Closure IgnoreReturn(Callback<R(void)> callback) { |
304 return Bind(&internal::VoidReturnAdapter<R>, callback); | 362 return Bind(&internal::VoidReturnAdapter<R>, callback); |
305 } | 363 } |
306 | 364 |
307 } // namespace base | 365 } // namespace base |
308 | 366 |
309 #endif // BASE_BIND_HELPERS_H_ | 367 #endif // BASE_BIND_HELPERS_H_ |
OLD | NEW |