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 // It also defines a set of simple functions and utilities that people want | 9 // It also defines a set of simple functions and utilities that people want |
10 // when using Callback<> and Bind(). | 10 // when using Callback<> and Bind(). |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 template <typename T> | 428 template <typename T> |
429 struct UnwrapTraits<PassedWrapper<T> > { | 429 struct UnwrapTraits<PassedWrapper<T> > { |
430 typedef T ForwardType; | 430 typedef T ForwardType; |
431 static T Unwrap(PassedWrapper<T>& o) { | 431 static T Unwrap(PassedWrapper<T>& o) { |
432 return o.Pass(); | 432 return o.Pass(); |
433 } | 433 } |
434 }; | 434 }; |
435 | 435 |
436 // Utility for handling different refcounting semantics in the Bind() | 436 // Utility for handling different refcounting semantics in the Bind() |
437 // function. | 437 // function. |
438 template <bool is_method, typename T> | 438 template <bool is_method, typename... T> |
439 struct MaybeRefcount; | 439 struct MaybeScopedRefPtr; |
440 | 440 |
441 template <typename T> | 441 template <bool is_method> |
442 struct MaybeRefcount<false, T> { | 442 struct MaybeScopedRefPtr<is_method> { |
443 static void AddRef(const T&) {} | 443 MaybeScopedRefPtr() {} |
444 static void Release(const T&) {} | |
445 }; | 444 }; |
446 | 445 |
447 template <typename T, size_t n> | 446 template <typename T, typename... Rest> |
448 struct MaybeRefcount<false, T[n]> { | 447 struct MaybeScopedRefPtr<false, T, Rest...> { |
449 static void AddRef(const T*) {} | 448 MaybeScopedRefPtr(const T&, const Rest&...) {} |
450 static void Release(const T*) {} | |
451 }; | 449 }; |
452 | 450 |
453 template <typename T> | 451 template <typename T, size_t n, typename... Rest> |
454 struct MaybeRefcount<true, T> { | 452 struct MaybeScopedRefPtr<false, T[n], Rest...> { |
455 static void AddRef(const T&) {} | 453 MaybeScopedRefPtr(const T*, const Rest&...) {} |
456 static void Release(const T&) {} | |
457 }; | 454 }; |
458 | 455 |
459 template <typename T> | 456 template <typename T, typename... Rest> |
460 struct MaybeRefcount<true, T*> { | 457 struct MaybeScopedRefPtr<true, T, Rest...> { |
461 static void AddRef(T* o) { o->AddRef(); } | 458 MaybeScopedRefPtr(const T& o, const Rest&...) {} |
462 static void Release(T* o) { o->Release(); } | 459 }; |
| 460 |
| 461 template <typename T, typename... Rest> |
| 462 struct MaybeScopedRefPtr<true, T*, Rest...> { |
| 463 MaybeScopedRefPtr(T* o, const Rest&...) : ref_(o) {} |
| 464 scoped_refptr<T> ref_; |
463 }; | 465 }; |
464 | 466 |
465 // No need to additionally AddRef() and Release() since we are storing a | 467 // No need to additionally AddRef() and Release() since we are storing a |
466 // scoped_refptr<> inside the storage object already. | 468 // scoped_refptr<> inside the storage object already. |
467 template <typename T> | 469 template <typename T, typename... Rest> |
468 struct MaybeRefcount<true, scoped_refptr<T> > { | 470 struct MaybeScopedRefPtr<true, scoped_refptr<T>, Rest...> { |
469 static void AddRef(const scoped_refptr<T>& o) {} | 471 MaybeScopedRefPtr(const scoped_refptr<T>&, const Rest&...) {} |
470 static void Release(const scoped_refptr<T>& o) {} | |
471 }; | 472 }; |
472 | 473 |
473 template <typename T> | 474 template <typename T, typename... Rest> |
474 struct MaybeRefcount<true, const T*> { | 475 struct MaybeScopedRefPtr<true, const T*, Rest...> { |
475 static void AddRef(const T* o) { o->AddRef(); } | 476 MaybeScopedRefPtr(const T* o, const Rest&...) : ref_(o) {} |
476 static void Release(const T* o) { o->Release(); } | 477 scoped_refptr<const T> ref_; |
477 }; | 478 }; |
478 | 479 |
479 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a | 480 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a |
480 // method. It is used internally by Bind() to select the correct | 481 // method. It is used internally by Bind() to select the correct |
481 // InvokeHelper that will no-op itself in the event the WeakPtr<> for | 482 // InvokeHelper that will no-op itself in the event the WeakPtr<> for |
482 // the target object is invalidated. | 483 // the target object is invalidated. |
483 // | 484 // |
484 // P1 should be the type of the object that will be received of the method. | 485 // The first argument should be the type of the object that will be received by |
485 template <bool IsMethod, typename P1> | 486 // the method. |
| 487 template <bool IsMethod, typename... Args> |
486 struct IsWeakMethod : public false_type {}; | 488 struct IsWeakMethod : public false_type {}; |
487 | 489 |
488 template <typename T> | 490 template <typename T, typename... Args> |
489 struct IsWeakMethod<true, WeakPtr<T> > : public true_type {}; | 491 struct IsWeakMethod<true, WeakPtr<T>, Args...> : public true_type {}; |
490 | 492 |
491 template <typename T> | 493 template <typename T, typename... Args> |
492 struct IsWeakMethod<true, ConstRefWrapper<WeakPtr<T> > > : public true_type {}; | 494 struct IsWeakMethod<true, ConstRefWrapper<WeakPtr<T>>, Args...> |
| 495 : public true_type {}; |
| 496 |
| 497 |
| 498 // Packs a list of types to hold them in a single type. |
| 499 template <typename... Types> |
| 500 struct TypeList {}; |
| 501 |
| 502 // Used for DropTypeListItem implementation. |
| 503 template <size_t n, typename List> |
| 504 struct DropTypeListItemImpl; |
| 505 |
| 506 // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. |
| 507 template <size_t n, typename T, typename... List> |
| 508 struct DropTypeListItemImpl<n, TypeList<T, List...>> |
| 509 : DropTypeListItemImpl<n - 1, TypeList<List...>> {}; |
| 510 |
| 511 template <typename T, typename... List> |
| 512 struct DropTypeListItemImpl<0, TypeList<T, List...>> { |
| 513 typedef TypeList<T, List...> Type; |
| 514 }; |
| 515 |
| 516 template <> |
| 517 struct DropTypeListItemImpl<0, TypeList<>> { |
| 518 typedef TypeList<> Type; |
| 519 }; |
| 520 |
| 521 // A type-level function that drops |n| list item from given TypeList. |
| 522 template <size_t n, typename List> |
| 523 using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type; |
| 524 |
| 525 // Used for ConcatTypeLists implementation. |
| 526 template <typename List1, typename List2> |
| 527 struct ConcatTypeListsImpl; |
| 528 |
| 529 template <typename... Types1, typename... Types2> |
| 530 struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> { |
| 531 typedef TypeList<Types1..., Types2...> Type; |
| 532 }; |
| 533 |
| 534 // A type-level function that concats two TypeLists. |
| 535 template <typename List1, typename List2> |
| 536 using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type; |
| 537 |
| 538 template <size_t n, typename List> |
| 539 struct NthTypeImpl; |
| 540 |
| 541 template <size_t n, typename T, typename... Types> |
| 542 struct NthTypeImpl<n, TypeList<T, Types...>> |
| 543 : NthTypeImpl<n - 1, TypeList<Types...>> { |
| 544 }; |
| 545 |
| 546 template <typename T, typename... Types> |
| 547 struct NthTypeImpl<0, TypeList<T, Types...>> { |
| 548 typedef T Type; |
| 549 }; |
| 550 |
| 551 // A type-level function that extracts |n|th type from a TypeList. |
| 552 template <size_t n, typename List> |
| 553 using NthType = typename NthTypeImpl<n, List>::Type; |
| 554 |
| 555 // Used for MakeFunctionType implementation. |
| 556 template <typename R, typename ArgList> |
| 557 struct MakeFunctionTypeImpl; |
| 558 |
| 559 template <typename R, typename... Args> |
| 560 struct MakeFunctionTypeImpl<R, TypeList<Args...>> { |
| 561 typedef R(Type)(Args...); |
| 562 }; |
| 563 |
| 564 // A type-level function that constructs a function type that has |R| as its |
| 565 // return type and has TypeLists items as its arguments. |
| 566 template <typename R, typename ArgList> |
| 567 using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type; |
493 | 568 |
494 } // namespace internal | 569 } // namespace internal |
495 | 570 |
496 template <typename T> | 571 template <typename T> |
497 static inline internal::UnretainedWrapper<T> Unretained(T* o) { | 572 static inline internal::UnretainedWrapper<T> Unretained(T* o) { |
498 return internal::UnretainedWrapper<T>(o); | 573 return internal::UnretainedWrapper<T>(o); |
499 } | 574 } |
500 | 575 |
501 template <typename T> | 576 template <typename T> |
502 static inline internal::ConstRefWrapper<T> ConstRef(const T& o) { | 577 static inline internal::ConstRefWrapper<T> ConstRef(const T& o) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 BASE_EXPORT void DoNothing(); | 610 BASE_EXPORT void DoNothing(); |
536 | 611 |
537 template<typename T> | 612 template<typename T> |
538 void DeletePointer(T* obj) { | 613 void DeletePointer(T* obj) { |
539 delete obj; | 614 delete obj; |
540 } | 615 } |
541 | 616 |
542 } // namespace base | 617 } // namespace base |
543 | 618 |
544 #endif // BASE_BIND_HELPERS_H_ | 619 #endif // BASE_BIND_HELPERS_H_ |
OLD | NEW |