| 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 |