[email protected] | ac4c668 | 2012-01-04 00:57:39 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 2041cf34 | 2010-02-19 03:15:59 | [diff] [blame] | 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 | |
[email protected] | d7f7524 | 2011-12-07 21:44:06 | [diff] [blame] | 8 | #include "base/callback_forward.h" |
[email protected] | 59eff91 | 2011-02-18 23:29:31 | [diff] [blame] | 9 | #include "base/callback_internal.h" |
[email protected] | 2041cf34 | 2010-02-19 03:15:59 | [diff] [blame] | 10 | |
[email protected] | d7f7524 | 2011-12-07 21:44:06 | [diff] [blame] | 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 | |
[email protected] | 2429264 | 2012-07-12 20:06:40 | [diff] [blame] | 14 | // ----------------------------------------------------------------------------- |
tzik | 703f156 | 2016-09-02 07:36:55 | [diff] [blame] | 15 | // Usage documentation |
[email protected] | 2429264 | 2012-07-12 20:06:40 | [diff] [blame] | 16 | // ----------------------------------------------------------------------------- |
[email protected] | 2041cf34 | 2010-02-19 03:15:59 | [diff] [blame] | 17 | // |
tzik | 703f156 | 2016-09-02 07:36:55 | [diff] [blame] | 18 | // See //docs/callback.md for documentation. |
[email protected] | 4346ef91 | 2011-02-19 00:52:15 | [diff] [blame] | 19 | |
tzik | 77d41139 | 2016-03-09 09:47:03 | [diff] [blame] | 20 | namespace base { |
[email protected] | e24f876 | 2011-12-20 00:10:04 | [diff] [blame] | 21 | |
tzik | 27d1e31 | 2016-09-13 05:28:59 | [diff] [blame] | 22 | namespace internal { |
tzik | caf1d84b | 2016-06-28 12:22:21 | [diff] [blame] | 23 | |
tzik | 27d1e31 | 2016-09-13 05:28:59 | [diff] [blame] | 24 | template <typename From, typename To> |
| 25 | struct IsCallbackConvertible : std::false_type {}; |
| 26 | |
| 27 | template <typename Signature> |
dcheng | 77172b9 | 2016-11-22 07:46:06 | [diff] [blame] | 28 | struct IsCallbackConvertible<RepeatingCallback<Signature>, |
| 29 | OnceCallback<Signature>> : std::true_type {}; |
tzik | 27d1e31 | 2016-09-13 05:28:59 | [diff] [blame] | 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> |
tzik | ecb1b24 | 2017-03-21 07:25:54 | [diff] [blame] | 38 | : public internal::CallbackBase<copy_mode> { |
tzik | 27d1e31 | 2016-09-13 05:28:59 | [diff] [blame] | 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...); |
tzik | ecb1b24 | 2017-03-21 07:25:54 | [diff] [blame] | 45 | using PolymorphicInvoke = R (*)(internal::BindStateBase*, Args&&...); |
[email protected] | b38d357 | 2011-02-15 01:27:38 | [diff] [blame] | 46 | |
tzik | 77d41139 | 2016-03-09 09:47:03 | [diff] [blame] | 47 | Callback() : internal::CallbackBase<copy_mode>(nullptr) {} |
[email protected] | b38d357 | 2011-02-15 01:27:38 | [diff] [blame] | 48 | |
tzik | 1886c27 | 2016-09-08 05:45:38 | [diff] [blame] | 49 | explicit Callback(internal::BindStateBase* bind_state) |
tzik | 77d41139 | 2016-03-09 09:47:03 | [diff] [blame] | 50 | : internal::CallbackBase<copy_mode>(bind_state) { |
[email protected] | 2041cf34 | 2010-02-19 03:15:59 | [diff] [blame] | 51 | } |
| 52 | |
Jeremy Roman | 35a31743 | 2017-08-16 22:20:53 | [diff] [blame] | 53 | template < |
| 54 | typename OtherCallback, |
| 55 | typename = std::enable_if_t< |
| 56 | internal::IsCallbackConvertible<OtherCallback, Callback>::value>> |
tzik | 27d1e31 | 2016-09-13 05:28:59 | [diff] [blame] | 57 | Callback(OtherCallback other) |
| 58 | : internal::CallbackBase<copy_mode>(std::move(other)) {} |
| 59 | |
Jeremy Roman | 35a31743 | 2017-08-16 22:20:53 | [diff] [blame] | 60 | template < |
| 61 | typename OtherCallback, |
| 62 | typename = std::enable_if_t< |
| 63 | internal::IsCallbackConvertible<OtherCallback, Callback>::value>> |
tzik | 27d1e31 | 2016-09-13 05:28:59 | [diff] [blame] | 64 | Callback& operator=(OtherCallback other) { |
| 65 | static_cast<internal::CallbackBase<copy_mode>&>(*this) = std::move(other); |
| 66 | return *this; |
| 67 | } |
| 68 | |
[email protected] | 481915a77 | 2011-09-10 03:14:35 | [diff] [blame] | 69 | bool Equals(const Callback& other) const { |
tzik | 77d41139 | 2016-03-09 09:47:03 | [diff] [blame] | 70 | return this->EqualsInternal(other); |
[email protected] | 481915a77 | 2011-09-10 03:14:35 | [diff] [blame] | 71 | } |
| 72 | |
tzik | ecb1b24 | 2017-03-21 07:25:54 | [diff] [blame] | 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 | } |
[email protected] | 2041cf34 | 2010-02-19 03:15:59 | [diff] [blame] | 93 | }; |
| 94 | |
[email protected] | b38d357 | 2011-02-15 01:27:38 | [diff] [blame] | 95 | } // namespace base |
[email protected] | 2041cf34 | 2010-02-19 03:15:59 | [diff] [blame] | 96 | |
tzik | c87149e | 2014-11-20 01:08:20 | [diff] [blame] | 97 | #endif // BASE_CALLBACK_H_ |