blob: b57a969c355beba16f712c55ab7a0beff047dce9 [file] [log] [blame]
[email protected]b38d3572011-02-15 01:27:381// 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]b38d3572011-02-15 01:27:387
Jeremy Roman84956fa2017-08-16 15:55:208#include <utility>
9
[email protected]b38d3572011-02-15 01:27:3810#include "base/bind_internal.h"
[email protected]b38d3572011-02-15 01:27:3811
[email protected]24292642012-07-12 20:06:4012// -----------------------------------------------------------------------------
13// Usage documentation
14// -----------------------------------------------------------------------------
[email protected]b38d3572011-02-15 01:27:3815//
tzik703f1562016-09-02 07:36:5516// See //docs/callback.md for documentation.
[email protected]24292642012-07-12 20:06:4017//
18//
19// -----------------------------------------------------------------------------
20// Implementation notes
21// -----------------------------------------------------------------------------
22//
23// If you're reading the implementation, before proceeding further, you should
24// read the top comment of base/bind_internal.h for a definition of common
25// terms and concepts.
[email protected]b38d3572011-02-15 01:27:3826
27namespace base {
28
tzikae4202e2017-07-31 10:41:5429namespace internal {
30
31// IsOnceCallback<T> is a std::true_type if |T| is a OnceCallback.
32template <typename T>
33struct IsOnceCallback : std::false_type {};
34
35template <typename Signature>
36struct IsOnceCallback<OnceCallback<Signature>> : std::true_type {};
37
Daniel Chenga09cb602017-08-30 13:46:1938// Helper to assert that parameter |i| of type |Arg| can be bound, which means:
39// - |Arg| can be retained internally as |Storage|.
40// - |Arg| can be forwarded as |Unwrapped| to |Param|.
41template <size_t i,
42 typename Arg,
43 typename Storage,
44 typename Unwrapped,
45 typename Param>
tzikae4202e2017-07-31 10:41:5446struct AssertConstructible {
Daniel Chenga09cb602017-08-30 13:46:1947 private:
48 static constexpr bool param_is_forwardable =
49 std::is_constructible<Param, Unwrapped>::value;
50 // Unlike the check for binding into storage below, the check for
51 // forwardability drops the const qualifier for repeating callbacks. This is
52 // to try to catch instances where std::move()--which forwards as a const
53 // reference with repeating callbacks--is used instead of base::Passed().
54 static_assert(
55 param_is_forwardable ||
56 !std::is_constructible<Param, std::decay_t<Unwrapped>&&>::value,
57 "Bound argument |i| is move-only but will be forwarded by copy. "
58 "Ensure |Arg| is bound using base::Passed(), not std::move().");
59 static_assert(
60 param_is_forwardable,
61 "Bound argument |i| of type |Arg| cannot be forwarded as "
62 "|Unwrapped| to the bound functor, which declares it as |Param|.");
63
64 static constexpr bool arg_is_storable =
65 std::is_constructible<Storage, Arg>::value;
66 static_assert(arg_is_storable ||
67 !std::is_constructible<Storage, std::decay_t<Arg>&&>::value,
68 "Bound argument |i| is move-only but will be bound by copy. "
69 "Ensure |Arg| is mutable and bound using std::move().");
70 static_assert(arg_is_storable,
71 "Bound argument |i| of type |Arg| cannot be converted and "
72 "bound as |Storage|.");
tzikae4202e2017-07-31 10:41:5473};
74
75// Takes three same-length TypeLists, and applies AssertConstructible for each
76// triples.
77template <typename Index,
Daniel Chenga09cb602017-08-30 13:46:1978 typename Args,
tzikae4202e2017-07-31 10:41:5479 typename UnwrappedTypeList,
80 typename ParamsList>
81struct AssertBindArgsValidity;
82
83template <size_t... Ns,
84 typename... Args,
85 typename... Unwrapped,
86 typename... Params>
Jeremy Roman84956fa2017-08-16 15:55:2087struct AssertBindArgsValidity<std::index_sequence<Ns...>,
tzikae4202e2017-07-31 10:41:5488 TypeList<Args...>,
89 TypeList<Unwrapped...>,
90 TypeList<Params...>>
Daniel Chenga09cb602017-08-30 13:46:1991 : AssertConstructible<Ns, Args, std::decay_t<Args>, Unwrapped, Params>... {
tzikae4202e2017-07-31 10:41:5492 static constexpr bool ok = true;
93};
94
95// The implementation of TransformToUnwrappedType below.
tzikd4bb5b7d2017-08-28 19:08:5296template <bool is_once, typename T>
tzikae4202e2017-07-31 10:41:5497struct TransformToUnwrappedTypeImpl;
98
99template <typename T>
tzikd4bb5b7d2017-08-28 19:08:52100struct TransformToUnwrappedTypeImpl<true, T> {
Jeremy Roman35a317432017-08-16 22:20:53101 using StoredType = std::decay_t<T>;
tzikae4202e2017-07-31 10:41:54102 using ForwardType = StoredType&&;
103 using Unwrapped = decltype(Unwrap(std::declval<ForwardType>()));
104};
105
106template <typename T>
tzikd4bb5b7d2017-08-28 19:08:52107struct TransformToUnwrappedTypeImpl<false, T> {
Jeremy Roman35a317432017-08-16 22:20:53108 using StoredType = std::decay_t<T>;
tzikae4202e2017-07-31 10:41:54109 using ForwardType = const StoredType&;
110 using Unwrapped = decltype(Unwrap(std::declval<ForwardType>()));
111};
112
113// Transform |T| into `Unwrapped` type, which is passed to the target function.
114// Example:
tzikd4bb5b7d2017-08-28 19:08:52115// In is_once == true case,
tzikae4202e2017-07-31 10:41:54116// `int&&` -> `int&&`,
117// `const int&` -> `int&&`,
118// `OwnedWrapper<int>&` -> `int*&&`.
tzikd4bb5b7d2017-08-28 19:08:52119// In is_once == false case,
tzikae4202e2017-07-31 10:41:54120// `int&&` -> `const int&`,
121// `const int&` -> `const int&`,
122// `OwnedWrapper<int>&` -> `int* const &`.
tzikd4bb5b7d2017-08-28 19:08:52123template <bool is_once, typename T>
tzikae4202e2017-07-31 10:41:54124using TransformToUnwrappedType =
tzikd4bb5b7d2017-08-28 19:08:52125 typename TransformToUnwrappedTypeImpl<is_once, T>::Unwrapped;
tzikae4202e2017-07-31 10:41:54126
127// Transforms |Args| into `Unwrapped` types, and packs them into a TypeList.
128// If |is_method| is true, tries to dereference the first argument to support
129// smart pointers.
tzikd4bb5b7d2017-08-28 19:08:52130template <bool is_once, bool is_method, typename... Args>
tzikae4202e2017-07-31 10:41:54131struct MakeUnwrappedTypeListImpl {
tzikd4bb5b7d2017-08-28 19:08:52132 using Type = TypeList<TransformToUnwrappedType<is_once, Args>...>;
tzikae4202e2017-07-31 10:41:54133};
134
135// Performs special handling for this pointers.
136// Example:
137// int* -> int*,
138// std::unique_ptr<int> -> int*.
tzikd4bb5b7d2017-08-28 19:08:52139template <bool is_once, typename Receiver, typename... Args>
140struct MakeUnwrappedTypeListImpl<is_once, true, Receiver, Args...> {
141 using UnwrappedReceiver = TransformToUnwrappedType<is_once, Receiver>;
tzikae4202e2017-07-31 10:41:54142 using Type = TypeList<decltype(&*std::declval<UnwrappedReceiver>()),
tzikd4bb5b7d2017-08-28 19:08:52143 TransformToUnwrappedType<is_once, Args>...>;
tzikae4202e2017-07-31 10:41:54144};
145
tzikd4bb5b7d2017-08-28 19:08:52146template <bool is_once, bool is_method, typename... Args>
tzikae4202e2017-07-31 10:41:54147using MakeUnwrappedTypeList =
tzikd4bb5b7d2017-08-28 19:08:52148 typename MakeUnwrappedTypeListImpl<is_once, is_method, Args...>::Type;
tzikae4202e2017-07-31 10:41:54149
150} // namespace internal
151
tzik27d1e312016-09-13 05:28:59152// Bind as OnceCallback.
tzik401dd3672014-11-26 07:54:58153template <typename Functor, typename... Args>
tzik27d1e312016-09-13 05:28:59154inline OnceCallback<MakeUnboundRunType<Functor, Args...>>
155BindOnce(Functor&& functor, Args&&... args) {
Jeremy Roman35a317432017-08-16 22:20:53156 static_assert(!internal::IsOnceCallback<std::decay_t<Functor>>() ||
157 (std::is_rvalue_reference<Functor&&>() &&
158 !std::is_const<std::remove_reference_t<Functor>>()),
159 "BindOnce requires non-const rvalue for OnceCallback binding."
160 " I.e.: base::BindOnce(std::move(callback)).");
tzikae4202e2017-07-31 10:41:54161
162 // This block checks if each |args| matches to the corresponding params of the
163 // target function. This check does not affect the behavior of Bind, but its
164 // error message should be more readable.
165 using Helper = internal::BindTypeHelper<Functor, Args...>;
166 using FunctorTraits = typename Helper::FunctorTraits;
167 using BoundArgsList = typename Helper::BoundArgsList;
168 using UnwrappedArgsList =
tzikd4bb5b7d2017-08-28 19:08:52169 internal::MakeUnwrappedTypeList<true, FunctorTraits::is_method,
170 Args&&...>;
tzikae4202e2017-07-31 10:41:54171 using BoundParamsList = typename Helper::BoundParamsList;
Jeremy Roman84956fa2017-08-16 15:55:20172 static_assert(internal::AssertBindArgsValidity<
173 std::make_index_sequence<Helper::num_bounds>, BoundArgsList,
174 UnwrappedArgsList, BoundParamsList>::ok,
175 "The bound args need to be convertible to the target params.");
tzikae4202e2017-07-31 10:41:54176
tzik99de02b2016-07-01 05:54:12177 using BindState = internal::MakeBindStateType<Functor, Args...>;
tzikcaf1d84b2016-06-28 12:22:21178 using UnboundRunType = MakeUnboundRunType<Functor, Args...>;
tzikcaf1d84b2016-06-28 12:22:21179 using Invoker = internal::Invoker<BindState, UnboundRunType>;
tzik27d1e312016-09-13 05:28:59180 using CallbackType = OnceCallback<UnboundRunType>;
181
182 // Store the invoke func into PolymorphicInvoke before casting it to
183 // InvokeFuncStorage, so that we can ensure its type matches to
184 // PolymorphicInvoke, to which CallbackType will cast back.
185 using PolymorphicInvoke = typename CallbackType::PolymorphicInvoke;
186 PolymorphicInvoke invoke_func = &Invoker::RunOnce;
187
188 using InvokeFuncStorage = internal::BindStateBase::InvokeFuncStorage;
189 return CallbackType(new BindState(
190 reinterpret_cast<InvokeFuncStorage>(invoke_func),
191 std::forward<Functor>(functor),
192 std::forward<Args>(args)...));
193}
194
195// Bind as RepeatingCallback.
196template <typename Functor, typename... Args>
197inline RepeatingCallback<MakeUnboundRunType<Functor, Args...>>
198BindRepeating(Functor&& functor, Args&&... args) {
tzikae4202e2017-07-31 10:41:54199 static_assert(
Jeremy Roman35a317432017-08-16 22:20:53200 !internal::IsOnceCallback<std::decay_t<Functor>>(),
tzikae4202e2017-07-31 10:41:54201 "BindRepeating cannot bind OnceCallback. Use BindOnce with std::move().");
202
203 // This block checks if each |args| matches to the corresponding params of the
204 // target function. This check does not affect the behavior of Bind, but its
205 // error message should be more readable.
206 using Helper = internal::BindTypeHelper<Functor, Args...>;
207 using FunctorTraits = typename Helper::FunctorTraits;
208 using BoundArgsList = typename Helper::BoundArgsList;
209 using UnwrappedArgsList =
tzikd4bb5b7d2017-08-28 19:08:52210 internal::MakeUnwrappedTypeList<false, FunctorTraits::is_method,
211 Args&&...>;
tzikae4202e2017-07-31 10:41:54212 using BoundParamsList = typename Helper::BoundParamsList;
Jeremy Roman84956fa2017-08-16 15:55:20213 static_assert(internal::AssertBindArgsValidity<
214 std::make_index_sequence<Helper::num_bounds>, BoundArgsList,
215 UnwrappedArgsList, BoundParamsList>::ok,
216 "The bound args need to be convertible to the target params.");
tzikae4202e2017-07-31 10:41:54217
tzik27d1e312016-09-13 05:28:59218 using BindState = internal::MakeBindStateType<Functor, Args...>;
219 using UnboundRunType = MakeUnboundRunType<Functor, Args...>;
220 using Invoker = internal::Invoker<BindState, UnboundRunType>;
221 using CallbackType = RepeatingCallback<UnboundRunType>;
tzik1886c272016-09-08 05:45:38222
223 // Store the invoke func into PolymorphicInvoke before casting it to
224 // InvokeFuncStorage, so that we can ensure its type matches to
225 // PolymorphicInvoke, to which CallbackType will cast back.
226 using PolymorphicInvoke = typename CallbackType::PolymorphicInvoke;
227 PolymorphicInvoke invoke_func = &Invoker::Run;
228
229 using InvokeFuncStorage = internal::BindStateBase::InvokeFuncStorage;
230 return CallbackType(new BindState(
231 reinterpret_cast<InvokeFuncStorage>(invoke_func),
232 std::forward<Functor>(functor),
233 std::forward<Args>(args)...));
[email protected]fccef1552011-11-28 22:13:54234}
235
tzik27d1e312016-09-13 05:28:59236// Unannotated Bind.
237// TODO(tzik): Deprecate this and migrate to OnceCallback and
238// RepeatingCallback, once they get ready.
239template <typename Functor, typename... Args>
240inline Callback<MakeUnboundRunType<Functor, Args...>>
241Bind(Functor&& functor, Args&&... args) {
Yuta Kitamurad6c13d8e2017-12-01 06:09:41242 return base::BindRepeating(std::forward<Functor>(functor),
243 std::forward<Args>(args)...);
tzik27d1e312016-09-13 05:28:59244}
245
tzikc20ed0b2017-08-18 22:59:55246// Special cases for binding to a base::Callback without extra bound arguments.
247template <typename Signature>
248OnceCallback<Signature> BindOnce(OnceCallback<Signature> closure) {
249 return closure;
250}
251
252template <typename Signature>
253RepeatingCallback<Signature> BindRepeating(
254 RepeatingCallback<Signature> closure) {
255 return closure;
256}
257
258template <typename Signature>
259Callback<Signature> Bind(Callback<Signature> closure) {
260 return closure;
261}
262
Peter Kastinga85265e32018-02-15 08:30:23263// Unretained() allows Bind() to bind a non-refcounted class, and to disable
264// refcounting on arguments that are refcounted objects.
265//
266// EXAMPLE OF Unretained():
267//
268// class Foo {
269// public:
270// void func() { cout << "Foo:f" << endl; }
271// };
272//
273// // In some function somewhere.
274// Foo foo;
275// Closure foo_callback =
276// Bind(&Foo::func, Unretained(&foo));
277// foo_callback.Run(); // Prints "Foo:f".
278//
279// Without the Unretained() wrapper on |&foo|, the above call would fail
280// to compile because Foo does not support the AddRef() and Release() methods.
281template <typename T>
282static inline internal::UnretainedWrapper<T> Unretained(T* o) {
283 return internal::UnretainedWrapper<T>(o);
284}
285
286// RetainedRef() accepts a ref counted object and retains a reference to it.
287// When the callback is called, the object is passed as a raw pointer.
288//
289// EXAMPLE OF RetainedRef():
290//
291// void foo(RefCountedBytes* bytes) {}
292//
293// scoped_refptr<RefCountedBytes> bytes = ...;
294// Closure callback = Bind(&foo, base::RetainedRef(bytes));
295// callback.Run();
296//
297// Without RetainedRef, the scoped_refptr would try to implicitly convert to
298// a raw pointer and fail compilation:
299//
300// Closure callback = Bind(&foo, bytes); // ERROR!
301template <typename T>
302static inline internal::RetainedRefWrapper<T> RetainedRef(T* o) {
303 return internal::RetainedRefWrapper<T>(o);
304}
305template <typename T>
306static inline internal::RetainedRefWrapper<T> RetainedRef(scoped_refptr<T> o) {
307 return internal::RetainedRefWrapper<T>(std::move(o));
308}
309
310// ConstRef() allows binding a constant reference to an argument rather
311// than a copy.
312//
313// EXAMPLE OF ConstRef():
314//
315// void foo(int arg) { cout << arg << endl }
316//
317// int n = 1;
318// Closure no_ref = Bind(&foo, n);
319// Closure has_ref = Bind(&foo, ConstRef(n));
320//
321// no_ref.Run(); // Prints "1"
322// has_ref.Run(); // Prints "1"
323//
324// n = 2;
325// no_ref.Run(); // Prints "1"
326// has_ref.Run(); // Prints "2"
327//
328// Note that because ConstRef() takes a reference on |n|, |n| must outlive all
329// its bound callbacks.
330template <typename T>
331static inline internal::ConstRefWrapper<T> ConstRef(const T& o) {
332 return internal::ConstRefWrapper<T>(o);
333}
334
335// Owned() transfers ownership of an object to the Callback resulting from
336// bind; the object will be deleted when the Callback is deleted.
337//
338// EXAMPLE OF Owned():
339//
340// void foo(int* arg) { cout << *arg << endl }
341//
342// int* pn = new int(1);
343// Closure foo_callback = Bind(&foo, Owned(pn));
344//
345// foo_callback.Run(); // Prints "1"
346// foo_callback.Run(); // Prints "1"
347// *n = 2;
348// foo_callback.Run(); // Prints "2"
349//
350// foo_callback.Reset(); // |pn| is deleted. Also will happen when
351// // |foo_callback| goes out of scope.
352//
353// Without Owned(), someone would have to know to delete |pn| when the last
354// reference to the Callback is deleted.
355template <typename T>
356static inline internal::OwnedWrapper<T> Owned(T* o) {
357 return internal::OwnedWrapper<T>(o);
358}
359
360// Passed() is for transferring movable-but-not-copyable types (eg. unique_ptr)
361// through a Callback. Logically, this signifies a destructive transfer of
362// the state of the argument into the target function. Invoking
363// Callback::Run() twice on a Callback that was created with a Passed()
364// argument will CHECK() because the first invocation would have already
365// transferred ownership to the target function.
366//
Max Morinb51cf512018-02-19 12:49:49367// Note that Passed() is not necessary with BindOnce(), as std::move() does the
368// same thing. Avoid Passed() in favor of std::move() with BindOnce().
369//
Peter Kastinga85265e32018-02-15 08:30:23370// EXAMPLE OF Passed():
371//
372// void TakesOwnership(std::unique_ptr<Foo> arg) { }
Max Morinb51cf512018-02-19 12:49:49373// std::unique_ptr<Foo> CreateFoo() { return std::make_unique<Foo>();
Peter Kastinga85265e32018-02-15 08:30:23374// }
375//
Max Morinb51cf512018-02-19 12:49:49376// auto f = std::make_unique<Foo>();
Peter Kastinga85265e32018-02-15 08:30:23377//
378// // |cb| is given ownership of Foo(). |f| is now NULL.
379// // You can use std::move(f) in place of &f, but it's more verbose.
380// Closure cb = Bind(&TakesOwnership, Passed(&f));
381//
382// // Run was never called so |cb| still owns Foo() and deletes
383// // it on Reset().
384// cb.Reset();
385//
386// // |cb| is given a new Foo created by CreateFoo().
387// cb = Bind(&TakesOwnership, Passed(CreateFoo()));
388//
389// // |arg| in TakesOwnership() is given ownership of Foo(). |cb|
390// // no longer owns Foo() and, if reset, would not delete Foo().
391// cb.Run(); // Foo() is now transferred to |arg| and deleted.
392// cb.Run(); // This CHECK()s since Foo() already been used once.
393//
Peter Kastinga85265e32018-02-15 08:30:23394// We offer 2 syntaxes for calling Passed(). The first takes an rvalue and
395// is best suited for use with the return value of a function or other temporary
396// rvalues. The second takes a pointer to the scoper and is just syntactic sugar
397// to avoid having to write Passed(std::move(scoper)).
398//
399// Both versions of Passed() prevent T from being an lvalue reference. The first
400// via use of enable_if, and the second takes a T* which will not bind to T&.
401template <typename T,
402 std::enable_if_t<!std::is_lvalue_reference<T>::value>* = nullptr>
403static inline internal::PassedWrapper<T> Passed(T&& scoper) {
404 return internal::PassedWrapper<T>(std::move(scoper));
405}
406template <typename T>
407static inline internal::PassedWrapper<T> Passed(T* scoper) {
408 return internal::PassedWrapper<T>(std::move(*scoper));
409}
410
411// IgnoreResult() is used to adapt a function or Callback with a return type to
412// one with a void return. This is most useful if you have a function with,
413// say, a pesky ignorable bool return that you want to use with PostTask or
414// something else that expect a Callback with a void return.
415//
416// EXAMPLE OF IgnoreResult():
417//
418// int DoSomething(int arg) { cout << arg << endl; }
419//
420// // Assign to a Callback with a void return type.
421// Callback<void(int)> cb = Bind(IgnoreResult(&DoSomething));
422// cb->Run(1); // Prints "1".
423//
424// // Prints "1" on |ml|.
425// ml->PostTask(FROM_HERE, Bind(IgnoreResult(&DoSomething), 1);
426template <typename T>
427static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) {
428 return internal::IgnoreResultHelper<T>(std::move(data));
429}
430
[email protected]b38d3572011-02-15 01:27:38431} // namespace base
432
433#endif // BASE_BIND_H_