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 #ifndef BASE_BIND_INTERNAL_H_ | 5 #ifndef BASE_BIND_INTERNAL_H_ |
6 #define BASE_BIND_INTERNAL_H_ | 6 #define BASE_BIND_INTERNAL_H_ |
7 | 7 |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 | 9 |
10 #include <tuple> | 10 #include <tuple> |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 struct ForceVoidReturn; | 123 struct ForceVoidReturn; |
124 | 124 |
125 template <typename R, typename... Args> | 125 template <typename R, typename... Args> |
126 struct ForceVoidReturn<R(Args...)> { | 126 struct ForceVoidReturn<R(Args...)> { |
127 using RunType = void(Args...); | 127 using RunType = void(Args...); |
128 }; | 128 }; |
129 | 129 |
130 // FunctorTraits<> | 130 // FunctorTraits<> |
131 // | 131 // |
132 // See description at top of file. | 132 // See description at top of file. |
133 template <typename Functor, typename SFINAE = void> | 133 template <typename Functor, typename SFINAE> |
134 struct FunctorTraits; | 134 struct FunctorTraits; |
135 | 135 |
136 // For a callable type that is convertible to the corresponding function type. | 136 // For a callable type that is convertible to the corresponding function type. |
137 // This specialization is intended to allow binding captureless lambdas by | 137 // This specialization is intended to allow binding captureless lambdas by |
138 // base::Bind(), based on the fact that captureless lambdas can be convertible | 138 // base::Bind(), based on the fact that captureless lambdas can be convertible |
139 // to the function type while capturing lambdas can't. | 139 // to the function type while capturing lambdas can't. |
140 template <typename Functor> | 140 template <typename Functor> |
141 struct FunctorTraits< | 141 struct FunctorTraits< |
142 Functor, | 142 Functor, |
143 typename std::enable_if<IsConvertibleToRunType<Functor>::value>::type> { | 143 typename std::enable_if<IsConvertibleToRunType<Functor>::value>::type> { |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 IsNull(const Functor& functor) { | 380 IsNull(const Functor& functor) { |
381 return !functor; | 381 return !functor; |
382 } | 382 } |
383 | 383 |
384 template <typename Functor> | 384 template <typename Functor> |
385 typename std::enable_if<!FunctorTraits<Functor>::is_nullable, bool>::type | 385 typename std::enable_if<!FunctorTraits<Functor>::is_nullable, bool>::type |
386 IsNull(const Functor&) { | 386 IsNull(const Functor&) { |
387 return false; | 387 return false; |
388 } | 388 } |
389 | 389 |
390 template <typename Functor, typename... BoundArgs> | 390 // Used by ApplyCancellationTraits below. |
391 struct BindState; | 391 template <typename Functor, typename BoundArgsTuple, size_t... indices> |
| 392 bool ApplyCancellationTraitsImpl(const Functor& functor, |
| 393 const BoundArgsTuple& bound_args, |
| 394 IndexSequence<indices...>) { |
| 395 return CallbackCancellationTraits<Functor, BoundArgsTuple>::IsCancelled( |
| 396 functor, base::get<indices>(bound_args)...); |
| 397 } |
392 | 398 |
393 template <typename BindStateType, typename SFINAE = void> | 399 // Relays |base| to corresponding CallbackCancellationTraits<>::Run(). Returns |
394 struct CancellationChecker { | 400 // true if the callback |base| represents is canceled. |
395 static constexpr bool is_cancellable = false; | 401 template <typename BindStateType> |
396 static bool Run(const BindStateBase*) { | 402 bool ApplyCancellationTraits(const BindStateBase* base) { |
397 return false; | 403 const BindStateType* storage = static_cast<const BindStateType*>(base); |
398 } | 404 static constexpr size_t num_bound_args = |
399 }; | 405 std::tuple_size<decltype(storage->bound_args_)>::value; |
400 | 406 return ApplyCancellationTraitsImpl(storage->functor_, storage->bound_args_, |
401 template <typename Functor, typename... BoundArgs> | 407 MakeIndexSequence<num_bound_args>()); |
402 struct CancellationChecker< | |
403 BindState<Functor, BoundArgs...>, | |
404 typename std::enable_if<IsWeakMethod<FunctorTraits<Functor>::is_method, | |
405 BoundArgs...>::value>::type> { | |
406 static constexpr bool is_cancellable = true; | |
407 static bool Run(const BindStateBase* base) { | |
408 using BindStateType = BindState<Functor, BoundArgs...>; | |
409 const BindStateType* bind_state = static_cast<const BindStateType*>(base); | |
410 return !base::get<0>(bind_state->bound_args_); | |
411 } | |
412 }; | |
413 | |
414 template <typename Signature, | |
415 typename... BoundArgs, | |
416 CopyMode copy_mode, | |
417 RepeatMode repeat_mode> | |
418 struct CancellationChecker< | |
419 BindState<Callback<Signature, copy_mode, repeat_mode>, BoundArgs...>> { | |
420 static constexpr bool is_cancellable = true; | |
421 static bool Run(const BindStateBase* base) { | |
422 using Functor = Callback<Signature, copy_mode, repeat_mode>; | |
423 using BindStateType = BindState<Functor, BoundArgs...>; | |
424 const BindStateType* bind_state = static_cast<const BindStateType*>(base); | |
425 return bind_state->functor_.IsCancelled(); | |
426 } | |
427 }; | 408 }; |
428 | 409 |
429 // Template helpers to detect using Bind() on a base::Callback without any | 410 // Template helpers to detect using Bind() on a base::Callback without any |
430 // additional arguments. In that case, the original base::Callback object should | 411 // additional arguments. In that case, the original base::Callback object should |
431 // just be directly used. | 412 // just be directly used. |
432 template <typename Functor, typename... BoundArgs> | 413 template <typename Functor, typename... BoundArgs> |
433 struct BindingCallbackWithNoArgs { | 414 struct BindingCallbackWithNoArgs { |
434 static constexpr bool value = false; | 415 static constexpr bool value = false; |
435 }; | 416 }; |
436 | 417 |
437 template <typename Signature, | 418 template <typename Signature, |
438 typename... BoundArgs, | 419 typename... BoundArgs, |
439 CopyMode copy_mode, | 420 CopyMode copy_mode, |
440 RepeatMode repeat_mode> | 421 RepeatMode repeat_mode> |
441 struct BindingCallbackWithNoArgs<Callback<Signature, copy_mode, repeat_mode>, | 422 struct BindingCallbackWithNoArgs<Callback<Signature, copy_mode, repeat_mode>, |
442 BoundArgs...> { | 423 BoundArgs...> { |
443 static constexpr bool value = sizeof...(BoundArgs) == 0; | 424 static constexpr bool value = sizeof...(BoundArgs) == 0; |
444 }; | 425 }; |
445 | 426 |
446 // BindState<> | 427 // BindState<> |
447 // | 428 // |
448 // This stores all the state passed into Bind(). | 429 // This stores all the state passed into Bind(). |
449 template <typename Functor, typename... BoundArgs> | 430 template <typename Functor, typename... BoundArgs> |
450 struct BindState final : BindStateBase { | 431 struct BindState final : BindStateBase { |
451 using IsCancellable = std::integral_constant< | 432 using IsCancellable = std::integral_constant< |
452 bool, CancellationChecker<BindState>::is_cancellable>; | 433 bool, |
| 434 CallbackCancellationTraits<Functor, |
| 435 std::tuple<BoundArgs...>>::is_cancellable>; |
453 | 436 |
454 template <typename ForwardFunctor, typename... ForwardBoundArgs> | 437 template <typename ForwardFunctor, typename... ForwardBoundArgs> |
455 explicit BindState(BindStateBase::InvokeFuncStorage invoke_func, | 438 explicit BindState(BindStateBase::InvokeFuncStorage invoke_func, |
456 ForwardFunctor&& functor, | 439 ForwardFunctor&& functor, |
457 ForwardBoundArgs&&... bound_args) | 440 ForwardBoundArgs&&... bound_args) |
458 // IsCancellable is std::false_type if the CancellationChecker<>::Run | 441 // IsCancellable is std::false_type if |
459 // returns always false. Otherwise, it's std::true_type. | 442 // CallbackCancellationTraits<>::IsCancelled returns always false. |
| 443 // Otherwise, it's std::true_type. |
460 : BindState(IsCancellable{}, | 444 : BindState(IsCancellable{}, |
461 invoke_func, | 445 invoke_func, |
462 std::forward<ForwardFunctor>(functor), | 446 std::forward<ForwardFunctor>(functor), |
463 std::forward<ForwardBoundArgs>(bound_args)...) { | 447 std::forward<ForwardBoundArgs>(bound_args)...) { |
464 static_assert(!BindingCallbackWithNoArgs<Functor, BoundArgs...>::value, | 448 static_assert(!BindingCallbackWithNoArgs<Functor, BoundArgs...>::value, |
465 "Attempting to bind a base::Callback with no additional " | 449 "Attempting to bind a base::Callback with no additional " |
466 "arguments: save a heap allocation and use the original " | 450 "arguments: save a heap allocation and use the original " |
467 "base::Callback object"); | 451 "base::Callback object"); |
468 } | 452 } |
469 | 453 |
470 Functor functor_; | 454 Functor functor_; |
471 std::tuple<BoundArgs...> bound_args_; | 455 std::tuple<BoundArgs...> bound_args_; |
472 | 456 |
473 private: | 457 private: |
474 template <typename ForwardFunctor, typename... ForwardBoundArgs> | 458 template <typename ForwardFunctor, typename... ForwardBoundArgs> |
475 explicit BindState(std::true_type, | 459 explicit BindState(std::true_type, |
476 BindStateBase::InvokeFuncStorage invoke_func, | 460 BindStateBase::InvokeFuncStorage invoke_func, |
477 ForwardFunctor&& functor, | 461 ForwardFunctor&& functor, |
478 ForwardBoundArgs&&... bound_args) | 462 ForwardBoundArgs&&... bound_args) |
479 : BindStateBase(invoke_func, &Destroy, | 463 : BindStateBase(invoke_func, |
480 &CancellationChecker<BindState>::Run), | 464 &Destroy, |
| 465 &ApplyCancellationTraits<BindState>), |
481 functor_(std::forward<ForwardFunctor>(functor)), | 466 functor_(std::forward<ForwardFunctor>(functor)), |
482 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) { | 467 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) { |
483 DCHECK(!IsNull(functor_)); | 468 DCHECK(!IsNull(functor_)); |
484 } | 469 } |
485 | 470 |
486 template <typename ForwardFunctor, typename... ForwardBoundArgs> | 471 template <typename ForwardFunctor, typename... ForwardBoundArgs> |
487 explicit BindState(std::false_type, | 472 explicit BindState(std::false_type, |
488 BindStateBase::InvokeFuncStorage invoke_func, | 473 BindStateBase::InvokeFuncStorage invoke_func, |
489 ForwardFunctor&& functor, | 474 ForwardFunctor&& functor, |
490 ForwardBoundArgs&&... bound_args) | 475 ForwardBoundArgs&&... bound_args) |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 | 534 |
550 // Returns a RunType of bound functor. | 535 // Returns a RunType of bound functor. |
551 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C). | 536 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C). |
552 template <typename Functor, typename... BoundArgs> | 537 template <typename Functor, typename... BoundArgs> |
553 using MakeUnboundRunType = | 538 using MakeUnboundRunType = |
554 typename internal::MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type; | 539 typename internal::MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type; |
555 | 540 |
556 } // namespace base | 541 } // namespace base |
557 | 542 |
558 #endif // BASE_BIND_INTERNAL_H_ | 543 #endif // BASE_BIND_INTERNAL_H_ |
OLD | NEW |