Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_CALLBACK_H_
      6 #define BASE_CALLBACK_H_
      7 
      8 #include "base/callback_forward.h"
      9 #include "base/callback_internal.h"
     10 
     11 // NOTE: Header files that do not require the full definition of Callback or
     12 // Closure should #include "base/callback_forward.h" instead of this file.
     13 
     14 // -----------------------------------------------------------------------------
     15 // Usage documentation
     16 // -----------------------------------------------------------------------------
     17 //
     18 // See //docs/callback.md for documentation.
     19 
     20 namespace base {
     21 
     22 namespace internal {
     23 
     24 template <typename From, typename To>
     25 struct IsCallbackConvertible : std::false_type {};
     26 
     27 template <typename Signature>
     28 struct IsCallbackConvertible<RepeatingCallback<Signature>,
     29                              OnceCallback<Signature>> : std::true_type {};
     30 
     31 }  // namespace internal
     32 
     33 template <typename R,
     34           typename... Args,
     35           internal::CopyMode copy_mode,
     36           internal::RepeatMode repeat_mode>
     37 class Callback<R(Args...), copy_mode, repeat_mode>
     38     : public internal::CallbackBase<copy_mode> {
     39  public:
     40   static_assert(repeat_mode != internal::RepeatMode::Once ||
     41                 copy_mode == internal::CopyMode::MoveOnly,
     42                 "OnceCallback must be MoveOnly.");
     43 
     44   using RunType = R(Args...);
     45   using PolymorphicInvoke = R (*)(internal::BindStateBase*, Args&&...);
     46 
     47   Callback() : internal::CallbackBase<copy_mode>(nullptr) {}
     48 
     49   explicit Callback(internal::BindStateBase* bind_state)
     50       : internal::CallbackBase<copy_mode>(bind_state) {
     51   }
     52 
     53   template <typename OtherCallback,
     54             typename = typename std::enable_if<
     55                 internal::IsCallbackConvertible<OtherCallback, Callback>::value
     56             >::type>
     57   Callback(OtherCallback other)
     58       : internal::CallbackBase<copy_mode>(std::move(other)) {}
     59 
     60   template <typename OtherCallback,
     61             typename = typename std::enable_if<
     62                 internal::IsCallbackConvertible<OtherCallback, Callback>::value
     63             >::type>
     64   Callback& operator=(OtherCallback other) {
     65     static_cast<internal::CallbackBase<copy_mode>&>(*this) = std::move(other);
     66     return *this;
     67   }
     68 
     69   bool Equals(const Callback& other) const {
     70     return this->EqualsInternal(other);
     71   }
     72 
     73   R Run(Args... args) const & {
     74     static_assert(repeat_mode == internal::RepeatMode::Repeating,
     75                   "OnceCallback::Run() may only be invoked on a non-const "
     76                   "rvalue, i.e. std::move(callback).Run().");
     77 
     78     PolymorphicInvoke f =
     79         reinterpret_cast<PolymorphicInvoke>(this->polymorphic_invoke());
     80     return f(this->bind_state_.get(), std::forward<Args>(args)...);
     81   }
     82 
     83   R Run(Args... args) && {
     84     // Move the callback instance into a local variable before the invocation,
     85     // that ensures the internal state is cleared after the invocation.
     86     // It's not safe to touch |this| after the invocation, since running the
     87     // bound function may destroy |this|.
     88     Callback cb = std::move(*this);
     89     PolymorphicInvoke f =
     90         reinterpret_cast<PolymorphicInvoke>(cb.polymorphic_invoke());
     91     return f(cb.bind_state_.get(), std::forward<Args>(args)...);
     92   }
     93 };
     94 
     95 }  // namespace base
     96 
     97 #endif  // BASE_CALLBACK_H_
     98