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_INTERNAL_H_
6 #define BASE_BIND_INTERNAL_H_
7
8 #include <stddef.h>
9
10 #include <type_traits>
11 #include <utility>
12
13 #include "base/callback_internal.h"
14 #include "base/compiler_specific.h"
15 #include "base/memory/raw_scoped_refptr_mismatch_checker.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/template_util.h"
18 #include "build/build_config.h"
19
20 #if defined(OS_MACOSX) && !HAS_FEATURE(objc_arc)
21 #include "base/mac/scoped_block.h"
22 #endif
23
24 // See base/callback.h for user documentation.
25 //
26 //
27 // CONCEPTS:
28 // Functor -- A movable type representing something that should be called.
29 // All function pointers and Callback<> are functors even if the
30 // invocation syntax differs.
31 // RunType -- A function type (as opposed to function _pointer_ type) for
32 // a Callback<>::Run(). Usually just a convenience typedef.
33 // (Bound)Args -- A set of types that stores the arguments.
34 //
35 // Types:
36 // ForceVoidReturn<> -- Helper class for translating function signatures to
37 // equivalent forms with a "void" return type.
38 // FunctorTraits<> -- Type traits used to determine the correct RunType and
39 // invocation manner for a Functor. This is where function
40 // signature adapters are applied.
41 // InvokeHelper<> -- Take a Functor + arguments and actully invokes it.
42 // Handle the differing syntaxes needed for WeakPtr<>
43 // support. This is separate from Invoker to avoid creating
44 // multiple version of Invoker<>.
45 // Invoker<> -- Unwraps the curried parameters and executes the Functor.
46 // BindState<> -- Stores the curried parameters, and is the main entry point
47 // into the Bind() system.
48
49 namespace base {
50
51 template <typename T>
52 struct IsWeakReceiver;
53
54 template <typename>
55 struct BindUnwrapTraits;
56
57 template <typename Functor, typename BoundArgsTuple, typename SFINAE = void>
58 struct CallbackCancellationTraits;
59
60 namespace internal {
61
62 template <typename Functor, typename SFINAE = void>
63 struct FunctorTraits;
64
65 template <typename T>
66 class UnretainedWrapper {
67 public:
UnretainedWrapper(T * o)68 explicit UnretainedWrapper(T* o) : ptr_(o) {}
get()69 T* get() const { return ptr_; }
70
71 private:
72 T* ptr_;
73 };
74
75 template <typename T>
76 class ConstRefWrapper {
77 public:
ConstRefWrapper(const T & o)78 explicit ConstRefWrapper(const T& o) : ptr_(&o) {}
get()79 const T& get() const { return *ptr_; }
80
81 private:
82 const T* ptr_;
83 };
84
85 template <typename T>
86 class RetainedRefWrapper {
87 public:
RetainedRefWrapper(T * o)88 explicit RetainedRefWrapper(T* o) : ptr_(o) {}
RetainedRefWrapper(scoped_refptr<T> o)89 explicit RetainedRefWrapper(scoped_refptr<T> o) : ptr_(std::move(o)) {}
get()90 T* get() const { return ptr_.get(); }
91
92 private:
93 scoped_refptr<T> ptr_;
94 };
95
96 template <typename T>
97 struct IgnoreResultHelper {
IgnoreResultHelperIgnoreResultHelper98 explicit IgnoreResultHelper(T functor) : functor_(std::move(functor)) {}
99 explicit operator bool() const { return !!functor_; }
100
101 T functor_;
102 };
103
104 // An alternate implementation is to avoid the destructive copy, and instead
105 // specialize ParamTraits<> for OwnedWrapper<> to change the StorageType to
106 // a class that is essentially a std::unique_ptr<>.
107 //
108 // The current implementation has the benefit though of leaving ParamTraits<>
109 // fully in callback_internal.h as well as avoiding type conversions during
110 // storage.
111 template <typename T>
112 class OwnedWrapper {
113 public:
OwnedWrapper(T * o)114 explicit OwnedWrapper(T* o) : ptr_(o) {}
~OwnedWrapper()115 ~OwnedWrapper() { delete ptr_; }
get()116 T* get() const { return ptr_; }
OwnedWrapper(OwnedWrapper && other)117 OwnedWrapper(OwnedWrapper&& other) {
118 ptr_ = other.ptr_;
119 other.ptr_ = NULL;
120 }
121
122 private:
123 mutable T* ptr_;
124 };
125
126 // PassedWrapper is a copyable adapter for a scoper that ignores const.
127 //
128 // It is needed to get around the fact that Bind() takes a const reference to
129 // all its arguments. Because Bind() takes a const reference to avoid
130 // unnecessary copies, it is incompatible with movable-but-not-copyable
131 // types; doing a destructive "move" of the type into Bind() would violate
132 // the const correctness.
133 //
134 // This conundrum cannot be solved without either C++11 rvalue references or
135 // a O(2^n) blowup of Bind() templates to handle each combination of regular
136 // types and movable-but-not-copyable types. Thus we introduce a wrapper type
137 // that is copyable to transmit the correct type information down into
138 // BindState<>. Ignoring const in this type makes sense because it is only
139 // created when we are explicitly trying to do a destructive move.
140 //
141 // Two notes:
142 // 1) PassedWrapper supports any type that has a move constructor, however
143 // the type will need to be specifically whitelisted in order for it to be
144 // bound to a Callback. We guard this explicitly at the call of Passed()
145 // to make for clear errors. Things not given to Passed() will be forwarded
146 // and stored by value which will not work for general move-only types.
147 // 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL"
148 // scoper to a Callback and allow the Callback to execute once.
149 template <typename T>
150 class PassedWrapper {
151 public:
PassedWrapper(T && scoper)152 explicit PassedWrapper(T&& scoper)
153 : is_valid_(true), scoper_(std::move(scoper)) {}
PassedWrapper(PassedWrapper && other)154 PassedWrapper(PassedWrapper&& other)
155 : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {}
Take()156 T Take() const {
157 CHECK(is_valid_);
158 is_valid_ = false;
159 return std::move(scoper_);
160 }
161
162 private:
163 mutable bool is_valid_;
164 mutable T scoper_;
165 };
166
167 template <typename T>
168 using Unwrapper = BindUnwrapTraits<std::decay_t<T>>;
169
170 template <typename T>
decltype(auto)171 decltype(auto) Unwrap(T&& o) {
172 return Unwrapper<T>::Unwrap(std::forward<T>(o));
173 }
174
175 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a
176 // method. It is used internally by Bind() to select the correct
177 // InvokeHelper that will no-op itself in the event the WeakPtr<> for
178 // the target object is invalidated.
179 //
180 // The first argument should be the type of the object that will be received by
181 // the method.
182 template <bool is_method, typename... Args>
183 struct IsWeakMethod : std::false_type {};
184
185 template <typename T, typename... Args>
186 struct IsWeakMethod<true, T, Args...> : IsWeakReceiver<T> {};
187
188 // Packs a list of types to hold them in a single type.
189 template <typename... Types>
190 struct TypeList {};
191
192 // Used for DropTypeListItem implementation.
193 template <size_t n, typename List>
194 struct DropTypeListItemImpl;
195
196 // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure.
197 template <size_t n, typename T, typename... List>
198 struct DropTypeListItemImpl<n, TypeList<T, List...>>
199 : DropTypeListItemImpl<n - 1, TypeList<List...>> {};
200
201 template <typename T, typename... List>
202 struct DropTypeListItemImpl<0, TypeList<T, List...>> {
203 using Type = TypeList<T, List...>;
204 };
205
206 template <>
207 struct DropTypeListItemImpl<0, TypeList<>> {
208 using Type = TypeList<>;
209 };
210
211 // A type-level function that drops |n| list item from given TypeList.
212 template <size_t n, typename List>
213 using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type;
214
215 // Used for TakeTypeListItem implementation.
216 template <size_t n, typename List, typename... Accum>
217 struct TakeTypeListItemImpl;
218
219 // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure.
220 template <size_t n, typename T, typename... List, typename... Accum>
221 struct TakeTypeListItemImpl<n, TypeList<T, List...>, Accum...>
222 : TakeTypeListItemImpl<n - 1, TypeList<List...>, Accum..., T> {};
223
224 template <typename T, typename... List, typename... Accum>
225 struct TakeTypeListItemImpl<0, TypeList<T, List...>, Accum...> {
226 using Type = TypeList<Accum...>;
227 };
228
229 template <typename... Accum>
230 struct TakeTypeListItemImpl<0, TypeList<>, Accum...> {
231 using Type = TypeList<Accum...>;
232 };
233
234 // A type-level function that takes first |n| list item from given TypeList.
235 // E.g. TakeTypeListItem<3, TypeList<A, B, C, D>> is evaluated to
236 // TypeList<A, B, C>.
237 template <size_t n, typename List>
238 using TakeTypeListItem = typename TakeTypeListItemImpl<n, List>::Type;
239
240 // Used for ConcatTypeLists implementation.
241 template <typename List1, typename List2>
242 struct ConcatTypeListsImpl;
243
244 template <typename... Types1, typename... Types2>
245 struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> {
246 using Type = TypeList<Types1..., Types2...>;
247 };
248
249 // A type-level function that concats two TypeLists.
250 template <typename List1, typename List2>
251 using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type;
252
253 // Used for MakeFunctionType implementation.
254 template <typename R, typename ArgList>
255 struct MakeFunctionTypeImpl;
256
257 template <typename R, typename... Args>
258 struct MakeFunctionTypeImpl<R, TypeList<Args...>> {
259 // MSVC 2013 doesn't support Type Alias of function types.
260 // Revisit this after we update it to newer version.
261 typedef R Type(Args...);
262 };
263
264 // A type-level function that constructs a function type that has |R| as its
265 // return type and has TypeLists items as its arguments.
266 template <typename R, typename ArgList>
267 using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type;
268
269 // Used for ExtractArgs and ExtractReturnType.
270 template <typename Signature>
271 struct ExtractArgsImpl;
272
273 template <typename R, typename... Args>
274 struct ExtractArgsImpl<R(Args...)> {
275 using ReturnType = R;
276 using ArgsList = TypeList<Args...>;
277 };
278
279 // A type-level function that extracts function arguments into a TypeList.
280 // E.g. ExtractArgs<R(A, B, C)> is evaluated to TypeList<A, B, C>.
281 template <typename Signature>
282 using ExtractArgs = typename ExtractArgsImpl<Signature>::ArgsList;
283
284 // A type-level function that extracts the return type of a function.
285 // E.g. ExtractReturnType<R(A, B, C)> is evaluated to R.
286 template <typename Signature>
287 using ExtractReturnType = typename ExtractArgsImpl<Signature>::ReturnType;
288
289 template <typename Callable,
290 typename Signature = decltype(&Callable::operator())>
291 struct ExtractCallableRunTypeImpl;
292
293 template <typename Callable, typename R, typename... Args>
294 struct ExtractCallableRunTypeImpl<Callable, R (Callable::*)(Args...)> {
295 using Type = R(Args...);
296 };
297
298 template <typename Callable, typename R, typename... Args>
299 struct ExtractCallableRunTypeImpl<Callable, R (Callable::*)(Args...) const> {
300 using Type = R(Args...);
301 };
302
303 // Evaluated to RunType of the given callable type.
304 // Example:
305 // auto f = [](int, char*) { return 0.1; };
306 // ExtractCallableRunType<decltype(f)>
307 // is evaluated to
308 // double(int, char*);
309 template <typename Callable>
310 using ExtractCallableRunType =
311 typename ExtractCallableRunTypeImpl<Callable>::Type;
312
313 // IsCallableObject<Functor> is std::true_type if |Functor| has operator().
314 // Otherwise, it's std::false_type.
315 // Example:
316 // IsCallableObject<void(*)()>::value is false.
317 //
318 // struct Foo {};
319 // IsCallableObject<void(Foo::*)()>::value is false.
320 //
321 // int i = 0;
322 // auto f = [i]() {};
323 // IsCallableObject<decltype(f)>::value is false.
324 template <typename Functor, typename SFINAE = void>
325 struct IsCallableObject : std::false_type {};
326
327 template <typename Callable>
328 struct IsCallableObject<Callable, void_t<decltype(&Callable::operator())>>
329 : std::true_type {};
330
331 // HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw
332 // pointer to a RefCounted type.
333 // Implementation note: This non-specialized case handles zero-arity case only.
334 // Non-zero-arity cases should be handled by the specialization below.
335 template <typename... Args>
336 struct HasRefCountedTypeAsRawPtr : std::false_type {};
337
338 // Implementation note: Select true_type if the first parameter is a raw pointer
339 // to a RefCounted type. Otherwise, skip the first parameter and check rest of
340 // parameters recursively.
341 template <typename T, typename... Args>
342 struct HasRefCountedTypeAsRawPtr<T, Args...>
343 : std::conditional_t<NeedsScopedRefptrButGetsRawPtr<T>::value,
344 std::true_type,
345 HasRefCountedTypeAsRawPtr<Args...>> {};
346
347 // ForceVoidReturn<>
348 //
349 // Set of templates that support forcing the function return type to void.
350 template <typename Sig>
351 struct ForceVoidReturn;
352
353 template <typename R, typename... Args>
354 struct ForceVoidReturn<R(Args...)> {
355 using RunType = void(Args...);
356 };
357
358 // FunctorTraits<>
359 //
360 // See description at top of file.
361 template <typename Functor, typename SFINAE>
362 struct FunctorTraits;
363
364 // For empty callable types.
365 // This specialization is intended to allow binding captureless lambdas by
366 // base::Bind(), based on the fact that captureless lambdas are empty while
367 // capturing lambdas are not. This also allows any functors as far as it's an
368 // empty class.
369 // Example:
370 //
371 // // Captureless lambdas are allowed.
372 // []() {return 42;};
373 //
374 // // Capturing lambdas are *not* allowed.
375 // int x;
376 // [x]() {return x;};
377 //
378 // // Any empty class with operator() is allowed.
379 // struct Foo {
380 // void operator()() const {}
381 // // No non-static member variable and no virtual functions.
382 // };
383 template <typename Functor>
384 struct FunctorTraits<Functor,
385 std::enable_if_t<IsCallableObject<Functor>::value &&
386 std::is_empty<Functor>::value>> {
387 using RunType = ExtractCallableRunType<Functor>;
388 static constexpr bool is_method = false;
389 static constexpr bool is_nullable = false;
390
391 template <typename RunFunctor, typename... RunArgs>
392 static ExtractReturnType<RunType> Invoke(RunFunctor&& functor,
393 RunArgs&&... args) {
394 return std::forward<RunFunctor>(functor)(std::forward<RunArgs>(args)...);
395 }
396 };
397
398 // For functions.
399 template <typename R, typename... Args>
400 struct FunctorTraits<R (*)(Args...)> {
401 using RunType = R(Args...);
402 static constexpr bool is_method = false;
403 static constexpr bool is_nullable = true;
404
405 template <typename Function, typename... RunArgs>
406 static R Invoke(Function&& function, RunArgs&&... args) {
407 return std::forward<Function>(function)(std::forward<RunArgs>(args)...);
408 }
409 };
410
411 #if defined(OS_WIN) && !defined(ARCH_CPU_X86_64)
412
413 // For functions.
414 template <typename R, typename... Args>
415 struct FunctorTraits<R(__stdcall*)(Args...)> {
416 using RunType = R(Args...);
417 static constexpr bool is_method = false;
418 static constexpr bool is_nullable = true;
419
420 template <typename... RunArgs>
421 static R Invoke(R(__stdcall* function)(Args...), RunArgs&&... args) {
422 return function(std::forward<RunArgs>(args)...);
423 }
424 };
425
426 // For functions.
427 template <typename R, typename... Args>
428 struct FunctorTraits<R(__fastcall*)(Args...)> {
429 using RunType = R(Args...);
430 static constexpr bool is_method = false;
431 static constexpr bool is_nullable = true;
432
433 template <typename... RunArgs>
434 static R Invoke(R(__fastcall* function)(Args...), RunArgs&&... args) {
435 return function(std::forward<RunArgs>(args)...);
436 }
437 };
438
439 #endif // defined(OS_WIN) && !defined(ARCH_CPU_X86_64)
440
441 #if defined(OS_MACOSX)
442
443 // Support for Objective-C blocks. There are two implementation depending
444 // on whether Automated Reference Counting (ARC) is enabled. When ARC is
445 // enabled, then the block itself can be bound as the compiler will ensure
446 // its lifetime will be correctly managed. Otherwise, require the block to
447 // be wrapped in a base::mac::ScopedBlock (via base::RetainBlock) that will
448 // correctly manage the block lifetime.
449 //
450 // The two implementation ensure that the One Definition Rule (ODR) is not
451 // broken (it is not possible to write a template base::RetainBlock that would
452 // work correctly both with ARC enabled and disabled).
453
454 #if HAS_FEATURE(objc_arc)
455
456 template <typename R, typename... Args>
457 struct FunctorTraits<R (^)(Args...)> {
458 using RunType = R(Args...);
459 static constexpr bool is_method = false;
460 static constexpr bool is_nullable = true;
461
462 template <typename BlockType, typename... RunArgs>
463 static R Invoke(BlockType&& block, RunArgs&&... args) {
464 // According to LLVM documentation (§ 6.3), "local variables of automatic
465 // storage duration do not have precise lifetime." Use objc_precise_lifetime
466 // to ensure that the Objective-C block is not deallocated until it has
467 // finished executing even if the Callback<> is destroyed during the block
468 // execution.
469 // https://clang.llvm.org/docs/AutomaticReferenceCounting.html#precise-lifetime-semantics
470 __attribute__((objc_precise_lifetime)) R (^scoped_block)(Args...) = block;
471 return scoped_block(std::forward<RunArgs>(args)...);
472 }
473 };
474
475 #else // HAS_FEATURE(objc_arc)
476
477 template <typename R, typename... Args>
478 struct FunctorTraits<base::mac::ScopedBlock<R (^)(Args...)>> {
479 using RunType = R(Args...);
480 static constexpr bool is_method = false;
481 static constexpr bool is_nullable = true;
482
483 template <typename BlockType, typename... RunArgs>
484 static R Invoke(BlockType&& block, RunArgs&&... args) {
485 // Copy the block to ensure that the Objective-C block is not deallocated
486 // until it has finished executing even if the Callback<> is destroyed
487 // during the block execution.
488 base::mac::ScopedBlock<R (^)(Args...)> scoped_block(block);
489 return scoped_block.get()(std::forward<RunArgs>(args)...);
490 }
491 };
492
493 #endif // HAS_FEATURE(objc_arc)
494 #endif // defined(OS_MACOSX)
495
496 // For methods.
497 template <typename R, typename Receiver, typename... Args>
498 struct FunctorTraits<R (Receiver::*)(Args...)> {
499 using RunType = R(Receiver*, Args...);
500 static constexpr bool is_method = true;
501 static constexpr bool is_nullable = true;
502
503 template <typename Method, typename ReceiverPtr, typename... RunArgs>
504 static R Invoke(Method method,
505 ReceiverPtr&& receiver_ptr,
506 RunArgs&&... args) {
507 return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...);
508 }
509 };
510
511 // For const methods.
512 template <typename R, typename Receiver, typename... Args>
513 struct FunctorTraits<R (Receiver::*)(Args...) const> {
514 using RunType = R(const Receiver*, Args...);
515 static constexpr bool is_method = true;
516 static constexpr bool is_nullable = true;
517
518 template <typename Method, typename ReceiverPtr, typename... RunArgs>
519 static R Invoke(Method method,
520 ReceiverPtr&& receiver_ptr,
521 RunArgs&&... args) {
522 return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...);
523 }
524 };
525
526 #ifdef __cpp_noexcept_function_type
527 // noexcept makes a distinct function type in C++17.
528 // I.e. `void(*)()` and `void(*)() noexcept` are same in pre-C++17, and
529 // different in C++17.
530 template <typename R, typename... Args>
531 struct FunctorTraits<R (*)(Args...) noexcept> : FunctorTraits<R (*)(Args...)> {
532 };
533
534 template <typename R, typename Receiver, typename... Args>
535 struct FunctorTraits<R (Receiver::*)(Args...) noexcept>
536 : FunctorTraits<R (Receiver::*)(Args...)> {};
537
538 template <typename R, typename Receiver, typename... Args>
539 struct FunctorTraits<R (Receiver::*)(Args...) const noexcept>
540 : FunctorTraits<R (Receiver::*)(Args...) const> {};
541 #endif
542
543 // For IgnoreResults.
544 template <typename T>
545 struct FunctorTraits<IgnoreResultHelper<T>> : FunctorTraits<T> {
546 using RunType =
547 typename ForceVoidReturn<typename FunctorTraits<T>::RunType>::RunType;
548
549 template <typename IgnoreResultType, typename... RunArgs>
550 static void Invoke(IgnoreResultType&& ignore_result_helper,
551 RunArgs&&... args) {
552 FunctorTraits<T>::Invoke(
553 std::forward<IgnoreResultType>(ignore_result_helper).functor_,
554 std::forward<RunArgs>(args)...);
555 }
556 };
557
558 // For OnceCallbacks.
559 template <typename R, typename... Args>
560 struct FunctorTraits<OnceCallback<R(Args...)>> {
561 using RunType = R(Args...);
562 static constexpr bool is_method = false;
563 static constexpr bool is_nullable = true;
564
565 template <typename CallbackType, typename... RunArgs>
566 static R Invoke(CallbackType&& callback, RunArgs&&... args) {
567 DCHECK(!callback.is_null());
568 return std::forward<CallbackType>(callback).Run(
569 std::forward<RunArgs>(args)...);
570 }
571 };
572
573 // For RepeatingCallbacks.
574 template <typename R, typename... Args>
575 struct FunctorTraits<RepeatingCallback<R(Args...)>> {
576 using RunType = R(Args...);
577 static constexpr bool is_method = false;
578 static constexpr bool is_nullable = true;
579
580 template <typename CallbackType, typename... RunArgs>
581 static R Invoke(CallbackType&& callback, RunArgs&&... args) {
582 DCHECK(!callback.is_null());
583 return std::forward<CallbackType>(callback).Run(
584 std::forward<RunArgs>(args)...);
585 }
586 };
587
588 template <typename Functor>
589 using MakeFunctorTraits = FunctorTraits<std::decay_t<Functor>>;
590
591 // InvokeHelper<>
592 //
593 // There are 2 logical InvokeHelper<> specializations: normal, WeakCalls.
594 //
595 // The normal type just calls the underlying runnable.
596 //
597 // WeakCalls need special syntax that is applied to the first argument to check
598 // if they should no-op themselves.
599 template <bool is_weak_call, typename ReturnType>
600 struct InvokeHelper;
601
602 template <typename ReturnType>
603 struct InvokeHelper<false, ReturnType> {
604 template <typename Functor, typename... RunArgs>
605 static inline ReturnType MakeItSo(Functor&& functor, RunArgs&&... args) {
606 using Traits = MakeFunctorTraits<Functor>;
607 return Traits::Invoke(std::forward<Functor>(functor),
608 std::forward<RunArgs>(args)...);
609 }
610 };
611
612 template <typename ReturnType>
613 struct InvokeHelper<true, ReturnType> {
614 // WeakCalls are only supported for functions with a void return type.
615 // Otherwise, the function result would be undefined if the the WeakPtr<>
616 // is invalidated.
617 static_assert(std::is_void<ReturnType>::value,
618 "weak_ptrs can only bind to methods without return values");
619
620 template <typename Functor, typename BoundWeakPtr, typename... RunArgs>
621 static inline void MakeItSo(Functor&& functor,
622 BoundWeakPtr&& weak_ptr,
623 RunArgs&&... args) {
624 if (!weak_ptr)
625 return;
626 using Traits = MakeFunctorTraits<Functor>;
627 Traits::Invoke(std::forward<Functor>(functor),
628 std::forward<BoundWeakPtr>(weak_ptr),
629 std::forward<RunArgs>(args)...);
630 }
631 };
632
633 // Invoker<>
634 //
635 // See description at the top of the file.
636 template <typename StorageType, typename UnboundRunType>
637 struct Invoker;
638
639 template <typename StorageType, typename R, typename... UnboundArgs>
640 struct Invoker<StorageType, R(UnboundArgs...)> {
641 static R RunOnce(BindStateBase* base,
642 PassingType<UnboundArgs>... unbound_args) {
643 // Local references to make debugger stepping easier. If in a debugger,
644 // you really want to warp ahead and step through the
645 // InvokeHelper<>::MakeItSo() call below.
646 StorageType* storage = static_cast<StorageType*>(base);
647 static constexpr size_t num_bound_args =
648 std::tuple_size<decltype(storage->bound_args_)>::value;
649 return RunImpl(std::move(storage->functor_),
650 std::move(storage->bound_args_),
651 std::make_index_sequence<num_bound_args>(),
652 std::forward<UnboundArgs>(unbound_args)...);
653 }
654
655 static R Run(BindStateBase* base, PassingType<UnboundArgs>... unbound_args) {
656 // Local references to make debugger stepping easier. If in a debugger,
657 // you really want to warp ahead and step through the
658 // InvokeHelper<>::MakeItSo() call below.
659 const StorageType* storage = static_cast<StorageType*>(base);
660 static constexpr size_t num_bound_args =
661 std::tuple_size<decltype(storage->bound_args_)>::value;
662 return RunImpl(storage->functor_, storage->bound_args_,
663 std::make_index_sequence<num_bound_args>(),
664 std::forward<UnboundArgs>(unbound_args)...);
665 }
666
667 private:
668 template <typename Functor, typename BoundArgsTuple, size_t... indices>
669 static inline R RunImpl(Functor&& functor,
670 BoundArgsTuple&& bound,
671 std::index_sequence<indices...>,
672 UnboundArgs&&... unbound_args) {
673 static constexpr bool is_method = MakeFunctorTraits<Functor>::is_method;
674
675 using DecayedArgsTuple = std::decay_t<BoundArgsTuple>;
676 static constexpr bool is_weak_call =
677 IsWeakMethod<is_method,
678 std::tuple_element_t<indices, DecayedArgsTuple>...>();
679
680 return InvokeHelper<is_weak_call, R>::MakeItSo(
681 std::forward<Functor>(functor),
682 Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))...,
683 std::forward<UnboundArgs>(unbound_args)...);
684 }
685 };
686
687 // Extracts necessary type info from Functor and BoundArgs.
688 // Used to implement MakeUnboundRunType, BindOnce and BindRepeating.
689 template <typename Functor, typename... BoundArgs>
690 struct BindTypeHelper {
691 static constexpr size_t num_bounds = sizeof...(BoundArgs);
692 using FunctorTraits = MakeFunctorTraits<Functor>;
693
694 // Example:
695 // When Functor is `double (Foo::*)(int, const std::string&)`, and BoundArgs
696 // is a template pack of `Foo*` and `int16_t`:
697 // - RunType is `double(Foo*, int, const std::string&)`,
698 // - ReturnType is `double`,
699 // - RunParamsList is `TypeList<Foo*, int, const std::string&>`,
700 // - BoundParamsList is `TypeList<Foo*, int>`,
701 // - UnboundParamsList is `TypeList<const std::string&>`,
702 // - BoundArgsList is `TypeList<Foo*, int16_t>`,
703 // - UnboundRunType is `double(const std::string&)`.
704 using RunType = typename FunctorTraits::RunType;
705 using ReturnType = ExtractReturnType<RunType>;
706
707 using RunParamsList = ExtractArgs<RunType>;
708 using BoundParamsList = TakeTypeListItem<num_bounds, RunParamsList>;
709 using UnboundParamsList = DropTypeListItem<num_bounds, RunParamsList>;
710
711 using BoundArgsList = TypeList<BoundArgs...>;
712
713 using UnboundRunType = MakeFunctionType<ReturnType, UnboundParamsList>;
714 };
715
716 template <typename Functor>
717 std::enable_if_t<FunctorTraits<Functor>::is_nullable, bool> IsNull(
718 const Functor& functor) {
719 return !functor;
720 }
721
722 template <typename Functor>
723 std::enable_if_t<!FunctorTraits<Functor>::is_nullable, bool> IsNull(
724 const Functor&) {
725 return false;
726 }
727
728 // Used by ApplyCancellationTraits below.
729 template <typename Functor, typename BoundArgsTuple, size_t... indices>
730 bool ApplyCancellationTraitsImpl(const Functor& functor,
731 const BoundArgsTuple& bound_args,
732 std::index_sequence<indices...>) {
733 return CallbackCancellationTraits<Functor, BoundArgsTuple>::IsCancelled(
734 functor, std::get<indices>(bound_args)...);
735 }
736
737 // Relays |base| to corresponding CallbackCancellationTraits<>::Run(). Returns
738 // true if the callback |base| represents is canceled.
739 template <typename BindStateType>
740 bool ApplyCancellationTraits(const BindStateBase* base) {
741 const BindStateType* storage = static_cast<const BindStateType*>(base);
742 static constexpr size_t num_bound_args =
743 std::tuple_size<decltype(storage->bound_args_)>::value;
744 return ApplyCancellationTraitsImpl(
745 storage->functor_, storage->bound_args_,
746 std::make_index_sequence<num_bound_args>());
747 };
748
749 // BindState<>
750 //
751 // This stores all the state passed into Bind().
752 template <typename Functor, typename... BoundArgs>
753 struct BindState final : BindStateBase {
754 using IsCancellable = std::integral_constant<
755 bool,
756 CallbackCancellationTraits<Functor,
757 std::tuple<BoundArgs...>>::is_cancellable>;
758
759 template <typename ForwardFunctor, typename... ForwardBoundArgs>
760 explicit BindState(BindStateBase::InvokeFuncStorage invoke_func,
761 ForwardFunctor&& functor,
762 ForwardBoundArgs&&... bound_args)
763 // IsCancellable is std::false_type if
764 // CallbackCancellationTraits<>::IsCancelled returns always false.
765 // Otherwise, it's std::true_type.
766 : BindState(IsCancellable{},
767 invoke_func,
768 std::forward<ForwardFunctor>(functor),
769 std::forward<ForwardBoundArgs>(bound_args)...) {}
770
771 Functor functor_;
772 std::tuple<BoundArgs...> bound_args_;
773
774 private:
775 template <typename ForwardFunctor, typename... ForwardBoundArgs>
776 explicit BindState(std::true_type,
777 BindStateBase::InvokeFuncStorage invoke_func,
778 ForwardFunctor&& functor,
779 ForwardBoundArgs&&... bound_args)
780 : BindStateBase(invoke_func,
781 &Destroy,
782 &ApplyCancellationTraits<BindState>),
783 functor_(std::forward<ForwardFunctor>(functor)),
784 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
785 DCHECK(!IsNull(functor_));
786 }
787
788 template <typename ForwardFunctor, typename... ForwardBoundArgs>
789 explicit BindState(std::false_type,
790 BindStateBase::InvokeFuncStorage invoke_func,
791 ForwardFunctor&& functor,
792 ForwardBoundArgs&&... bound_args)
793 : BindStateBase(invoke_func, &Destroy),
794 functor_(std::forward<ForwardFunctor>(functor)),
795 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
796 DCHECK(!IsNull(functor_));
797 }
798
799 ~BindState() = default;
800
801 static void Destroy(const BindStateBase* self) {
802 delete static_cast<const BindState*>(self);
803 }
804 };
805
806 // Used to implement MakeBindStateType.
807 template <bool is_method, typename Functor, typename... BoundArgs>
808 struct MakeBindStateTypeImpl;
809
810 template <typename Functor, typename... BoundArgs>
811 struct MakeBindStateTypeImpl<false, Functor, BoundArgs...> {
812 static_assert(!HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>::value,
813 "A parameter is a refcounted type and needs scoped_refptr.");
814 using Type = BindState<std::decay_t<Functor>, std::decay_t<BoundArgs>...>;
815 };
816
817 template <typename Functor>
818 struct MakeBindStateTypeImpl<true, Functor> {
819 using Type = BindState<std::decay_t<Functor>>;
820 };
821
822 template <typename Functor, typename Receiver, typename... BoundArgs>
823 struct MakeBindStateTypeImpl<true, Functor, Receiver, BoundArgs...> {
824 private:
825 using DecayedReceiver = std::decay_t<Receiver>;
826
827 static_assert(!std::is_array<std::remove_reference_t<Receiver>>::value,
828 "First bound argument to a method cannot be an array.");
829 static_assert(
830 !std::is_pointer<DecayedReceiver>::value ||
831 IsRefCountedType<std::remove_pointer_t<DecayedReceiver>>::value,
832 "Receivers may not be raw pointers. If using a raw pointer here is safe"
833 " and has no lifetime concerns, use base::Unretained() and document why"
834 " it's safe.");
835 static_assert(!HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>::value,
836 "A parameter is a refcounted type and needs scoped_refptr.");
837
838 public:
839 using Type = BindState<
840 std::decay_t<Functor>,
841 std::conditional_t<std::is_pointer<DecayedReceiver>::value,
842 scoped_refptr<std::remove_pointer_t<DecayedReceiver>>,
843 DecayedReceiver>,
844 std::decay_t<BoundArgs>...>;
845 };
846
847 template <typename Functor, typename... BoundArgs>
848 using MakeBindStateType =
849 typename MakeBindStateTypeImpl<MakeFunctorTraits<Functor>::is_method,
850 Functor,
851 BoundArgs...>::Type;
852
853 } // namespace internal
854
855 // An injection point to control |this| pointer behavior on a method invocation.
856 // If IsWeakReceiver<> is true_type for |T| and |T| is used for a receiver of a
857 // method, base::Bind cancels the method invocation if the receiver is tested as
858 // false.
859 // E.g. Foo::bar() is not called:
860 // struct Foo : base::SupportsWeakPtr<Foo> {
861 // void bar() {}
862 // };
863 //
864 // WeakPtr<Foo> oo = nullptr;
865 // base::Bind(&Foo::bar, oo).Run();
866 template <typename T>
867 struct IsWeakReceiver : std::false_type {};
868
869 template <typename T>
870 struct IsWeakReceiver<internal::ConstRefWrapper<T>> : IsWeakReceiver<T> {};
871
872 template <typename T>
873 struct IsWeakReceiver<WeakPtr<T>> : std::true_type {};
874
875 // An injection point to control how bound objects passed to the target
876 // function. BindUnwrapTraits<>::Unwrap() is called for each bound objects right
877 // before the target function is invoked.
878 template <typename>
879 struct BindUnwrapTraits {
880 template <typename T>
881 static T&& Unwrap(T&& o) {
882 return std::forward<T>(o);
883 }
884 };
885
886 template <typename T>
887 struct BindUnwrapTraits<internal::UnretainedWrapper<T>> {
888 static T* Unwrap(const internal::UnretainedWrapper<T>& o) { return o.get(); }
889 };
890
891 template <typename T>
892 struct BindUnwrapTraits<internal::ConstRefWrapper<T>> {
893 static const T& Unwrap(const internal::ConstRefWrapper<T>& o) {
894 return o.get();
895 }
896 };
897
898 template <typename T>
899 struct BindUnwrapTraits<internal::RetainedRefWrapper<T>> {
900 static T* Unwrap(const internal::RetainedRefWrapper<T>& o) { return o.get(); }
901 };
902
903 template <typename T>
904 struct BindUnwrapTraits<internal::OwnedWrapper<T>> {
905 static T* Unwrap(const internal::OwnedWrapper<T>& o) { return o.get(); }
906 };
907
908 template <typename T>
909 struct BindUnwrapTraits<internal::PassedWrapper<T>> {
910 static T Unwrap(const internal::PassedWrapper<T>& o) { return o.Take(); }
911 };
912
913 // CallbackCancellationTraits allows customization of Callback's cancellation
914 // semantics. By default, callbacks are not cancellable. A specialization should
915 // set is_cancellable = true and implement an IsCancelled() that returns if the
916 // callback should be cancelled.
917 template <typename Functor, typename BoundArgsTuple, typename SFINAE>
918 struct CallbackCancellationTraits {
919 static constexpr bool is_cancellable = false;
920 };
921
922 // Specialization for method bound to weak pointer receiver.
923 template <typename Functor, typename... BoundArgs>
924 struct CallbackCancellationTraits<
925 Functor,
926 std::tuple<BoundArgs...>,
927 std::enable_if_t<
928 internal::IsWeakMethod<internal::FunctorTraits<Functor>::is_method,
929 BoundArgs...>::value>> {
930 static constexpr bool is_cancellable = true;
931
932 template <typename Receiver, typename... Args>
933 static bool IsCancelled(const Functor&,
934 const Receiver& receiver,
935 const Args&...) {
936 return !receiver;
937 }
938 };
939
940 // Specialization for a nested bind.
941 template <typename Signature, typename... BoundArgs>
942 struct CallbackCancellationTraits<OnceCallback<Signature>,
943 std::tuple<BoundArgs...>> {
944 static constexpr bool is_cancellable = true;
945
946 template <typename Functor>
947 static bool IsCancelled(const Functor& functor, const BoundArgs&...) {
948 return functor.IsCancelled();
949 }
950 };
951
952 template <typename Signature, typename... BoundArgs>
953 struct CallbackCancellationTraits<RepeatingCallback<Signature>,
954 std::tuple<BoundArgs...>> {
955 static constexpr bool is_cancellable = true;
956
957 template <typename Functor>
958 static bool IsCancelled(const Functor& functor, const BoundArgs&...) {
959 return functor.IsCancelled();
960 }
961 };
962
963 // Returns a RunType of bound functor.
964 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C).
965 template <typename Functor, typename... BoundArgs>
966 using MakeUnboundRunType =
967 typename internal::BindTypeHelper<Functor, BoundArgs...>::UnboundRunType;
968
969 } // namespace base
970
971 #endif // BASE_BIND_INTERNAL_H_
972