Chromium Code Reviews| Index: base/callback.h | 
| diff --git a/base/callback.h b/base/callback.h | 
| index c6b8ca3c448a92fbcf0be7d083f63e3aa852aec5..8f2f2503fb12c26c39c5c5dd08d7f4ea60b856dd 100644 | 
| --- a/base/callback.h | 
| +++ b/base/callback.h | 
| @@ -21,6 +21,12 @@ 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> | 
| @@ -28,14 +34,19 @@ class RunMixin; | 
| // Specialization for OnceCallback. | 
| template <typename R, typename... Args> | 
| -class RunMixin<Callback<R(Args...), CopyMode::MoveOnly, RepeatMode::Once>> { | 
| +class RunMixin<OnceCallback<R(Args...)>> { | 
| private: | 
| - using CallbackType = | 
| - Callback<R(Args...), CopyMode::MoveOnly, RepeatMode::Once>; | 
| + using CallbackType = OnceCallback<R(Args...)>; | 
| public: | 
| using PolymorphicInvoke = R(*)(internal::BindStateBase*, Args&&...); | 
| + R Run(Args... args) & { | 
| 
 
dcheng
2016/11/19 08:07:59
All overloads must either use ref-qualifiers or no
 
 | 
| + static_assert(!IsOnceCallback<CallbackType>::value, | 
| 
 
dcheng
2016/11/19 08:07:59
This feels a bit silly, but we need to make sure t
 
vmpstr
2016/11/21 20:00:40
14.7.1 of the standard is so dense that I don't un
 
dcheng
2016/11/22 01:48:28
Added a language lawyering explanation; hopefully
 
 | 
| + "OnceCallback::Run() may only be invoked on an 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. | 
| @@ -49,10 +60,10 @@ class RunMixin<Callback<R(Args...), CopyMode::MoveOnly, RepeatMode::Once>> { | 
| }; | 
| // Specialization for RepeatingCallback. | 
| -template <typename R, typename... Args, CopyMode copy_mode> | 
| -class RunMixin<Callback<R(Args...), copy_mode, RepeatMode::Repeating>> { | 
| +template <typename R, typename... Args> | 
| +class RunMixin<RepeatingCallback<R(Args...)>> { | 
| private: | 
| - using CallbackType = Callback<R(Args...), copy_mode, RepeatMode::Repeating>; | 
| + using CallbackType = RepeatingCallback<R(Args...)>; | 
| public: | 
| using PolymorphicInvoke = R(*)(internal::BindStateBase*, Args&&...); | 
| @@ -69,10 +80,8 @@ template <typename From, typename To> | 
| struct IsCallbackConvertible : std::false_type {}; | 
| template <typename Signature> | 
| -struct IsCallbackConvertible< | 
| - Callback<Signature, CopyMode::Copyable, RepeatMode::Repeating>, | 
| - Callback<Signature, CopyMode::MoveOnly, RepeatMode::Once>> : std::true_type { | 
| -}; | 
| +struct IsCallbackConvertible<RepeatingCallback<Signature>, | 
| + OnceCallback<Signature>> : std::true_type {}; | 
| } // namespace internal |