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(), |
10 // base::ConstRef(), and base::IgnoreReturn(). | 10 // base::ConstRef(), and base::IgnoreReturn(). |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 // or | 83 // or |
84 // ml->PostTask(FROM_HERE, IgnoreReturn(cb)); // Prints "1" on |ml| | 84 // ml->PostTask(FROM_HERE, IgnoreReturn(cb)); // Prints "1" on |ml| |
85 | 85 |
86 #ifndef BASE_BIND_HELPERS_H_ | 86 #ifndef BASE_BIND_HELPERS_H_ |
87 #define BASE_BIND_HELPERS_H_ | 87 #define BASE_BIND_HELPERS_H_ |
88 #pragma once | 88 #pragma once |
89 | 89 |
90 #include "base/basictypes.h" | 90 #include "base/basictypes.h" |
91 #include "base/bind.h" | 91 #include "base/bind.h" |
92 #include "base/callback.h" | 92 #include "base/callback.h" |
| 93 #include "base/memory/scoped_ptr.h" |
93 #include "base/memory/weak_ptr.h" | 94 #include "base/memory/weak_ptr.h" |
94 #include "base/template_util.h" | 95 #include "base/template_util.h" |
95 | 96 |
96 namespace base { | 97 namespace base { |
97 namespace internal { | 98 namespace internal { |
98 | 99 |
99 // Use the Substitution Failure Is Not An Error (SFINAE) trick to inspect T | 100 // Use the Substitution Failure Is Not An Error (SFINAE) trick to inspect T |
100 // for the existence of AddRef() and Release() functions of the correct | 101 // for the existence of AddRef() and Release() functions of the correct |
101 // signature. | 102 // signature. |
102 // | 103 // |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 T* get() const { return ptr_; } | 281 T* get() const { return ptr_; } |
281 OwnedWrapper(const OwnedWrapper& other) { | 282 OwnedWrapper(const OwnedWrapper& other) { |
282 ptr_ = other.ptr_; | 283 ptr_ = other.ptr_; |
283 other.ptr_ = NULL; | 284 other.ptr_ = NULL; |
284 } | 285 } |
285 | 286 |
286 private: | 287 private: |
287 mutable T* ptr_; | 288 mutable T* ptr_; |
288 }; | 289 }; |
289 | 290 |
| 291 template <typename T> |
| 292 class PassScopedWrapper { |
| 293 public: |
| 294 explicit PassScopedWrapper(T scoper) : scoper_(scoper.Pass()) {} |
| 295 PassScopedWrapper(const PassScopedWrapper& other) |
| 296 : scoper_(other.scoper_.Pass()) { |
| 297 } |
| 298 T Pass() const { return scoper_.Pass(); } |
| 299 |
| 300 private: |
| 301 mutable T scoper_; |
| 302 }; |
| 303 |
290 // Unwrap the stored parameters for the wrappers above. | 304 // Unwrap the stored parameters for the wrappers above. |
291 template <typename T> | 305 template <typename T> |
292 struct UnwrapTraits { | 306 struct UnwrapTraits { |
293 typedef const T& ForwardType; | 307 typedef const T& ForwardType; |
294 static ForwardType Unwrap(const T& o) { return o; } | 308 static ForwardType Unwrap(const T& o) { return o; } |
295 }; | 309 }; |
296 | 310 |
297 template <typename T> | 311 template <typename T> |
298 struct UnwrapTraits<UnretainedWrapper<T> > { | 312 struct UnwrapTraits<UnretainedWrapper<T> > { |
299 typedef T* ForwardType; | 313 typedef T* ForwardType; |
(...skipping 23 matching lines...) Expand all Loading... |
323 }; | 337 }; |
324 | 338 |
325 template <typename T> | 339 template <typename T> |
326 struct UnwrapTraits<OwnedWrapper<T> > { | 340 struct UnwrapTraits<OwnedWrapper<T> > { |
327 typedef T* ForwardType; | 341 typedef T* ForwardType; |
328 static ForwardType Unwrap(const OwnedWrapper<T>& o) { | 342 static ForwardType Unwrap(const OwnedWrapper<T>& o) { |
329 return o.get(); | 343 return o.get(); |
330 } | 344 } |
331 }; | 345 }; |
332 | 346 |
| 347 |
| 348 template <typename T> |
| 349 T& BindMoveSupport(T& t) { return t; } |
| 350 |
| 351 template <typename T> |
| 352 T BindMoveSupport(const PassScopedWrapper<T>& p) { return p.Pass(); } |
| 353 |
333 // Utility for handling different refcounting semantics in the Bind() | 354 // Utility for handling different refcounting semantics in the Bind() |
334 // function. | 355 // function. |
335 template <bool, typename T> | 356 template <bool is_method, typename T> |
336 struct MaybeRefcount; | 357 struct MaybeRefcount; |
337 | 358 |
338 template <typename T> | 359 template <typename T> |
339 struct MaybeRefcount<false, T> { | 360 struct MaybeRefcount<false, T> { |
340 static void AddRef(const T&) {} | 361 static void AddRef(const T&) {} |
341 static void Release(const T&) {} | 362 static void Release(const T&) {} |
342 }; | 363 }; |
343 | 364 |
344 template <typename T, size_t n> | 365 template <typename T, size_t n> |
345 struct MaybeRefcount<false, T[n]> { | 366 struct MaybeRefcount<false, T[n]> { |
346 static void AddRef(const T*) {} | 367 static void AddRef(const T*) {} |
347 static void Release(const T*) {} | 368 static void Release(const T*) {} |
348 }; | 369 }; |
349 | 370 |
350 template <typename T> | 371 template <typename T> |
| 372 struct MaybeRefcount<true, T> { |
| 373 static void AddRef(const T&) {} |
| 374 static void Release(const T&) {} |
| 375 }; |
| 376 |
| 377 template <typename T> |
351 struct MaybeRefcount<true, T*> { | 378 struct MaybeRefcount<true, T*> { |
352 static void AddRef(T* o) { o->AddRef(); } | 379 static void AddRef(T* o) { o->AddRef(); } |
353 static void Release(T* o) { o->Release(); } | 380 static void Release(T* o) { o->Release(); } |
354 }; | 381 }; |
355 | 382 |
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 | 383 // No need to additionally AddRef() and Release() since we are storing a |
369 // scoped_refptr<> inside the storage object already. | 384 // scoped_refptr<> inside the storage object already. |
370 template <typename T> | 385 template <typename T> |
371 struct MaybeRefcount<true, scoped_refptr<T> > { | 386 struct MaybeRefcount<true, scoped_refptr<T> > { |
372 static void AddRef(const scoped_refptr<T>& o) {} | 387 static void AddRef(const scoped_refptr<T>& o) {} |
373 static void Release(const scoped_refptr<T>& o) {} | 388 static void Release(const scoped_refptr<T>& o) {} |
374 }; | 389 }; |
375 | 390 |
376 template <typename T> | 391 template <typename T> |
377 struct MaybeRefcount<true, const T*> { | 392 struct MaybeRefcount<true, const T*> { |
378 static void AddRef(const T* o) { o->AddRef(); } | 393 static void AddRef(const T* o) { o->AddRef(); } |
379 static void Release(const T* o) { o->Release(); } | 394 static void Release(const T* o) { o->Release(); } |
380 }; | 395 }; |
381 | 396 |
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> | 397 template <typename R> |
389 void VoidReturnAdapter(Callback<R(void)> callback) { | 398 void VoidReturnAdapter(Callback<R(void)> callback) { |
390 callback.Run(); | 399 callback.Run(); |
391 } | 400 } |
392 | 401 |
393 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a | 402 // 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 | 403 // method. It is unsed internally by Bind() to select the correct |
395 // InvokeHelper that will no-op itself in the event the WeakPtr<> for | 404 // InvokeHelper that will no-op itself in the event the WeakPtr<> for |
396 // the target object is invalidated. | 405 // the target object is invalidated. |
397 // | 406 // |
(...skipping 17 matching lines...) Expand all Loading... |
415 template <typename T> | 424 template <typename T> |
416 static inline internal::ConstRefWrapper<T> ConstRef(const T& o) { | 425 static inline internal::ConstRefWrapper<T> ConstRef(const T& o) { |
417 return internal::ConstRefWrapper<T>(o); | 426 return internal::ConstRefWrapper<T>(o); |
418 } | 427 } |
419 | 428 |
420 template <typename T> | 429 template <typename T> |
421 static inline internal::OwnedWrapper<T> Owned(T* o) { | 430 static inline internal::OwnedWrapper<T> Owned(T* o) { |
422 return internal::OwnedWrapper<T>(o); | 431 return internal::OwnedWrapper<T>(o); |
423 } | 432 } |
424 | 433 |
| 434 template <typename T> |
| 435 static inline internal::PassScopedWrapper<T> PassScoped(T* scoper) { |
| 436 return internal::PassScopedWrapper<T>(scoper->Pass()); |
| 437 } |
| 438 |
425 template <typename R> | 439 template <typename R> |
426 static inline Closure IgnoreReturn(Callback<R(void)> callback) { | 440 static inline Closure IgnoreReturn(Callback<R(void)> callback) { |
427 return Bind(&internal::VoidReturnAdapter<R>, callback); | 441 return Bind(&internal::VoidReturnAdapter<R>, callback); |
428 } | 442 } |
429 | 443 |
430 template <typename T> | 444 template <typename T> |
431 static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) { | 445 static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) { |
432 return internal::IgnoreResultHelper<T>(data); | 446 return internal::IgnoreResultHelper<T>(data); |
433 } | 447 } |
434 | 448 |
435 template <typename T> | 449 template <typename T> |
436 static inline internal::IgnoreResultHelper<Callback<T> > | 450 static inline internal::IgnoreResultHelper<Callback<T> > |
437 IgnoreResult(const Callback<T>& data) { | 451 IgnoreResult(const Callback<T>& data) { |
438 return internal::IgnoreResultHelper<Callback<T> >(data); | 452 return internal::IgnoreResultHelper<Callback<T> >(data); |
439 } | 453 } |
440 | 454 |
441 | |
442 } // namespace base | 455 } // namespace base |
443 | 456 |
444 #endif // BASE_BIND_HELPERS_H_ | 457 #endif // BASE_BIND_HELPERS_H_ |
OLD | NEW |