[email protected] | b38d357 | 2011-02-15 01:27:38 | [diff] [blame] | 1 | // Copyright (c) 2011 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_BIND_H_ |
| 6 | #define BASE_BIND_H_ |
[email protected] | b38d357 | 2011-02-15 01:27:38 | [diff] [blame] | 7 | |
| 8 | #include "base/bind_internal.h" |
[email protected] | b38d357 | 2011-02-15 01:27:38 | [diff] [blame] | 9 | |
[email protected] | 2429264 | 2012-07-12 20:06:40 | [diff] [blame] | 10 | // ----------------------------------------------------------------------------- |
| 11 | // Usage documentation |
| 12 | // ----------------------------------------------------------------------------- |
[email protected] | b38d357 | 2011-02-15 01:27:38 | [diff] [blame] | 13 | // |
tzik | 703f156 | 2016-09-02 07:36:55 | [diff] [blame] | 14 | // See //docs/callback.md for documentation. |
[email protected] | 2429264 | 2012-07-12 20:06:40 | [diff] [blame] | 15 | // |
| 16 | // |
| 17 | // ----------------------------------------------------------------------------- |
| 18 | // Implementation notes |
| 19 | // ----------------------------------------------------------------------------- |
| 20 | // |
| 21 | // If you're reading the implementation, before proceeding further, you should |
| 22 | // read the top comment of base/bind_internal.h for a definition of common |
| 23 | // terms and concepts. |
[email protected] | b38d357 | 2011-02-15 01:27:38 | [diff] [blame] | 24 | |
| 25 | namespace base { |
| 26 | |
tzik | 27d1e31 | 2016-09-13 05:28:59 | [diff] [blame] | 27 | // Bind as OnceCallback. |
tzik | 401dd367 | 2014-11-26 07:54:58 | [diff] [blame] | 28 | template <typename Functor, typename... Args> |
tzik | 27d1e31 | 2016-09-13 05:28:59 | [diff] [blame] | 29 | inline OnceCallback<MakeUnboundRunType<Functor, Args...>> |
| 30 | BindOnce(Functor&& functor, Args&&... args) { |
tzik | 99de02b | 2016-07-01 05:54:12 | [diff] [blame] | 31 | using BindState = internal::MakeBindStateType<Functor, Args...>; |
tzik | caf1d84b | 2016-06-28 12:22:21 | [diff] [blame] | 32 | using UnboundRunType = MakeUnboundRunType<Functor, Args...>; |
tzik | caf1d84b | 2016-06-28 12:22:21 | [diff] [blame] | 33 | using Invoker = internal::Invoker<BindState, UnboundRunType>; |
tzik | 27d1e31 | 2016-09-13 05:28:59 | [diff] [blame] | 34 | using CallbackType = OnceCallback<UnboundRunType>; |
| 35 | |
| 36 | // Store the invoke func into PolymorphicInvoke before casting it to |
| 37 | // InvokeFuncStorage, so that we can ensure its type matches to |
| 38 | // PolymorphicInvoke, to which CallbackType will cast back. |
| 39 | using PolymorphicInvoke = typename CallbackType::PolymorphicInvoke; |
| 40 | PolymorphicInvoke invoke_func = &Invoker::RunOnce; |
| 41 | |
| 42 | using InvokeFuncStorage = internal::BindStateBase::InvokeFuncStorage; |
| 43 | return CallbackType(new BindState( |
| 44 | reinterpret_cast<InvokeFuncStorage>(invoke_func), |
| 45 | std::forward<Functor>(functor), |
| 46 | std::forward<Args>(args)...)); |
| 47 | } |
| 48 | |
| 49 | // Bind as RepeatingCallback. |
| 50 | template <typename Functor, typename... Args> |
| 51 | inline RepeatingCallback<MakeUnboundRunType<Functor, Args...>> |
| 52 | BindRepeating(Functor&& functor, Args&&... args) { |
| 53 | using BindState = internal::MakeBindStateType<Functor, Args...>; |
| 54 | using UnboundRunType = MakeUnboundRunType<Functor, Args...>; |
| 55 | using Invoker = internal::Invoker<BindState, UnboundRunType>; |
| 56 | using CallbackType = RepeatingCallback<UnboundRunType>; |
tzik | 1886c27 | 2016-09-08 05:45:38 | [diff] [blame] | 57 | |
| 58 | // Store the invoke func into PolymorphicInvoke before casting it to |
| 59 | // InvokeFuncStorage, so that we can ensure its type matches to |
| 60 | // PolymorphicInvoke, to which CallbackType will cast back. |
| 61 | using PolymorphicInvoke = typename CallbackType::PolymorphicInvoke; |
| 62 | PolymorphicInvoke invoke_func = &Invoker::Run; |
| 63 | |
| 64 | using InvokeFuncStorage = internal::BindStateBase::InvokeFuncStorage; |
| 65 | return CallbackType(new BindState( |
| 66 | reinterpret_cast<InvokeFuncStorage>(invoke_func), |
| 67 | std::forward<Functor>(functor), |
| 68 | std::forward<Args>(args)...)); |
[email protected] | fccef155 | 2011-11-28 22:13:54 | [diff] [blame] | 69 | } |
| 70 | |
tzik | 27d1e31 | 2016-09-13 05:28:59 | [diff] [blame] | 71 | // Unannotated Bind. |
| 72 | // TODO(tzik): Deprecate this and migrate to OnceCallback and |
| 73 | // RepeatingCallback, once they get ready. |
| 74 | template <typename Functor, typename... Args> |
| 75 | inline Callback<MakeUnboundRunType<Functor, Args...>> |
| 76 | Bind(Functor&& functor, Args&&... args) { |
tzik | 07dbcfd | 2016-10-12 08:49:03 | [diff] [blame] | 77 | return BindRepeating(std::forward<Functor>(functor), |
| 78 | std::forward<Args>(args)...); |
tzik | 27d1e31 | 2016-09-13 05:28:59 | [diff] [blame] | 79 | } |
| 80 | |
[email protected] | b38d357 | 2011-02-15 01:27:38 | [diff] [blame] | 81 | } // namespace base |
| 82 | |
| 83 | #endif // BASE_BIND_H_ |