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