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