diff options
author | Jakub Pawlowski <jpawlowski@google.com> | 2017-03-14 10:55:53 -0700 |
---|---|---|
committer | Jakub Pawlowski <jpawlowski@google.com> | 2017-12-19 07:47:37 -0800 |
commit | bf8c17f71511c1e90cd8cccfe71f0852c566bd3b (patch) | |
tree | b5603968c3907c8b41594f2a2b0f15475406f94d /base/callback.h | |
parent | 9b3f4a254c327005c91c1eb094062cdefe5f0553 (diff) | |
download | libchrome-bf8c17f71511c1e90cd8cccfe71f0852c566bd3b.tar.gz |
Uprev the library to r462023 from Chromium
This merge was done against r462023 which corresponds to git commit
32eb7c31af9cab6231f0d3d05206072079177605 from Apr 05, 2017
Change-Id: I70bf77fcb3215da3e17f997752bfdad7d4e6e1c9
Diffstat (limited to 'base/callback.h')
-rw-r--r-- | base/callback.h | 90 |
1 files changed, 22 insertions, 68 deletions
diff --git a/base/callback.h b/base/callback.h index 40bd5208a8..c91e1a88d3 100644 --- a/base/callback.h +++ b/base/callback.h @@ -21,71 +21,6 @@ namespace base { namespace internal { -template <typename CallbackType> -struct IsOnceCallback : std::false_type {}; - -template <typename Signature> -struct IsOnceCallback<OnceCallback<Signature>> : std::true_type {}; - -// RunMixin provides different variants of `Run()` function to `Callback<>` -// based on the type of callback. -template <typename CallbackType> -class RunMixin; - -// Specialization for OnceCallback. -template <typename R, typename... Args> -class RunMixin<OnceCallback<R(Args...)>> { - private: - using CallbackType = OnceCallback<R(Args...)>; - - public: - using PolymorphicInvoke = R(*)(internal::BindStateBase*, Args&&...); - - R Run(Args... /* args */) const & { - // Note: even though this static_assert will trivially always fail, it - // cannot be simply replaced with static_assert(false, ...) because: - // - Per [dcl.dcl]/p4, a program is ill-formed if the constant-expression - // argument does not evaluate to true. - // - Per [temp.res]/p8, if no valid specialization can be generated for a - // template definition, and that template is not instantiated, the - // template definition is ill-formed, no diagnostic required. - // These two clauses, taken together, would allow a conforming C++ compiler - // to immediately reject static_assert(false, ...), even inside an - // uninstantiated template. - static_assert(!IsOnceCallback<CallbackType>::value, - "OnceCallback::Run() may only be invoked on a non-const " - "rvalue, i.e. std::move(callback).Run()."); - } - - R Run(Args... args) && { - // Move the callback instance into a local variable before the invocation, - // that ensures the internal state is cleared after the invocation. - // It's not safe to touch |this| after the invocation, since running the - // bound function may destroy |this|. - CallbackType cb = static_cast<CallbackType&&>(*this); - PolymorphicInvoke f = - reinterpret_cast<PolymorphicInvoke>(cb.polymorphic_invoke()); - return f(cb.bind_state_.get(), std::forward<Args>(args)...); - } -}; - -// Specialization for RepeatingCallback. -template <typename R, typename... Args> -class RunMixin<RepeatingCallback<R(Args...)>> { - private: - using CallbackType = RepeatingCallback<R(Args...)>; - - public: - using PolymorphicInvoke = R(*)(internal::BindStateBase*, Args&&...); - - R Run(Args... args) const { - const CallbackType& cb = static_cast<const CallbackType&>(*this); - PolymorphicInvoke f = - reinterpret_cast<PolymorphicInvoke>(cb.polymorphic_invoke()); - return f(cb.bind_state_.get(), std::forward<Args>(args)...); - } -}; - template <typename From, typename To> struct IsCallbackConvertible : std::false_type {}; @@ -100,14 +35,14 @@ template <typename R, internal::CopyMode copy_mode, internal::RepeatMode repeat_mode> class Callback<R(Args...), copy_mode, repeat_mode> - : public internal::CallbackBase<copy_mode>, - public internal::RunMixin<Callback<R(Args...), copy_mode, repeat_mode>> { + : public internal::CallbackBase<copy_mode> { public: static_assert(repeat_mode != internal::RepeatMode::Once || copy_mode == internal::CopyMode::MoveOnly, "OnceCallback must be MoveOnly."); using RunType = R(Args...); + using PolymorphicInvoke = R (*)(internal::BindStateBase*, Args&&...); Callback() : internal::CallbackBase<copy_mode>(nullptr) {} @@ -135,7 +70,26 @@ class Callback<R(Args...), copy_mode, repeat_mode> return this->EqualsInternal(other); } - friend class internal::RunMixin<Callback>; + R Run(Args... args) const & { + static_assert(repeat_mode == internal::RepeatMode::Repeating, + "OnceCallback::Run() may only be invoked on a non-const " + "rvalue, i.e. std::move(callback).Run()."); + + PolymorphicInvoke f = + reinterpret_cast<PolymorphicInvoke>(this->polymorphic_invoke()); + return f(this->bind_state_.get(), std::forward<Args>(args)...); + } + + R Run(Args... args) && { + // Move the callback instance into a local variable before the invocation, + // that ensures the internal state is cleared after the invocation. + // It's not safe to touch |this| after the invocation, since running the + // bound function may destroy |this|. + Callback cb = std::move(*this); + PolymorphicInvoke f = + reinterpret_cast<PolymorphicInvoke>(cb.polymorphic_invoke()); + return f(cb.bind_state_.get(), std::forward<Args>(args)...); + } }; } // namespace base |