OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
Nico
2015/02/05 05:53:33
I think the "Introduce Tuple" from the CL descript
tzik
2015/02/05 08:52:49
Done.
| |
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(). |
11 // | 11 // |
(...skipping 416 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(); } | |
463 }; | 459 }; |
464 | 460 |
465 // No need to additionally AddRef() and Release() since we are storing a | 461 template <typename T, typename... Rest> |
466 // scoped_refptr<> inside the storage object already. | 462 struct MaybeScopedRefPtr<true, T*, Rest...> { |
467 template <typename T> | 463 MaybeScopedRefPtr(T* o, const Rest&...) : ref_(o) {} |
468 struct MaybeRefcount<true, scoped_refptr<T> > { | 464 scoped_refptr<T> ref_; |
Nico
2015/02/05 05:53:33
nit: Moving this from explicit AddRef / Release to
| |
469 static void AddRef(const scoped_refptr<T>& o) {} | |
470 static void Release(const scoped_refptr<T>& o) {} | |
471 }; | 465 }; |
472 | 466 |
473 template <typename T> | 467 template <typename T, typename... Rest> |
474 struct MaybeRefcount<true, const T*> { | 468 struct MaybeScopedRefPtr<true, scoped_refptr<T>, Rest...> { |
Nico
2015/02/05 05:53:33
Maybe keep the "No need to have a scoped_refptr in
tzik
2015/02/05 08:52:49
Done.
| |
475 static void AddRef(const T* o) { o->AddRef(); } | 469 MaybeScopedRefPtr(const scoped_refptr<T>&, const Rest&...) {} |
476 static void Release(const T* o) { o->Release(); } | 470 }; |
471 | |
472 template <typename T, typename... Rest> | |
473 struct MaybeScopedRefPtr<true, const T*, Rest...> { | |
474 MaybeScopedRefPtr(const T* o, const Rest&...) : ref_(o) {} | |
475 scoped_refptr<const T> ref_; | |
477 }; | 476 }; |
478 | 477 |
479 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a | 478 // 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 | 479 // method. It is used internally by Bind() to select the correct |
481 // InvokeHelper that will no-op itself in the event the WeakPtr<> for | 480 // InvokeHelper that will no-op itself in the event the WeakPtr<> for |
482 // the target object is invalidated. | 481 // the target object is invalidated. |
483 // | 482 // |
484 // P1 should be the type of the object that will be received of the method. | 483 // The first argument should be the type of the object that will be received of |
485 template <bool IsMethod, typename P1> | 484 // the method. |
485 template <bool IsMethod, typename... Args> | |
486 struct IsWeakMethod : public false_type {}; | 486 struct IsWeakMethod : public false_type {}; |
487 | 487 |
488 template <typename T> | 488 template <typename T, typename... Args> |
489 struct IsWeakMethod<true, WeakPtr<T> > : public true_type {}; | 489 struct IsWeakMethod<true, WeakPtr<T>, Args...> : public true_type {}; |
490 | 490 |
491 template <typename T> | 491 template <typename T, typename... Args> |
492 struct IsWeakMethod<true, ConstRefWrapper<WeakPtr<T> > > : public true_type {}; | 492 struct IsWeakMethod<true, ConstRefWrapper<WeakPtr<T>>, Args...> |
493 : public true_type {}; | |
494 | |
495 | |
496 // Packs a list of types to hold them in a single type. | |
497 template <typename... Types> | |
498 struct TypeList {}; | |
499 | |
500 // Used for DropTypeListItem implementation. | |
501 template <size_t n, typename List> | |
502 struct DropTypeListItemImpl; | |
503 | |
504 // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. | |
505 template <size_t n, typename T, typename... List> | |
506 struct DropTypeListItemImpl<n, TypeList<T, List...>> | |
507 : DropTypeListItemImpl<n - 1, TypeList<List...>> {}; | |
508 | |
509 template <typename T, typename... List> | |
510 struct DropTypeListItemImpl<0, TypeList<T, List...>> { | |
511 typedef TypeList<T, List...> Type; | |
512 }; | |
513 | |
514 template <> | |
515 struct DropTypeListItemImpl<0, TypeList<>> { | |
516 typedef TypeList<> Type; | |
517 }; | |
518 | |
519 // A type-level function that drops |n| list item from given TypeList. | |
520 template <size_t n, typename List> | |
521 using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type; | |
522 | |
523 // Used for ConcatTypeLists implementation. | |
524 template <typename List1, typename List2> | |
525 struct ConcatTypeListsImpl; | |
526 | |
527 template <typename... Types1, typename... Types2> | |
528 struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> { | |
529 typedef TypeList<Types1..., Types2...> Type; | |
530 }; | |
531 | |
532 // A type-level function that concats two TypeLists. | |
533 template <typename List1, typename List2> | |
534 using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type; | |
535 | |
536 template <size_t n, typename List> | |
537 struct NthTypeImpl; | |
538 | |
539 template <size_t n, typename T, typename... Types> | |
540 struct NthTypeImpl<n, TypeList<T, Types...>> | |
541 : NthTypeImpl<n - 1, TypeList<Types...>> { | |
542 }; | |
543 | |
544 template <typename T, typename... Types> | |
545 struct NthTypeImpl<0, TypeList<T, Types...>> { | |
546 typedef T Type; | |
547 }; | |
548 | |
549 // A type-level function that extracts |n|th type from a TypeList. | |
550 template <size_t n, typename List> | |
551 using NthType = typename NthTypeImpl<n, List>::Type; | |
552 | |
553 // Used for MakeFunctionType implementation. | |
554 template <typename R, typename ArgList> | |
555 struct MakeFunctionTypeImpl; | |
556 | |
557 template <typename R, typename... Args> | |
558 struct MakeFunctionTypeImpl<R, TypeList<Args...>> { | |
559 typedef R(Type)(Args...); | |
560 }; | |
561 | |
562 // A type-level function that constructs a function type that has |R| as its | |
563 // return type and has TypeLists items as its arguments. | |
564 template <typename R, typename ArgList> | |
565 using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type; | |
493 | 566 |
494 } // namespace internal | 567 } // namespace internal |
495 | 568 |
496 template <typename T> | 569 template <typename T> |
497 static inline internal::UnretainedWrapper<T> Unretained(T* o) { | 570 static inline internal::UnretainedWrapper<T> Unretained(T* o) { |
498 return internal::UnretainedWrapper<T>(o); | 571 return internal::UnretainedWrapper<T>(o); |
499 } | 572 } |
500 | 573 |
501 template <typename T> | 574 template <typename T> |
502 static inline internal::ConstRefWrapper<T> ConstRef(const T& o) { | 575 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(); | 608 BASE_EXPORT void DoNothing(); |
536 | 609 |
537 template<typename T> | 610 template<typename T> |
538 void DeletePointer(T* obj) { | 611 void DeletePointer(T* obj) { |
539 delete obj; | 612 delete obj; |
540 } | 613 } |
541 | 614 |
542 } // namespace base | 615 } // namespace base |
543 | 616 |
544 #endif // BASE_BIND_HELPERS_H_ | 617 #endif // BASE_BIND_HELPERS_H_ |
OLD | NEW |