Index: base/callback.h |
diff --git a/base/callback.h b/base/callback.h |
index 9bb0c0f6679dbd09d1e2cfcdd1d38ac85ec8f287..c91e1a88d3811d7d6bcb76c266143beeddf70651 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 |