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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 // C::TargetFunc if TargetFunc does not exist directly in C. That is, if | 181 // C::TargetFunc if TargetFunc does not exist directly in C. That is, if |
182 // TargetFunc in inherited from an ancestor, &C::TargetFunc will not match, | 182 // TargetFunc in inherited from an ancestor, &C::TargetFunc will not match, |
183 // |value| will be false. This formulation only checks for whether or | 183 // |value| will be false. This formulation only checks for whether or |
184 // not TargetFunc exist directly in the class being introspected. | 184 // not TargetFunc exist directly in the class being introspected. |
185 // | 185 // |
186 // To get around this, we play a dirty trick with multiple inheritance. | 186 // To get around this, we play a dirty trick with multiple inheritance. |
187 // First, We create a class BaseMixin that declares each function that we | 187 // First, We create a class BaseMixin that declares each function that we |
188 // want to probe for. Then we create a class Base that inherits from both T | 188 // want to probe for. Then we create a class Base that inherits from both T |
189 // (the class we wish to probe) and BaseMixin. Note that the function | 189 // (the class we wish to probe) and BaseMixin. Note that the function |
190 // signature in BaseMixin does not need to match the signature of the function | 190 // signature in BaseMixin does not need to match the signature of the function |
191 // we are probing for; thus it's easiest to just use void(void). | 191 // we are probing for; thus it's easiest to just use void(). |
192 // | 192 // |
193 // Now, if TargetFunc exists somewhere in T, then &Base::TargetFunc has an | 193 // Now, if TargetFunc exists somewhere in T, then &Base::TargetFunc has an |
194 // ambiguous resolution between BaseMixin and T. This lets us write the | 194 // ambiguous resolution between BaseMixin and T. This lets us write the |
195 // following: | 195 // following: |
196 // | 196 // |
197 // template <typename C> | 197 // template <typename C> |
198 // No GoodCheck(Helper<&C::TargetFunc>*); | 198 // No GoodCheck(Helper<&C::TargetFunc>*); |
199 // | 199 // |
200 // template <typename C> | 200 // template <typename C> |
201 // Yes GoodCheck(...); | 201 // Yes GoodCheck(...); |
(...skipping 16 matching lines...) Expand all Loading... |
218 // | 218 // |
219 // Works on gcc-4.2, gcc-4.4, and Visual Studio 2008. | 219 // Works on gcc-4.2, gcc-4.4, and Visual Studio 2008. |
220 // | 220 // |
221 // TODO(ajwong): Move to ref_counted.h or template_util.h when we've vetted | 221 // TODO(ajwong): Move to ref_counted.h or template_util.h when we've vetted |
222 // this works well. | 222 // this works well. |
223 // | 223 // |
224 // TODO(ajwong): Make this check for Release() as well. | 224 // TODO(ajwong): Make this check for Release() as well. |
225 // See http://crbug.com/82038. | 225 // See http://crbug.com/82038. |
226 template <typename T> | 226 template <typename T> |
227 class SupportsAddRefAndRelease { | 227 class SupportsAddRefAndRelease { |
228 typedef char Yes[1]; | 228 using Yes = char[1]; |
229 typedef char No[2]; | 229 using No = char[2]; |
230 | 230 |
231 struct BaseMixin { | 231 struct BaseMixin { |
232 void AddRef(); | 232 void AddRef(); |
233 }; | 233 }; |
234 | 234 |
235 // MSVC warns when you try to use Base if T has a private destructor, the | 235 // MSVC warns when you try to use Base if T has a private destructor, the |
236 // common pattern for refcounted types. It does this even though no attempt to | 236 // common pattern for refcounted types. It does this even though no attempt to |
237 // instantiate Base is made. We disable the warning for this definition. | 237 // instantiate Base is made. We disable the warning for this definition. |
238 #if defined(OS_WIN) | 238 #if defined(OS_WIN) |
239 #pragma warning(push) | 239 #pragma warning(push) |
240 #pragma warning(disable:4624) | 240 #pragma warning(disable:4624) |
241 #endif | 241 #endif |
242 struct Base : public T, public BaseMixin { | 242 struct Base : public T, public BaseMixin { |
243 }; | 243 }; |
244 #if defined(OS_WIN) | 244 #if defined(OS_WIN) |
245 #pragma warning(pop) | 245 #pragma warning(pop) |
246 #endif | 246 #endif |
247 | 247 |
248 template <void(BaseMixin::*)(void)> struct Helper {}; | 248 template <void(BaseMixin::*)()> struct Helper {}; |
249 | 249 |
250 template <typename C> | 250 template <typename C> |
251 static No& Check(Helper<&C::AddRef>*); | 251 static No& Check(Helper<&C::AddRef>*); |
252 | 252 |
253 template <typename > | 253 template <typename > |
254 static Yes& Check(...); | 254 static Yes& Check(...); |
255 | 255 |
256 public: | 256 public: |
257 enum { value = sizeof(Check<Base>(0)) == sizeof(Yes) }; | 257 enum { value = sizeof(Check<Base>(0)) == sizeof(Yes) }; |
258 }; | 258 }; |
(...skipping 13 matching lines...) Expand all Loading... |
272 struct UnsafeBindtoRefCountedArg : false_type { | 272 struct UnsafeBindtoRefCountedArg : false_type { |
273 }; | 273 }; |
274 | 274 |
275 template <typename T> | 275 template <typename T> |
276 struct UnsafeBindtoRefCountedArg<T*> | 276 struct UnsafeBindtoRefCountedArg<T*> |
277 : UnsafeBindtoRefCountedArgHelper<is_class<T>::value, T> { | 277 : UnsafeBindtoRefCountedArgHelper<is_class<T>::value, T> { |
278 }; | 278 }; |
279 | 279 |
280 template <typename T> | 280 template <typename T> |
281 class HasIsMethodTag { | 281 class HasIsMethodTag { |
282 typedef char Yes[1]; | 282 using Yes = char[1]; |
283 typedef char No[2]; | 283 using No = char[2]; |
284 | 284 |
285 template <typename U> | 285 template <typename U> |
286 static Yes& Check(typename U::IsMethod*); | 286 static Yes& Check(typename U::IsMethod*); |
287 | 287 |
288 template <typename U> | 288 template <typename U> |
289 static No& Check(...); | 289 static No& Check(...); |
290 | 290 |
291 public: | 291 public: |
292 enum { value = sizeof(Check<T>(0)) == sizeof(Yes) }; | 292 enum { value = sizeof(Check<T>(0)) == sizeof(Yes) }; |
293 }; | 293 }; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 } | 383 } |
384 | 384 |
385 private: | 385 private: |
386 mutable bool is_valid_; | 386 mutable bool is_valid_; |
387 mutable T scoper_; | 387 mutable T scoper_; |
388 }; | 388 }; |
389 | 389 |
390 // Unwrap the stored parameters for the wrappers above. | 390 // Unwrap the stored parameters for the wrappers above. |
391 template <typename T> | 391 template <typename T> |
392 struct UnwrapTraits { | 392 struct UnwrapTraits { |
393 typedef const T& ForwardType; | 393 using ForwardType = const T&; |
394 static ForwardType Unwrap(const T& o) { return o; } | 394 static ForwardType Unwrap(const T& o) { return o; } |
395 }; | 395 }; |
396 | 396 |
397 template <typename T> | 397 template <typename T> |
398 struct UnwrapTraits<UnretainedWrapper<T> > { | 398 struct UnwrapTraits<UnretainedWrapper<T> > { |
399 typedef T* ForwardType; | 399 using ForwardType = T*; |
400 static ForwardType Unwrap(UnretainedWrapper<T> unretained) { | 400 static ForwardType Unwrap(UnretainedWrapper<T> unretained) { |
401 return unretained.get(); | 401 return unretained.get(); |
402 } | 402 } |
403 }; | 403 }; |
404 | 404 |
405 template <typename T> | 405 template <typename T> |
406 struct UnwrapTraits<ConstRefWrapper<T> > { | 406 struct UnwrapTraits<ConstRefWrapper<T> > { |
407 typedef const T& ForwardType; | 407 using ForwardType = const T&; |
408 static ForwardType Unwrap(ConstRefWrapper<T> const_ref) { | 408 static ForwardType Unwrap(ConstRefWrapper<T> const_ref) { |
409 return const_ref.get(); | 409 return const_ref.get(); |
410 } | 410 } |
411 }; | 411 }; |
412 | 412 |
413 template <typename T> | 413 template <typename T> |
414 struct UnwrapTraits<scoped_refptr<T> > { | 414 struct UnwrapTraits<scoped_refptr<T> > { |
415 typedef T* ForwardType; | 415 using ForwardType = T*; |
416 static ForwardType Unwrap(const scoped_refptr<T>& o) { return o.get(); } | 416 static ForwardType Unwrap(const scoped_refptr<T>& o) { return o.get(); } |
417 }; | 417 }; |
418 | 418 |
419 template <typename T> | 419 template <typename T> |
420 struct UnwrapTraits<WeakPtr<T> > { | 420 struct UnwrapTraits<WeakPtr<T> > { |
421 typedef const WeakPtr<T>& ForwardType; | 421 using ForwardType = const WeakPtr<T>&; |
422 static ForwardType Unwrap(const WeakPtr<T>& o) { return o; } | 422 static ForwardType Unwrap(const WeakPtr<T>& o) { return o; } |
423 }; | 423 }; |
424 | 424 |
425 template <typename T> | 425 template <typename T> |
426 struct UnwrapTraits<OwnedWrapper<T> > { | 426 struct UnwrapTraits<OwnedWrapper<T> > { |
427 typedef T* ForwardType; | 427 using ForwardType = T*; |
428 static ForwardType Unwrap(const OwnedWrapper<T>& o) { | 428 static ForwardType Unwrap(const OwnedWrapper<T>& o) { |
429 return o.get(); | 429 return o.get(); |
430 } | 430 } |
431 }; | 431 }; |
432 | 432 |
433 template <typename T> | 433 template <typename T> |
434 struct UnwrapTraits<PassedWrapper<T> > { | 434 struct UnwrapTraits<PassedWrapper<T> > { |
435 typedef T ForwardType; | 435 using ForwardType = T; |
436 static T Unwrap(PassedWrapper<T>& o) { | 436 static T Unwrap(PassedWrapper<T>& o) { |
437 return o.Pass(); | 437 return o.Pass(); |
438 } | 438 } |
439 }; | 439 }; |
440 | 440 |
441 // Utility for handling different refcounting semantics in the Bind() | 441 // Utility for handling different refcounting semantics in the Bind() |
442 // function. | 442 // function. |
443 template <bool is_method, typename... T> | 443 template <bool is_method, typename... T> |
444 struct MaybeScopedRefPtr; | 444 struct MaybeScopedRefPtr; |
445 | 445 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 template <size_t n, typename List> | 508 template <size_t n, typename List> |
509 struct DropTypeListItemImpl; | 509 struct DropTypeListItemImpl; |
510 | 510 |
511 // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. | 511 // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. |
512 template <size_t n, typename T, typename... List> | 512 template <size_t n, typename T, typename... List> |
513 struct DropTypeListItemImpl<n, TypeList<T, List...>> | 513 struct DropTypeListItemImpl<n, TypeList<T, List...>> |
514 : DropTypeListItemImpl<n - 1, TypeList<List...>> {}; | 514 : DropTypeListItemImpl<n - 1, TypeList<List...>> {}; |
515 | 515 |
516 template <typename T, typename... List> | 516 template <typename T, typename... List> |
517 struct DropTypeListItemImpl<0, TypeList<T, List...>> { | 517 struct DropTypeListItemImpl<0, TypeList<T, List...>> { |
518 typedef TypeList<T, List...> Type; | 518 using Type = TypeList<T, List...>; |
519 }; | 519 }; |
520 | 520 |
521 template <> | 521 template <> |
522 struct DropTypeListItemImpl<0, TypeList<>> { | 522 struct DropTypeListItemImpl<0, TypeList<>> { |
523 typedef TypeList<> Type; | 523 using Type = TypeList<>; |
524 }; | 524 }; |
525 | 525 |
526 // A type-level function that drops |n| list item from given TypeList. | 526 // A type-level function that drops |n| list item from given TypeList. |
527 template <size_t n, typename List> | 527 template <size_t n, typename List> |
528 using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type; | 528 using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type; |
529 | 529 |
530 // Used for TakeTypeListItem implementation. | 530 // Used for TakeTypeListItem implementation. |
531 template <size_t n, typename List, typename... Accum> | 531 template <size_t n, typename List, typename... Accum> |
532 struct TakeTypeListItemImpl; | 532 struct TakeTypeListItemImpl; |
533 | 533 |
(...skipping 17 matching lines...) Expand all Loading... |
551 // TypeList<A, B, C>. | 551 // TypeList<A, B, C>. |
552 template <size_t n, typename List> | 552 template <size_t n, typename List> |
553 using TakeTypeListItem = typename TakeTypeListItemImpl<n, List>::Type; | 553 using TakeTypeListItem = typename TakeTypeListItemImpl<n, List>::Type; |
554 | 554 |
555 // Used for ConcatTypeLists implementation. | 555 // Used for ConcatTypeLists implementation. |
556 template <typename List1, typename List2> | 556 template <typename List1, typename List2> |
557 struct ConcatTypeListsImpl; | 557 struct ConcatTypeListsImpl; |
558 | 558 |
559 template <typename... Types1, typename... Types2> | 559 template <typename... Types1, typename... Types2> |
560 struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> { | 560 struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> { |
561 typedef TypeList<Types1..., Types2...> Type; | 561 using Type = TypeList<Types1..., Types2...>; |
562 }; | 562 }; |
563 | 563 |
564 // A type-level function that concats two TypeLists. | 564 // A type-level function that concats two TypeLists. |
565 template <typename List1, typename List2> | 565 template <typename List1, typename List2> |
566 using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type; | 566 using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type; |
567 | 567 |
568 // Used for MakeFunctionType implementation. | 568 // Used for MakeFunctionType implementation. |
569 template <typename R, typename ArgList> | 569 template <typename R, typename ArgList> |
570 struct MakeFunctionTypeImpl; | 570 struct MakeFunctionTypeImpl; |
571 | 571 |
572 template <typename R, typename... Args> | 572 template <typename R, typename... Args> |
573 struct MakeFunctionTypeImpl<R, TypeList<Args...>> { | 573 struct MakeFunctionTypeImpl<R, TypeList<Args...>> { |
574 typedef R(Type)(Args...); | 574 // MSVC 2013 doesn't support Type Alias of function types. |
| 575 // Revisit this after we update it to newer version. |
| 576 typedef R Type(Args...); |
575 }; | 577 }; |
576 | 578 |
577 // A type-level function that constructs a function type that has |R| as its | 579 // A type-level function that constructs a function type that has |R| as its |
578 // return type and has TypeLists items as its arguments. | 580 // return type and has TypeLists items as its arguments. |
579 template <typename R, typename ArgList> | 581 template <typename R, typename ArgList> |
580 using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type; | 582 using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type; |
581 | 583 |
582 // Used for ExtractArgs. | 584 // Used for ExtractArgs. |
583 template <typename Signature> | 585 template <typename Signature> |
584 struct ExtractArgsImpl; | 586 struct ExtractArgsImpl; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 BASE_EXPORT void DoNothing(); | 647 BASE_EXPORT void DoNothing(); |
646 | 648 |
647 template<typename T> | 649 template<typename T> |
648 void DeletePointer(T* obj) { | 650 void DeletePointer(T* obj) { |
649 delete obj; | 651 delete obj; |
650 } | 652 } |
651 | 653 |
652 } // namespace base | 654 } // namespace base |
653 | 655 |
654 #endif // BASE_BIND_HELPERS_H_ | 656 #endif // BASE_BIND_HELPERS_H_ |
OLD | NEW |