forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
callback.h
221 lines (195 loc) · 8.93 KB
/
callback.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// NOTE: Header files that do not require the full definition of
// base::{Once,Repeating}Callback or base::{Once,Repeating}Closure should
// #include "base/callback_forward.h" instead of this file.
#ifndef BASE_CALLBACK_H_
#define BASE_CALLBACK_H_
#include <stddef.h>
#include "base/bind.h"
#include "base/callback_forward.h"
#include "base/callback_internal.h"
#include "base/notreached.h"
// -----------------------------------------------------------------------------
// Usage documentation
// -----------------------------------------------------------------------------
//
// Overview:
// A callback is similar in concept to a function pointer: it wraps a runnable
// object such as a function, method, lambda, or even another callback, allowing
// the runnable object to be invoked later via the callback object.
//
// Unlike function pointers, callbacks are created with base::BindOnce() or
// base::BindRepeating() and support partial function application.
//
// A base::OnceCallback may be Run() at most once; a base::RepeatingCallback may
// be Run() any number of times. |is_null()| is guaranteed to return true for a
// moved-from callback.
//
// // The lambda takes two arguments, but the first argument |x| is bound at
// // callback creation.
// base::OnceCallback<int(int)> cb = base::BindOnce([] (int x, int y) {
// return x + y;
// }, 1);
// // Run() only needs the remaining unbound argument |y|.
// printf("1 + 2 = %d\n", std::move(cb).Run(2)); // Prints 3
// printf("cb is null? %s\n",
// cb.is_null() ? "true" : "false"); // Prints true
// std::move(cb).Run(2); // Crashes since |cb| has already run.
//
// Callbacks also support cancellation. A common use is binding the receiver
// object as a WeakPtr<T>. If that weak pointer is invalidated, calling Run()
// will be a no-op. Note that |IsCancelled()| and |is_null()| are distinct:
// simply cancelling a callback will not also make it null.
//
// base::Callback is currently a type alias for base::RepeatingCallback. In the
// future, we expect to flip this to default to base::OnceCallback.
//
// See //docs/callback.md for the full documentation.
namespace base {
template <typename R, typename... Args>
class OnceCallback<R(Args...)> : public internal::CallbackBase {
public:
using ResultType = R;
using RunType = R(Args...);
using PolymorphicInvoke = R (*)(internal::BindStateBase*,
internal::PassingType<Args>...);
constexpr OnceCallback() = default;
OnceCallback(std::nullptr_t) = delete;
explicit OnceCallback(internal::BindStateBase* bind_state)
: internal::CallbackBase(bind_state) {}
OnceCallback(const OnceCallback&) = delete;
OnceCallback& operator=(const OnceCallback&) = delete;
OnceCallback(OnceCallback&&) noexcept = default;
OnceCallback& operator=(OnceCallback&&) noexcept = default;
OnceCallback(RepeatingCallback<RunType> other)
: internal::CallbackBase(std::move(other)) {}
OnceCallback& operator=(RepeatingCallback<RunType> other) {
static_cast<internal::CallbackBase&>(*this) = std::move(other);
return *this;
}
R Run(Args... args) const & {
static_assert(!sizeof(*this),
"OnceCallback::Run() may only be invoked on a non-const "
"rvalue, i.e. std::move(callback).Run().");
NOTREACHED();
}
R Run(Args... args) && {
// Move the callback instance into a local variable before the invocation,
// that ensures the internal state is cleared after the invocation.
// It's not safe to touch |this| after the invocation, since running the
// bound function may destroy |this|.
OnceCallback cb = std::move(*this);
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(cb.polymorphic_invoke());
return f(cb.bind_state_.get(), std::forward<Args>(args)...);
}
// Then() returns a new OnceCallback that receives the same arguments as
// |this|, and with the return type of |then|. The returned callback will:
// 1) Run the functor currently bound to |this| callback.
// 2) Run the |then| callback with the result from step 1 as its single
// argument.
// 3) Return the value from running the |then| callback.
//
// Since this method generates a callback that is a replacement for `this`,
// `this` will be consumed and reset to a null callback to ensure the
// originally-bound functor can be run at most once.
template <typename U, typename R2 = internal::ExtractReturnType<U>>
OnceCallback<R2(Args...)> Then(OnceCallback<U> then) && {
using ThenCallbackArgs = internal::ExtractArgs<U>;
static_assert(
(std::is_void<R>::value &&
std::is_same<internal::TypeList<>, ThenCallbackArgs>::value) ||
std::is_same<internal::TypeList<R>, ThenCallbackArgs>::value,
"The |then| callback must accept the return value from the original "
"callback as its only parameter.");
CHECK(then);
return BindOnce(
internal::ThenHelper<OnceCallback, OnceCallback<U>, R, Args...>(),
std::move(*this), std::move(then));
}
};
template <typename R, typename... Args>
class RepeatingCallback<R(Args...)> : public internal::CallbackBaseCopyable {
public:
using ResultType = R;
using RunType = R(Args...);
using PolymorphicInvoke = R (*)(internal::BindStateBase*,
internal::PassingType<Args>...);
constexpr RepeatingCallback() = default;
RepeatingCallback(std::nullptr_t) = delete;
explicit RepeatingCallback(internal::BindStateBase* bind_state)
: internal::CallbackBaseCopyable(bind_state) {}
// Copyable and movable.
RepeatingCallback(const RepeatingCallback&) = default;
RepeatingCallback& operator=(const RepeatingCallback&) = default;
RepeatingCallback(RepeatingCallback&&) noexcept = default;
RepeatingCallback& operator=(RepeatingCallback&&) noexcept = default;
bool operator==(const RepeatingCallback& other) const {
return EqualsInternal(other);
}
bool operator!=(const RepeatingCallback& other) const {
return !operator==(other);
}
R Run(Args... args) const & {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(this->polymorphic_invoke());
return f(this->bind_state_.get(), std::forward<Args>(args)...);
}
R Run(Args... args) && {
// Move the callback instance into a local variable before the invocation,
// that ensures the internal state is cleared after the invocation.
// It's not safe to touch |this| after the invocation, since running the
// bound function may destroy |this|.
RepeatingCallback cb = std::move(*this);
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(cb.polymorphic_invoke());
return f(std::move(cb).bind_state_.get(), std::forward<Args>(args)...);
}
// Then() returns a new RepeatingCallback that receives the same arguments as
// |this|, and with the return type of |then|. The
// returned callback will:
// 1) Run the functor currently bound to |this| callback.
// 2) Run the |then| callback with the result from step 1 as its single
// argument.
// 3) Return the value from running the |then| callback.
//
// If called on an rvalue (e.g. std::move(cb).Then(...)), this method
// generates a callback that is a replacement for `this`. Therefore, `this`
// will be consumed and reset to a null callback to ensure the
// originally-bound functor can be run at most once.
template <typename U, typename R2 = internal::ExtractReturnType<U>>
RepeatingCallback<R2(Args...)> Then(RepeatingCallback<U> then) const& {
using ThenCallbackArgs = internal::ExtractArgs<U>;
static_assert(
(std::is_void<R>::value &&
std::is_same<internal::TypeList<>, ThenCallbackArgs>::value) ||
std::is_same<internal::TypeList<R>, ThenCallbackArgs>::value,
"The |then| callback must accept the return value from the original "
"callback as its only parameter.");
CHECK(then);
return BindRepeating(
internal::ThenHelper<RepeatingCallback, RepeatingCallback<U>, R,
Args...>(),
*this, std::move(then));
}
template <typename U, typename R2 = internal::ExtractReturnType<U>>
RepeatingCallback<R2(Args...)> Then(RepeatingCallback<U> then) && {
using ThenCallbackArgs = internal::ExtractArgs<U>;
static_assert(
(std::is_void<R>::value &&
std::is_same<internal::TypeList<>, ThenCallbackArgs>::value) ||
std::is_same<internal::TypeList<R>, ThenCallbackArgs>::value,
"The |then| callback must accept the return value from the original "
"callback as its only parameter.");
CHECK(then);
return BindRepeating(
internal::ThenHelper<RepeatingCallback, RepeatingCallback<U>, R,
Args...>(),
std::move(*this), std::move(then));
}
};
} // namespace base
#endif // BASE_CALLBACK_H_