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 template <typename R, typename... Args> 23 class OnceCallback<R(Args...)> : public internal::CallbackBase { 24 public: 25 using RunType = R(Args...); 26 using PolymorphicInvoke = R (*)(internal::BindStateBase*, Args&&...); 27 OnceCallback()28 OnceCallback() : internal::CallbackBase(nullptr) {} 29 OnceCallback(internal::BindStateBase * bind_state)30 explicit OnceCallback(internal::BindStateBase* bind_state) 31 : internal::CallbackBase(bind_state) {} 32 33 OnceCallback(const OnceCallback&) = delete; 34 OnceCallback& operator=(const OnceCallback&) = delete; 35 36 OnceCallback(OnceCallback&&) = default; 37 OnceCallback& operator=(OnceCallback&&) = default; 38 OnceCallback(RepeatingCallback<RunType> other)39 OnceCallback(RepeatingCallback<RunType> other) 40 : internal::CallbackBase(std::move(other)) {} 41 42 OnceCallback& operator=(RepeatingCallback<RunType> other) { 43 static_cast<internal::CallbackBase&>(*this) = std::move(other); 44 return *this; 45 } 46 Equals(const OnceCallback & other)47 bool Equals(const OnceCallback& other) const { return EqualsInternal(other); } 48 Run(Args...args)49 R Run(Args... args) const & { 50 static_assert(!sizeof(*this), 51 "OnceCallback::Run() may only be invoked on a non-const " 52 "rvalue, i.e. std::move(callback).Run()."); 53 NOTREACHED(); 54 } 55 Run(Args...args)56 R Run(Args... args) && { 57 // Move the callback instance into a local variable before the invocation, 58 // that ensures the internal state is cleared after the invocation. 59 // It's not safe to touch |this| after the invocation, since running the 60 // bound function may destroy |this|. 61 OnceCallback cb = std::move(*this); 62 PolymorphicInvoke f = 63 reinterpret_cast<PolymorphicInvoke>(cb.polymorphic_invoke()); 64 return f(cb.bind_state_.get(), std::forward<Args>(args)...); 65 } 66 }; 67 68 template <typename R, typename... Args> 69 class RepeatingCallback<R(Args...)> : public internal::CallbackBaseCopyable { 70 public: 71 using RunType = R(Args...); 72 using PolymorphicInvoke = R (*)(internal::BindStateBase*, Args&&...); 73 RepeatingCallback()74 RepeatingCallback() : internal::CallbackBaseCopyable(nullptr) {} 75 RepeatingCallback(internal::BindStateBase * bind_state)76 explicit RepeatingCallback(internal::BindStateBase* bind_state) 77 : internal::CallbackBaseCopyable(bind_state) {} 78 79 // Copyable and movabl. 80 RepeatingCallback(const RepeatingCallback&) = default; 81 RepeatingCallback& operator=(const RepeatingCallback&) = default; 82 RepeatingCallback(RepeatingCallback&&) = default; 83 RepeatingCallback& operator=(RepeatingCallback&&) = default; 84 Equals(const RepeatingCallback & other)85 bool Equals(const RepeatingCallback& other) const { 86 return EqualsInternal(other); 87 } 88 Run(Args...args)89 R Run(Args... args) const & { 90 PolymorphicInvoke f = 91 reinterpret_cast<PolymorphicInvoke>(this->polymorphic_invoke()); 92 return f(this->bind_state_.get(), std::forward<Args>(args)...); 93 } 94 Run(Args...args)95 R Run(Args... args) && { 96 // Move the callback instance into a local variable before the invocation, 97 // that ensures the internal state is cleared after the invocation. 98 // It's not safe to touch |this| after the invocation, since running the 99 // bound function may destroy |this|. 100 RepeatingCallback cb = std::move(*this); 101 PolymorphicInvoke f = 102 reinterpret_cast<PolymorphicInvoke>(cb.polymorphic_invoke()); 103 return f(cb.bind_state_.get(), std::forward<Args>(args)...); 104 } 105 }; 106 107 } // namespace base 108 109 #endif // BASE_CALLBACK_H_ 110