1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef BASE_FUNCTIONAL_BIND_INTERNAL_H_
6 #define BASE_FUNCTIONAL_BIND_INTERNAL_H_
13 #include <type_traits>
16 #include "base/allocator/partition_allocator/src/partition_alloc/partition_alloc_buildflags.h"
17 #include "base/allocator/partition_allocator/src/partition_alloc/partition_alloc_config.h"
18 #include "base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr.h"
19 #include "base/check.h"
20 #include "base/compiler_specific.h"
21 #include "base/functional/callback_internal.h"
22 #include "base/functional/disallow_unretained.h"
23 #include "base/functional/unretained_traits.h"
24 #include "base/memory/raw_ptr.h"
25 #include "base/memory/raw_ptr_asan_bound_arg_tracker.h"
26 #include "base/memory/raw_ref.h"
27 #include "base/memory/raw_scoped_refptr_mismatch_checker.h"
28 #include "base/memory/weak_ptr.h"
29 #include "base/notreached.h"
30 #include "base/types/always_false.h"
31 #include "build/build_config.h"
32 #include "third_party/abseil-cpp/absl/functional/function_ref.h"
34 // See base/functional/callback.h for user documentation.
38 // Functor -- A movable type representing something that should be called.
39 // All function pointers and Callback<> are functors even if the
40 // invocation syntax differs.
41 // RunType -- A function type (as opposed to function _pointer_ type) for
42 // a Callback<>::Run(). Usually just a convenience typedef.
43 // (Bound)Args -- A set of types that stores the arguments.
46 // ForceVoidReturn<> -- Helper class for translating function signatures to
47 // equivalent forms with a "void" return type.
48 // FunctorTraits<> -- Type traits used to determine the correct RunType and
49 // invocation manner for a Functor. This is where function
50 // signature adapters are applied.
51 // StorageTraits<> -- Type traits that determine how a bound argument is
52 // stored in BindState.
53 // InvokeHelper<> -- Take a Functor + arguments and actually invokes it.
54 // Handle the differing syntaxes needed for WeakPtr<>
55 // support. This is separate from Invoker to avoid creating
56 // multiple version of Invoker<>.
57 // Invoker<> -- Unwraps the curried parameters and executes the Functor.
58 // BindState<> -- Stores the curried parameters, and is the main entry point
59 // into the Bind() system.
67 } // namespace Microsoft
73 struct IsWeakReceiver;
76 struct BindUnwrapTraits;
78 template <typename Functor, typename BoundArgsTuple, typename SFINAE = void>
79 struct CallbackCancellationTraits;
81 template <typename Signature>
84 namespace unretained_traits {
86 // UnretainedWrapper will check and report if pointer is dangling upon
88 struct MayNotDangle {};
89 // UnretainedWrapper won't check if pointer is dangling upon invocation. For
90 // extra safety, the receiver must be of type MayBeDangling<>.
92 // UnretainedWrapper won't check if pointer is dangling upon invocation. The
93 // receiver doesn't have to be a raw_ptr<>. This is just a temporary state, to
94 // allow dangling pointers that would otherwise crash if MayNotDangle was used.
95 // It should be replaced ASAP with MayNotDangle (after fixing the dangling
96 // pointers) or with MayDangle if there is really no other way (after making
97 // receivers MayBeDangling<>).
98 struct MayDangleUntriaged {};
100 } // namespace unretained_traits
104 template <typename Functor, typename SFINAE = void>
105 struct FunctorTraits;
107 template <typename T,
108 typename UnretainedTrait,
109 RawPtrTraits PtrTraits = RawPtrTraits::kEmpty>
110 class UnretainedWrapper {
111 // Note that if PtrTraits already includes MayDangle, DanglingRawPtrType
112 // will be identical to `raw_ptr<T, PtrTraits>`.
113 using DanglingRawPtrType = MayBeDangling<T, PtrTraits>;
116 // We want the getter type to match the receiver parameter that it is passed
117 // into, to minimize `raw_ptr<T>` <-> `T*` conversions. We also would like to
118 // match `StorageType`, but sometimes we can't have both, as shown in
119 // https://docs.google.com/document/d/1dLM34aKqbNBfRdOYxxV_T-zQU4J5wjmXwIBJZr7JvZM/edit
120 // When we can't have both, prefer the former, mostly because
121 // `GetPtrType`=`raw_ptr<T>` would break if e.g. UnretainedWrapper() is
122 // constructed using `char*`, but the receiver is of type `std::string&`.
123 // This is enforced by static_asserts in base::internal::AssertConstructible.
124 using GetPtrType = std::conditional_t<
125 raw_ptr_traits::IsSupportedType<T>::value &&
126 std::is_same_v<UnretainedTrait, unretained_traits::MayDangle>,
130 static_assert(TypeSupportsUnretainedV<T>,
131 "Callback cannot capture an unprotected C++ pointer since this "
132 "Type is annotated with DISALLOW_UNRETAINED(). Please see "
133 "base/functional/disallow_unretained.h for alternatives.");
135 // Raw pointer makes sense only if there are no PtrTraits. If there are,
136 // it means that a `raw_ptr` is being passed, so use the ctors below instead.
137 template <RawPtrTraits PTraits = PtrTraits,
138 typename = std::enable_if_t<PTraits == RawPtrTraits::kEmpty>>
139 explicit UnretainedWrapper(T* o) : ptr_(o) {}
141 // Trick to only instantiate these constructors if they are used. Otherwise,
142 // instantiating UnretainedWrapper with a T that is not supported by
143 // raw_ptr would trigger raw_ptr<T>'s static_assert.
144 template <typename U = T>
145 explicit UnretainedWrapper(const raw_ptr<U, PtrTraits>& o) : ptr_(o) {}
146 template <typename U = T>
147 explicit UnretainedWrapper(raw_ptr<U, PtrTraits>&& o) : ptr_(std::move(o)) {}
149 GetPtrType get() const { return GetInternal(ptr_); }
152 // `ptr_` is either a `raw_ptr` or a regular C++ pointer.
153 template <typename U>
154 static GetPtrType GetInternal(U* ptr) {
155 static_assert(std::is_same_v<T, U>);
158 template <typename U, RawPtrTraits Traits>
159 static GetPtrType GetInternal(const raw_ptr<U, Traits>& ptr) {
160 static_assert(std::is_same_v<T, U>);
161 if constexpr (std::is_same_v<UnretainedTrait,
162 unretained_traits::MayNotDangle>) {
163 ptr.ReportIfDangling();
168 // `Unretained()` arguments often dangle by design (a common design pattern
169 // is to manage an object's lifetime inside the callback itself, using
170 // stateful information), so disable direct dangling pointer detection
173 // If the callback is invoked, dangling pointer detection will be triggered
174 // before invoking the bound functor (unless stated otherwise, see
175 // `UnsafeDangling()` and `UnsafeDanglingUntriaged()`), when retrieving the
176 // pointer value via `get()` above.
178 std::conditional_t<raw_ptr_traits::IsSupportedType<T>::value,
181 // Avoid converting between different `raw_ptr` types when calling `get()`.
182 // It is allowable to convert `raw_ptr<T>` -> `T*`, but not in the other
183 // direction. See the comment by `GetPtrType` describing for more details.
184 static_assert(std::is_pointer_v<GetPtrType> ||
185 std::is_same_v<GetPtrType, StorageType>);
189 // Storage type for std::reference_wrapper so `BindState` can internally store
190 // unprotected references using raw_ref.
192 // std::reference_wrapper<T> and T& do not work, since the reference lifetime is
193 // not safely protected by MiraclePtr.
195 // UnretainedWrapper<T> and raw_ptr<T> do not work, since BindUnwrapTraits would
196 // try to pass by T* rather than T&.
197 template <typename T,
198 typename UnretainedTrait,
199 RawPtrTraits PtrTraits = RawPtrTraits::kEmpty>
200 class UnretainedRefWrapper {
203 TypeSupportsUnretainedV<T>,
204 "Callback cannot capture an unprotected C++ reference since this "
205 "type is annotated with DISALLOW_UNRETAINED(). Please see "
206 "base/functional/disallow_unretained.h for alternatives.");
208 // Raw reference makes sense only if there are no PtrTraits. If there are,
209 // it means that a `raw_ref` is being passed, so use the ctors below instead.
210 template <RawPtrTraits PTraits = PtrTraits,
211 typename = std::enable_if_t<PTraits == RawPtrTraits::kEmpty>>
212 explicit UnretainedRefWrapper(T& o) : ref_(o) {}
214 // Trick to only instantiate these constructors if they are used. Otherwise,
215 // instantiating UnretainedWrapper with a T that is not supported by
216 // raw_ref would trigger raw_ref<T>'s static_assert.
217 template <typename U = T>
218 explicit UnretainedRefWrapper(const raw_ref<U, PtrTraits>& o) : ref_(o) {}
219 template <typename U = T>
220 explicit UnretainedRefWrapper(raw_ref<U, PtrTraits>&& o)
221 : ref_(std::move(o)) {}
223 T& get() const { return GetInternal(ref_); }
226 // `ref_` is either a `raw_ref` or a regular C++ reference.
227 template <typename U>
228 static T& GetInternal(U& ref) {
229 static_assert(std::is_same_v<T, U>);
232 template <typename U, RawPtrTraits Traits>
233 static T& GetInternal(const raw_ref<U, Traits>& ref) {
234 static_assert(std::is_same_v<T, U>);
235 // The ultimate goal is to crash when a callback is invoked with a
236 // dangling pointer. This is checked here. For now, it is configured to
237 // either crash, DumpWithoutCrashing or be ignored. This depends on the
238 // PartitionAllocUnretainedDanglingPtr feature.
239 if constexpr (std::is_same_v<UnretainedTrait,
240 unretained_traits::MayNotDangle>) {
241 ref.ReportIfDangling();
243 // We can't use operator* here, we need to use raw_ptr's GetForExtraction
244 // instead of GetForDereference. If we did use GetForDereference then we'd
245 // crash in ASAN builds on calling a bound callback with a dangling
246 // reference parameter even if that parameter is not used. This could hide
247 // a later unprotected issue that would be reached in release builds.
251 // `Unretained()` arguments often dangle by design (a common design pattern
252 // is to manage an object's lifetime inside the callback itself, using
253 // stateful information), so disable direct dangling pointer detection
256 // If the callback is invoked, dangling pointer detection will be triggered
257 // before invoking the bound functor (unless stated otherwise, see
258 // `UnsafeDangling()` and `UnsafeDanglingUntriaged()`), when retrieving the
259 // pointer value via `get()` above.
261 std::conditional_t<raw_ptr_traits::IsSupportedType<T>::value,
262 raw_ref<T, DisableDanglingPtrDetection>,
268 // The class is used to wrap `UnretainedRefWrapper` when the latter is used as
269 // a method receiver (a reference on `this` argument). This is needed because
270 // the internal callback mechanism expects the receiver to have the type
271 // `MyClass*` and to have `operator*`.
272 // This is used as storage.
273 template <typename T, typename UnretainedTrait, RawPtrTraits PtrTraits>
274 class UnretainedRefWrapperReceiver {
276 // NOLINTNEXTLINE(google-explicit-constructor)
277 UnretainedRefWrapperReceiver(
278 UnretainedRefWrapper<T, UnretainedTrait, PtrTraits>&& obj)
279 : obj_(std::move(obj)) {}
280 // NOLINTNEXTLINE(google-explicit-constructor)
281 T& operator*() const { return obj_.get(); }
284 UnretainedRefWrapper<T, UnretainedTrait, PtrTraits> obj_;
287 // MethodReceiverStorageType converts the current receiver type to its stored
288 // type. For instance, it converts pointers to `scoped_refptr`, and wraps
289 // `UnretainedRefWrapper` to make it compliant with the internal callback
290 // invocation mechanism.
291 template <typename T>
292 struct MethodReceiverStorageType {
294 std::conditional_t<IsPointerV<T>, scoped_refptr<RemovePointerT<T>>, T>;
297 template <typename T, typename UnretainedTrait, RawPtrTraits PtrTraits>
298 struct MethodReceiverStorageType<
299 UnretainedRefWrapper<T, UnretainedTrait, PtrTraits>> {
300 // We can't use UnretainedRefWrapper as a receiver directly (see
301 // UnretainedRefWrapperReceiver for why).
302 using Type = UnretainedRefWrapperReceiver<T, UnretainedTrait, PtrTraits>;
305 template <typename T>
306 class RetainedRefWrapper {
308 explicit RetainedRefWrapper(T* o) : ptr_(o) {}
309 explicit RetainedRefWrapper(scoped_refptr<T> o) : ptr_(std::move(o)) {}
310 T* get() const { return ptr_.get(); }
313 scoped_refptr<T> ptr_;
316 template <typename T>
317 struct IgnoreResultHelper {
318 explicit IgnoreResultHelper(T functor) : functor_(std::move(functor)) {}
319 explicit operator bool() const { return !!functor_; }
324 template <typename T, typename Deleter = std::default_delete<T>>
327 explicit OwnedWrapper(T* o) : ptr_(o) {}
328 explicit OwnedWrapper(std::unique_ptr<T, Deleter>&& ptr)
329 : ptr_(std::move(ptr)) {}
330 T* get() const { return ptr_.get(); }
333 std::unique_ptr<T, Deleter> ptr_;
336 template <typename T>
337 class OwnedRefWrapper {
339 explicit OwnedRefWrapper(const T& t) : t_(t) {}
340 explicit OwnedRefWrapper(T&& t) : t_(std::move(t)) {}
341 T& get() const { return t_; }
347 // PassedWrapper is a copyable adapter for a scoper that ignores const.
349 // It is needed to get around the fact that Bind() takes a const reference to
350 // all its arguments. Because Bind() takes a const reference to avoid
351 // unnecessary copies, it is incompatible with movable-but-not-copyable
352 // types; doing a destructive "move" of the type into Bind() would violate
353 // the const correctness.
355 // This conundrum cannot be solved without either C++11 rvalue references or
356 // a O(2^n) blowup of Bind() templates to handle each combination of regular
357 // types and movable-but-not-copyable types. Thus we introduce a wrapper type
358 // that is copyable to transmit the correct type information down into
359 // BindState<>. Ignoring const in this type makes sense because it is only
360 // created when we are explicitly trying to do a destructive move.
363 // 1) PassedWrapper supports any type that has a move constructor, however
364 // the type will need to be specifically allowed in order for it to be
365 // bound to a Callback. We guard this explicitly at the call of Passed()
366 // to make for clear errors. Things not given to Passed() will be forwarded
367 // and stored by value which will not work for general move-only types.
368 // 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL"
369 // scoper to a Callback and allow the Callback to execute once.
370 template <typename T>
371 class PassedWrapper {
373 explicit PassedWrapper(T&& scoper) : scoper_(std::move(scoper)) {}
374 PassedWrapper(PassedWrapper&& other)
375 : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {}
379 return std::move(scoper_);
383 mutable bool is_valid_ = true;
387 template <typename T>
388 using Unwrapper = BindUnwrapTraits<std::decay_t<T>>;
390 template <typename T>
391 decltype(auto) Unwrap(T&& o) {
392 return Unwrapper<T>::Unwrap(std::forward<T>(o));
395 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a
396 // method. It is used internally by Bind() to select the correct
397 // InvokeHelper that will no-op itself in the event the WeakPtr<> for
398 // the target object is invalidated.
400 // The first argument should be the type of the object that will be received by
402 template <bool is_method, typename... Args>
403 struct IsWeakMethod : std::false_type {};
405 template <typename T, typename... Args>
406 struct IsWeakMethod<true, T, Args...> : IsWeakReceiver<T> {};
408 // Packs a list of types to hold them in a single type.
409 template <typename... Types>
412 // Used for DropTypeListItem implementation.
413 template <size_t n, typename List>
414 struct DropTypeListItemImpl;
416 // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure.
417 template <size_t n, typename T, typename... List>
418 struct DropTypeListItemImpl<n, TypeList<T, List...>>
419 : DropTypeListItemImpl<n - 1, TypeList<List...>> {};
421 template <typename T, typename... List>
422 struct DropTypeListItemImpl<0, TypeList<T, List...>> {
423 using Type = TypeList<T, List...>;
427 struct DropTypeListItemImpl<0, TypeList<>> {
428 using Type = TypeList<>;
431 // A type-level function that drops |n| list item from given TypeList.
432 template <size_t n, typename List>
433 using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type;
435 // Used for TakeTypeListItem implementation.
436 template <size_t n, typename List, typename... Accum>
437 struct TakeTypeListItemImpl;
439 // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure.
440 template <size_t n, typename T, typename... List, typename... Accum>
441 struct TakeTypeListItemImpl<n, TypeList<T, List...>, Accum...>
442 : TakeTypeListItemImpl<n - 1, TypeList<List...>, Accum..., T> {};
444 template <typename T, typename... List, typename... Accum>
445 struct TakeTypeListItemImpl<0, TypeList<T, List...>, Accum...> {
446 using Type = TypeList<Accum...>;
449 template <typename... Accum>
450 struct TakeTypeListItemImpl<0, TypeList<>, Accum...> {
451 using Type = TypeList<Accum...>;
454 // A type-level function that takes first |n| list item from given TypeList.
455 // E.g. TakeTypeListItem<3, TypeList<A, B, C, D>> is evaluated to
456 // TypeList<A, B, C>.
457 template <size_t n, typename List>
458 using TakeTypeListItem = typename TakeTypeListItemImpl<n, List>::Type;
460 // Used for ConcatTypeLists implementation.
461 template <typename List1, typename List2>
462 struct ConcatTypeListsImpl;
464 template <typename... Types1, typename... Types2>
465 struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> {
466 using Type = TypeList<Types1..., Types2...>;
469 // A type-level function that concats two TypeLists.
470 template <typename List1, typename List2>
471 using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type;
473 // Used for MakeFunctionType implementation.
474 template <typename R, typename ArgList>
475 struct MakeFunctionTypeImpl;
477 template <typename R, typename... Args>
478 struct MakeFunctionTypeImpl<R, TypeList<Args...>> {
479 // MSVC 2013 doesn't support Type Alias of function types.
480 // Revisit this after we update it to newer version.
481 typedef R Type(Args...);
484 // A type-level function that constructs a function type that has |R| as its
485 // return type and has TypeLists items as its arguments.
486 template <typename R, typename ArgList>
487 using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type;
489 // Used for ExtractArgs and ExtractReturnType.
490 template <typename Signature>
491 struct ExtractArgsImpl;
493 template <typename R, typename... Args>
494 struct ExtractArgsImpl<R(Args...)> {
495 using ReturnType = R;
496 using ArgsList = TypeList<Args...>;
499 // A type-level function that extracts function arguments into a TypeList.
500 // E.g. ExtractArgs<R(A, B, C)> is evaluated to TypeList<A, B, C>.
501 template <typename Signature>
502 using ExtractArgs = typename ExtractArgsImpl<Signature>::ArgsList;
504 // A type-level function that extracts the return type of a function.
505 // E.g. ExtractReturnType<R(A, B, C)> is evaluated to R.
506 template <typename Signature>
507 using ExtractReturnType = typename ExtractArgsImpl<Signature>::ReturnType;
509 template <typename Callable,
510 typename Signature = decltype(&Callable::operator())>
511 struct ExtractCallableRunTypeImpl;
513 template <typename Callable, typename R, typename... Args>
514 struct ExtractCallableRunTypeImpl<Callable, R (Callable::*)(Args...)> {
515 using Type = R(Args...);
518 template <typename Callable, typename R, typename... Args>
519 struct ExtractCallableRunTypeImpl<Callable, R (Callable::*)(Args...) const> {
520 using Type = R(Args...);
523 template <typename Callable, typename R, typename... Args>
524 struct ExtractCallableRunTypeImpl<Callable, R (Callable::*)(Args...) noexcept> {
525 using Type = R(Args...);
528 template <typename Callable, typename R, typename... Args>
529 struct ExtractCallableRunTypeImpl<Callable,
530 R (Callable::*)(Args...) const noexcept> {
531 using Type = R(Args...);
534 // Evaluated to RunType of the given callable type.
536 // auto f = [](int, char*) { return 0.1; };
537 // ExtractCallableRunType<decltype(f)>
539 // double(int, char*);
540 template <typename Callable>
541 using ExtractCallableRunType =
542 typename ExtractCallableRunTypeImpl<Callable>::Type;
544 // IsCallableObject<Functor> is std::true_type if |Functor| has operator().
545 // Otherwise, it's std::false_type.
547 // IsCallableObject<void(*)()>::value is false.
550 // IsCallableObject<void(Foo::*)()>::value is false.
554 // IsCallableObject<decltype(f)>::value is false.
555 template <typename Functor, typename SFINAE = void>
556 struct IsCallableObject : std::false_type {};
558 template <typename Callable>
559 struct IsCallableObject<Callable, std::void_t<decltype(&Callable::operator())>>
562 // HasRefCountedTypeAsRawPtr inherits from true_type when any of the |Args| is a
563 // raw pointer to a RefCounted type.
564 template <typename... Ts>
565 struct HasRefCountedTypeAsRawPtr
566 : std::disjunction<NeedsScopedRefptrButGetsRawPtr<Ts>...> {};
570 // Set of templates that support forcing the function return type to void.
571 template <typename Sig>
572 struct ForceVoidReturn;
574 template <typename R, typename... Args>
575 struct ForceVoidReturn<R(Args...)> {
576 using RunType = void(Args...);
581 // See description at top of file.
582 template <typename Functor, typename SFINAE>
583 struct FunctorTraits;
585 // For callable types.
586 // This specialization handles lambdas (captureless and capturing) and functors
587 // with a call operator. Capturing lambdas and stateful functors are explicitly
588 // disallowed by BindImpl().
592 // // Captureless lambdas are allowed.
593 // [] { return 42; };
595 // // Capturing lambdas are *not* allowed.
597 // [x] { return x; };
599 // // Any empty class with operator() is allowed.
601 // void operator()() const {}
602 // // No non-static member variable and no virtual functions.
604 template <typename Functor>
605 struct FunctorTraits<Functor,
606 std::enable_if_t<IsCallableObject<Functor>::value>> {
607 using RunType = ExtractCallableRunType<Functor>;
608 static constexpr bool is_method = false;
609 static constexpr bool is_nullable = false;
610 static constexpr bool is_callback = false;
611 static constexpr bool is_stateless = std::is_empty_v<Functor>;
613 template <typename RunFunctor, typename... RunArgs>
614 static ExtractReturnType<RunType> Invoke(RunFunctor&& functor,
616 return std::forward<RunFunctor>(functor)(std::forward<RunArgs>(args)...);
621 template <typename R, typename... Args>
622 struct FunctorTraits<R (*)(Args...)> {
623 using RunType = R(Args...);
624 static constexpr bool is_method = false;
625 static constexpr bool is_nullable = true;
626 static constexpr bool is_callback = false;
627 static constexpr bool is_stateless = true;
629 template <typename Function, typename... RunArgs>
630 static R Invoke(Function&& function, RunArgs&&... args) {
631 return std::forward<Function>(function)(std::forward<RunArgs>(args)...);
635 #if BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS)
638 template <typename R, typename... Args>
639 struct FunctorTraits<R(__stdcall*)(Args...)> {
640 using RunType = R(Args...);
641 static constexpr bool is_method = false;
642 static constexpr bool is_nullable = true;
643 static constexpr bool is_callback = false;
644 static constexpr bool is_stateless = true;
646 template <typename... RunArgs>
647 static R Invoke(R(__stdcall* function)(Args...), RunArgs&&... args) {
648 return function(std::forward<RunArgs>(args)...);
653 template <typename R, typename... Args>
654 struct FunctorTraits<R(__fastcall*)(Args...)> {
655 using RunType = R(Args...);
656 static constexpr bool is_method = false;
657 static constexpr bool is_nullable = true;
658 static constexpr bool is_callback = false;
659 static constexpr bool is_stateless = true;
661 template <typename... RunArgs>
662 static R Invoke(R(__fastcall* function)(Args...), RunArgs&&... args) {
663 return function(std::forward<RunArgs>(args)...);
667 #endif // BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS)
671 // Support for Objective-C blocks. Blocks can be bound as the compiler will
672 // ensure their lifetimes will be correctly managed.
674 #if HAS_FEATURE(objc_arc)
676 template <typename R, typename... Args>
677 struct FunctorTraits<R (^)(Args...)> {
678 using RunType = R(Args...);
679 static constexpr bool is_method = false;
680 static constexpr bool is_nullable = true;
681 static constexpr bool is_callback = false;
682 static constexpr bool is_stateless = true;
684 template <typename BlockType, typename... RunArgs>
685 static R Invoke(BlockType&& block, RunArgs&&... args) {
686 // According to LLVM documentation (§ 6.3), "local variables of automatic
687 // storage duration do not have precise lifetime." Use objc_precise_lifetime
688 // to ensure that the Objective-C block is not deallocated until it has
689 // finished executing even if the Callback<> is destroyed during the block
691 // https://clang.llvm.org/docs/AutomaticReferenceCounting.html#precise-lifetime-semantics
692 __attribute__((objc_precise_lifetime)) R (^scoped_block)(Args...) = block;
693 return scoped_block(std::forward<RunArgs>(args)...);
697 #endif // HAS_FEATURE(objc_arc)
701 template <typename R, typename Receiver, typename... Args>
702 struct FunctorTraits<R (Receiver::*)(Args...)> {
703 using RunType = R(Receiver*, Args...);
704 static constexpr bool is_method = true;
705 static constexpr bool is_nullable = true;
706 static constexpr bool is_callback = false;
707 static constexpr bool is_stateless = true;
709 template <typename Method, typename ReceiverPtr, typename... RunArgs>
710 static R Invoke(Method method,
711 ReceiverPtr&& receiver_ptr,
713 return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...);
717 // For const methods.
718 template <typename R, typename Receiver, typename... Args>
719 struct FunctorTraits<R (Receiver::*)(Args...) const> {
720 using RunType = R(const Receiver*, Args...);
721 static constexpr bool is_method = true;
722 static constexpr bool is_nullable = true;
723 static constexpr bool is_callback = false;
724 static constexpr bool is_stateless = true;
726 template <typename Method, typename ReceiverPtr, typename... RunArgs>
727 static R Invoke(Method method,
728 ReceiverPtr&& receiver_ptr,
730 return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...);
734 #if BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS)
736 // For __stdcall methods.
737 template <typename R, typename Receiver, typename... Args>
738 struct FunctorTraits<R (__stdcall Receiver::*)(Args...)>
739 : public FunctorTraits<R (Receiver::*)(Args...)> {};
741 // For __stdcall const methods.
742 template <typename R, typename Receiver, typename... Args>
743 struct FunctorTraits<R (__stdcall Receiver::*)(Args...) const>
744 : public FunctorTraits<R (Receiver::*)(Args...) const> {};
746 #endif // BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS)
748 #ifdef __cpp_noexcept_function_type
749 // noexcept makes a distinct function type in C++17.
750 // I.e. `void(*)()` and `void(*)() noexcept` are same in pre-C++17, and
751 // different in C++17.
752 template <typename R, typename... Args>
753 struct FunctorTraits<R (*)(Args...) noexcept> : FunctorTraits<R (*)(Args...)> {
756 template <typename R, typename Receiver, typename... Args>
757 struct FunctorTraits<R (Receiver::*)(Args...) noexcept>
758 : FunctorTraits<R (Receiver::*)(Args...)> {};
760 template <typename R, typename Receiver, typename... Args>
761 struct FunctorTraits<R (Receiver::*)(Args...) const noexcept>
762 : FunctorTraits<R (Receiver::*)(Args...) const> {};
765 // For IgnoreResults.
766 template <typename T>
767 struct FunctorTraits<IgnoreResultHelper<T>> : FunctorTraits<T> {
769 typename ForceVoidReturn<typename FunctorTraits<T>::RunType>::RunType;
771 template <typename IgnoreResultType, typename... RunArgs>
772 static void Invoke(IgnoreResultType&& ignore_result_helper,
774 FunctorTraits<T>::Invoke(
775 std::forward<IgnoreResultType>(ignore_result_helper).functor_,
776 std::forward<RunArgs>(args)...);
780 // For OnceCallbacks.
781 template <typename R, typename... Args>
782 struct FunctorTraits<OnceCallback<R(Args...)>> {
783 using RunType = R(Args...);
784 static constexpr bool is_method = false;
785 static constexpr bool is_nullable = true;
786 static constexpr bool is_callback = true;
787 static constexpr bool is_stateless = true;
789 template <typename CallbackType, typename... RunArgs>
790 static R Invoke(CallbackType&& callback, RunArgs&&... args) {
791 DCHECK(!callback.is_null());
792 return std::forward<CallbackType>(callback).Run(
793 std::forward<RunArgs>(args)...);
797 // For RepeatingCallbacks.
798 template <typename R, typename... Args>
799 struct FunctorTraits<RepeatingCallback<R(Args...)>> {
800 using RunType = R(Args...);
801 static constexpr bool is_method = false;
802 static constexpr bool is_nullable = true;
803 static constexpr bool is_callback = true;
804 static constexpr bool is_stateless = true;
806 template <typename CallbackType, typename... RunArgs>
807 static R Invoke(CallbackType&& callback, RunArgs&&... args) {
808 DCHECK(!callback.is_null());
809 return std::forward<CallbackType>(callback).Run(
810 std::forward<RunArgs>(args)...);
814 template <typename Functor>
815 using MakeFunctorTraits = FunctorTraits<std::decay_t<Functor>>;
819 // See description at top of file.
820 template <typename T>
821 struct StorageTraits {
825 // For T*, store as UnretainedWrapper<T> for safety, as it internally uses
826 // raw_ptr<T> (when possible).
827 template <typename T>
828 struct StorageTraits<T*> {
829 using Type = UnretainedWrapper<T, unretained_traits::MayNotDangle>;
832 // For raw_ptr<T>, store as UnretainedWrapper<T> for safety. This may seem
833 // contradictory, but this ensures guaranteed protection for the pointer even
834 // during execution of callbacks with parameters of type raw_ptr<T>.
835 template <typename T, RawPtrTraits PtrTraits>
836 struct StorageTraits<raw_ptr<T, PtrTraits>> {
837 using Type = UnretainedWrapper<T, unretained_traits::MayNotDangle, PtrTraits>;
840 // Unwrap std::reference_wrapper and store it in a custom wrapper so that
841 // references are also protected with raw_ptr<T>.
842 template <typename T>
843 struct StorageTraits<std::reference_wrapper<T>> {
844 using Type = UnretainedRefWrapper<T, unretained_traits::MayNotDangle>;
847 template <typename T>
848 using MakeStorageType = typename StorageTraits<std::decay_t<T>>::Type;
852 // There are 2 logical InvokeHelper<> specializations: normal, WeakCalls.
854 // The normal type just calls the underlying runnable.
856 // WeakCalls need special syntax that is applied to the first argument to check
857 // if they should no-op themselves.
858 template <bool is_weak_call, typename ReturnType, size_t... indices>
861 template <typename ReturnType, size_t... indices>
862 struct InvokeHelper<false, ReturnType, indices...> {
863 template <typename Functor, typename BoundArgsTuple, typename... RunArgs>
864 static inline ReturnType MakeItSo(Functor&& functor,
865 BoundArgsTuple&& bound,
867 using Traits = MakeFunctorTraits<Functor>;
868 return Traits::Invoke(
869 std::forward<Functor>(functor),
870 Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))...,
871 std::forward<RunArgs>(args)...);
875 template <typename ReturnType, size_t index_target, size_t... index_tail>
876 struct InvokeHelper<true, ReturnType, index_target, index_tail...> {
877 // WeakCalls are only supported for functions with a void return type.
878 // Otherwise, the function result would be undefined if the WeakPtr<>
880 static_assert(std::is_void_v<ReturnType>,
881 "weak_ptrs can only bind to methods without return values");
883 template <typename Functor, typename BoundArgsTuple, typename... RunArgs>
884 static inline void MakeItSo(Functor&& functor,
885 BoundArgsTuple&& bound,
887 static_assert(index_target == 0);
888 // Note the validity of the weak pointer should be tested _after_ it is
889 // unwrapped, otherwise it creates a race for weak pointer implementations
890 // that allow cross-thread usage and perform `Lock()` in Unwrap() traits.
891 const auto& target = Unwrap(std::get<0>(bound));
895 using Traits = MakeFunctorTraits<Functor>;
897 std::forward<Functor>(functor), target,
898 Unwrap(std::get<index_tail>(std::forward<BoundArgsTuple>(bound)))...,
899 std::forward<RunArgs>(args)...);
905 // See description at the top of the file.
906 template <typename StorageType, typename UnboundRunType>
909 template <typename StorageType, typename R, typename... UnboundArgs>
910 struct Invoker<StorageType, R(UnboundArgs...)> {
911 static R RunOnce(BindStateBase* base,
912 PassingType<UnboundArgs>... unbound_args) {
913 // Local references to make debugger stepping easier. If in a debugger,
914 // you really want to warp ahead and step through the
915 // InvokeHelper<>::MakeItSo() call below.
916 StorageType* storage = static_cast<StorageType*>(base);
917 static constexpr size_t num_bound_args =
918 std::tuple_size_v<decltype(storage->bound_args_)>;
919 return RunImpl(std::move(storage->functor_),
920 std::move(storage->bound_args_),
921 std::make_index_sequence<num_bound_args>(),
922 std::forward<UnboundArgs>(unbound_args)...);
925 static R Run(BindStateBase* base, PassingType<UnboundArgs>... unbound_args) {
926 // Local references to make debugger stepping easier. If in a debugger,
927 // you really want to warp ahead and step through the
928 // InvokeHelper<>::MakeItSo() call below.
929 const StorageType* storage = static_cast<StorageType*>(base);
930 static constexpr size_t num_bound_args =
931 std::tuple_size_v<decltype(storage->bound_args_)>;
932 return RunImpl(storage->functor_, storage->bound_args_,
933 std::make_index_sequence<num_bound_args>(),
934 std::forward<UnboundArgs>(unbound_args)...);
938 template <typename Functor, typename BoundArgsTuple, size_t... indices>
939 static inline R RunImpl(Functor&& functor,
940 BoundArgsTuple&& bound,
941 std::index_sequence<indices...> seq,
942 UnboundArgs&&... unbound_args) {
943 static constexpr bool is_method = MakeFunctorTraits<Functor>::is_method;
945 using DecayedArgsTuple = std::decay_t<BoundArgsTuple>;
947 #if BUILDFLAG(USE_ASAN_BACKUP_REF_PTR)
948 RawPtrAsanBoundArgTracker raw_ptr_asan_bound_arg_tracker;
949 raw_ptr_asan_bound_arg_tracker.AddArgs(
950 std::get<indices>(std::forward<BoundArgsTuple>(bound))...,
951 std::forward<UnboundArgs>(unbound_args)...);
952 #endif // BUILDFLAG(USE_ASAN_BACKUP_REF_PTR)
954 static constexpr bool is_weak_call =
955 IsWeakMethod<is_method,
956 std::tuple_element_t<indices, DecayedArgsTuple>...>();
958 // Do not `Unwrap()` here, as that immediately triggers dangling pointer
959 // detection. Dangling pointer detection should only be triggered if the
960 // callback is not cancelled, but cancellation status is not determined
961 // until later inside the InvokeHelper::MakeItSo specialization for weak
964 // Dangling pointers when invoking a cancelled callback are not considered
965 // a memory safety error because protecting raw pointers usage with weak
966 // receivers (where the weak receiver usually own the pointed objects) is a
967 // common and broadly used pattern in the codebase.
968 return InvokeHelper<is_weak_call, R, indices...>::MakeItSo(
969 std::forward<Functor>(functor), std::forward<BoundArgsTuple>(bound),
970 std::forward<UnboundArgs>(unbound_args)...);
974 // Extracts necessary type info from Functor and BoundArgs.
975 // Used to implement MakeUnboundRunType, BindOnce and BindRepeating.
976 template <typename Functor, typename... BoundArgs>
977 struct BindTypeHelper {
978 static constexpr size_t num_bounds = sizeof...(BoundArgs);
979 using FunctorTraits = MakeFunctorTraits<Functor>;
982 // When Functor is `double (Foo::*)(int, const std::string&)`, and BoundArgs
983 // is a template pack of `Foo*` and `int16_t`:
984 // - RunType is `double(Foo*, int, const std::string&)`,
985 // - ReturnType is `double`,
986 // - RunParamsList is `TypeList<Foo*, int, const std::string&>`,
987 // - BoundParamsList is `TypeList<Foo*, int>`,
988 // - UnboundParamsList is `TypeList<const std::string&>`,
989 // - BoundArgsList is `TypeList<Foo*, int16_t>`,
990 // - UnboundRunType is `double(const std::string&)`.
991 using RunType = typename FunctorTraits::RunType;
992 using ReturnType = ExtractReturnType<RunType>;
994 using RunParamsList = ExtractArgs<RunType>;
995 using BoundParamsList = TakeTypeListItem<num_bounds, RunParamsList>;
996 using UnboundParamsList = DropTypeListItem<num_bounds, RunParamsList>;
998 using BoundArgsList = TypeList<BoundArgs...>;
1000 using UnboundRunType = MakeFunctionType<ReturnType, UnboundParamsList>;
1003 template <typename Functor>
1004 std::enable_if_t<FunctorTraits<Functor>::is_nullable, bool> IsNull(
1005 const Functor& functor) {
1009 template <typename Functor>
1010 std::enable_if_t<!FunctorTraits<Functor>::is_nullable, bool> IsNull(
1015 // Used by QueryCancellationTraits below.
1016 template <typename Functor, typename BoundArgsTuple, size_t... indices>
1017 bool QueryCancellationTraitsImpl(BindStateBase::CancellationQueryMode mode,
1018 const Functor& functor,
1019 const BoundArgsTuple& bound_args,
1020 std::index_sequence<indices...>) {
1022 case BindStateBase::IS_CANCELLED:
1023 return CallbackCancellationTraits<Functor, BoundArgsTuple>::IsCancelled(
1024 functor, std::get<indices>(bound_args)...);
1025 case BindStateBase::MAYBE_VALID:
1026 return CallbackCancellationTraits<Functor, BoundArgsTuple>::MaybeValid(
1027 functor, std::get<indices>(bound_args)...);
1033 // Relays |base| to corresponding CallbackCancellationTraits<>::Run(). Returns
1034 // true if the callback |base| represents is canceled.
1035 template <typename BindStateType>
1036 bool QueryCancellationTraits(const BindStateBase* base,
1037 BindStateBase::CancellationQueryMode mode) {
1038 const BindStateType* storage = static_cast<const BindStateType*>(base);
1039 static constexpr size_t num_bound_args =
1040 std::tuple_size_v<decltype(storage->bound_args_)>;
1041 return QueryCancellationTraitsImpl(
1042 mode, storage->functor_, storage->bound_args_,
1043 std::make_index_sequence<num_bound_args>());
1046 // The base case of BanUnconstructedRefCountedReceiver that checks nothing.
1047 template <typename Functor, typename Receiver, typename... Unused>
1049 !(MakeFunctorTraits<Functor>::is_method &&
1050 IsPointerV<std::decay_t<Receiver>> &&
1051 IsRefCountedType<RemovePointerT<std::decay_t<Receiver>>>::value)>
1052 BanUnconstructedRefCountedReceiver(const Receiver& receiver, Unused&&...) {}
1054 template <typename Functor>
1055 void BanUnconstructedRefCountedReceiver() {}
1057 // Asserts that Callback is not the first owner of a ref-counted receiver.
1058 template <typename Functor, typename Receiver, typename... Unused>
1060 MakeFunctorTraits<Functor>::is_method &&
1061 IsPointerV<std::decay_t<Receiver>> &&
1062 IsRefCountedType<RemovePointerT<std::decay_t<Receiver>>>::value>
1063 BanUnconstructedRefCountedReceiver(const Receiver& receiver, Unused&&...) {
1066 // It's error prone to make the implicit first reference to ref-counted types.
1067 // In the example below, base::BindOnce() would make the implicit first
1068 // reference to the ref-counted Foo. If PostTask() failed or the posted task
1069 // ran fast enough, the newly created instance could be destroyed before `oo`
1070 // makes another reference.
1072 // base::ThreadPool::PostTask(FROM_HERE, base::BindOnce(&Foo::Bar, this));
1075 // scoped_refptr<Foo> oo = new Foo();
1077 // Hence, base::Bind{Once,Repeating}() refuses to create the first reference
1078 // to ref-counted objects, and DCHECK()s otherwise. As above, that typically
1079 // happens around PostTask() in their constructor, and such objects can be
1080 // destroyed before `new` returns if the task resolves fast enough.
1082 // Instead of doing the above, please consider adding a static constructor,
1083 // and keep the first reference alive explicitly.
1085 // scoped_refptr<Foo> Foo::Create() {
1086 // auto foo = base::WrapRefCounted(new Foo());
1087 // base::ThreadPool::PostTask(FROM_HERE, base::BindOnce(&Foo::Bar, foo));
1093 // scoped_refptr<Foo> oo = Foo::Create();
1094 DCHECK(receiver->HasAtLeastOneRef());
1099 // This stores all the state passed into Bind().
1100 template <typename Functor, typename... BoundArgs>
1101 struct BindState final : BindStateBase {
1102 using IsCancellable = std::bool_constant<
1103 CallbackCancellationTraits<Functor,
1104 std::tuple<BoundArgs...>>::is_cancellable>;
1105 template <typename ForwardFunctor, typename... ForwardBoundArgs>
1106 static BindState* Create(BindStateBase::InvokeFuncStorage invoke_func,
1107 ForwardFunctor&& functor,
1108 ForwardBoundArgs&&... bound_args) {
1109 // Ban ref counted receivers that were not yet fully constructed to avoid
1110 // a common pattern of racy situation.
1111 BanUnconstructedRefCountedReceiver<ForwardFunctor>(bound_args...);
1113 // IsCancellable is std::false_type if
1114 // CallbackCancellationTraits<>::IsCancelled returns always false.
1115 // Otherwise, it's std::true_type.
1116 return new BindState(IsCancellable{}, invoke_func,
1117 std::forward<ForwardFunctor>(functor),
1118 std::forward<ForwardBoundArgs>(bound_args)...);
1122 std::tuple<BoundArgs...> bound_args_;
1125 static constexpr bool is_nested_callback =
1126 MakeFunctorTraits<Functor>::is_callback;
1128 template <typename ForwardFunctor, typename... ForwardBoundArgs>
1129 explicit BindState(std::true_type,
1130 BindStateBase::InvokeFuncStorage invoke_func,
1131 ForwardFunctor&& functor,
1132 ForwardBoundArgs&&... bound_args)
1133 : BindStateBase(invoke_func,
1135 &QueryCancellationTraits<BindState>),
1136 functor_(std::forward<ForwardFunctor>(functor)),
1137 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
1138 // We check the validity of nested callbacks (e.g., Bind(callback, ...)) in
1139 // release builds to avoid null pointers from ending up in posted tasks,
1140 // causing hard-to-diagnose crashes. Ideally we'd do this for all functors
1141 // here, but that would have a large binary size impact.
1142 if (is_nested_callback) {
1143 CHECK(!IsNull(functor_));
1145 DCHECK(!IsNull(functor_));
1149 template <typename ForwardFunctor, typename... ForwardBoundArgs>
1150 explicit BindState(std::false_type,
1151 BindStateBase::InvokeFuncStorage invoke_func,
1152 ForwardFunctor&& functor,
1153 ForwardBoundArgs&&... bound_args)
1154 : BindStateBase(invoke_func, &Destroy),
1155 functor_(std::forward<ForwardFunctor>(functor)),
1156 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
1157 // See above for CHECK/DCHECK rationale.
1158 if (is_nested_callback) {
1159 CHECK(!IsNull(functor_));
1161 DCHECK(!IsNull(functor_));
1165 ~BindState() = default;
1167 static void Destroy(const BindStateBase* self) {
1168 delete static_cast<const BindState*>(self);
1172 // Used to implement MakeBindStateType.
1173 template <bool is_method, typename Functor, typename... BoundArgs>
1174 struct MakeBindStateTypeImpl;
1176 template <typename Functor, typename... BoundArgs>
1177 struct MakeBindStateTypeImpl<false, Functor, BoundArgs...> {
1178 static_assert(!HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>::value,
1179 "A parameter is a refcounted type and needs scoped_refptr.");
1180 using Type = BindState<std::decay_t<Functor>, MakeStorageType<BoundArgs>...>;
1183 template <typename Functor>
1184 struct MakeBindStateTypeImpl<true, Functor> {
1185 using Type = BindState<std::decay_t<Functor>>;
1188 template <typename Functor, typename Receiver, typename... BoundArgs>
1189 struct MakeBindStateTypeImpl<true, Functor, Receiver, BoundArgs...> {
1191 using DecayedReceiver = std::decay_t<Receiver>;
1192 static_assert(!std::is_array_v<std::remove_reference_t<Receiver>>,
1193 "First bound argument to a method cannot be an array.");
1195 !IsRawRefV<DecayedReceiver>,
1196 "Receivers may not be raw_ref<T>. If using a raw_ref<T> here is safe"
1197 " and has no lifetime concerns, use base::Unretained() and document why"
1200 !IsPointerV<DecayedReceiver> ||
1201 IsRefCountedType<RemovePointerT<DecayedReceiver>>::value,
1202 "Receivers may not be raw pointers. If using a raw pointer here is safe"
1203 " and has no lifetime concerns, use base::Unretained() and document why"
1206 static_assert(!HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>::value,
1207 "A parameter is a refcounted type and needs scoped_refptr.");
1209 using ReceiverStorageType =
1210 typename MethodReceiverStorageType<DecayedReceiver>::Type;
1213 using Type = BindState<std::decay_t<Functor>,
1214 ReceiverStorageType,
1215 MakeStorageType<BoundArgs>...>;
1218 template <typename Functor, typename... BoundArgs>
1219 using MakeBindStateType =
1220 typename MakeBindStateTypeImpl<MakeFunctorTraits<Functor>::is_method,
1222 BoundArgs...>::Type;
1224 // Returns a RunType of bound functor.
1225 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C).
1226 template <typename Functor, typename... BoundArgs>
1227 using MakeUnboundRunType =
1228 typename BindTypeHelper<Functor, BoundArgs...>::UnboundRunType;
1230 // The implementation of TransformToUnwrappedType below.
1231 template <bool is_once, typename T>
1232 struct TransformToUnwrappedTypeImpl;
1234 template <typename T>
1235 struct TransformToUnwrappedTypeImpl<true, T> {
1236 using StoredType = std::decay_t<T>;
1237 using ForwardType = StoredType&&;
1238 using Unwrapped = decltype(Unwrap(std::declval<ForwardType>()));
1241 template <typename T>
1242 struct TransformToUnwrappedTypeImpl<false, T> {
1243 using StoredType = std::decay_t<T>;
1244 using ForwardType = const StoredType&;
1245 using Unwrapped = decltype(Unwrap(std::declval<ForwardType>()));
1248 // Transform |T| into `Unwrapped` type, which is passed to the target function.
1250 // In is_once == true case,
1251 // `int&&` -> `int&&`,
1252 // `const int&` -> `int&&`,
1253 // `OwnedWrapper<int>&` -> `int*&&`.
1254 // In is_once == false case,
1255 // `int&&` -> `const int&`,
1256 // `const int&` -> `const int&`,
1257 // `OwnedWrapper<int>&` -> `int* const &`.
1258 template <bool is_once, typename T>
1259 using TransformToUnwrappedType =
1260 typename TransformToUnwrappedTypeImpl<is_once, T>::Unwrapped;
1262 // Transforms |Args| into `Unwrapped` types, and packs them into a TypeList.
1263 // If |is_method| is true, tries to dereference the first argument to support
1265 template <bool is_once, bool is_method, typename... Args>
1266 struct MakeUnwrappedTypeListImpl {
1267 using Type = TypeList<TransformToUnwrappedType<is_once, Args>...>;
1270 // Performs special handling for this pointers.
1273 // std::unique_ptr<int> -> int*.
1274 template <bool is_once, typename Receiver, typename... Args>
1275 struct MakeUnwrappedTypeListImpl<is_once, true, Receiver, Args...> {
1276 using ReceiverStorageType =
1277 typename MethodReceiverStorageType<std::decay_t<Receiver>>::Type;
1278 using UnwrappedReceiver =
1279 TransformToUnwrappedType<is_once, ReceiverStorageType>;
1280 using Type = TypeList<decltype(&*std::declval<UnwrappedReceiver>()),
1281 TransformToUnwrappedType<is_once, Args>...>;
1284 template <bool is_once, bool is_method, typename... Args>
1285 using MakeUnwrappedTypeList =
1286 typename MakeUnwrappedTypeListImpl<is_once, is_method, Args...>::Type;
1288 // IsOnceCallback<T> is a std::true_type if |T| is a OnceCallback.
1289 template <typename T>
1290 struct IsOnceCallback : std::false_type {};
1292 template <typename Signature>
1293 struct IsOnceCallback<OnceCallback<Signature>> : std::true_type {};
1295 // IsUnretainedMayDangle is true if StorageType is of type
1296 // `UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraits>.
1297 // Note that it is false for unretained_traits::MayDangleUntriaged.
1298 template <typename StorageType>
1299 inline constexpr bool IsUnretainedMayDangle = false;
1300 template <typename T, RawPtrTraits PtrTraits>
1301 inline constexpr bool IsUnretainedMayDangle<
1302 UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraits>> = true;
1304 // UnretainedAndRawPtrHaveCompatibleTraits is true if StorageType is of type
1305 // `UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraits1>` and
1306 // FunctionParamType is of type `raw_ptr<T, PtrTraits2>`, and the former's
1307 // ::GetPtrType is the same type as the latter.
1308 template <typename StorageType, typename FunctionParamType>
1309 inline constexpr bool UnretainedAndRawPtrHaveCompatibleTraits = false;
1310 template <typename T,
1311 RawPtrTraits PtrTraitsInUnretained,
1312 RawPtrTraits PtrTraitsInReceiver>
1313 inline constexpr bool UnretainedAndRawPtrHaveCompatibleTraits<
1314 UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraitsInUnretained>,
1315 raw_ptr<T, PtrTraitsInReceiver>> =
1317 typename UnretainedWrapper<T,
1318 unretained_traits::MayDangle,
1319 PtrTraitsInUnretained>::GetPtrType,
1320 raw_ptr<T, PtrTraitsInReceiver>>;
1322 // Helpers to make error messages slightly more readable.
1324 struct BindArgument {
1325 template <typename ForwardingType>
1326 struct ForwardedAs {
1327 template <typename FunctorParamType>
1328 struct ToParamWithType {
1329 static constexpr bool kNotARawPtr = !IsRawPtrV<FunctorParamType>;
1331 static constexpr bool kCanBeForwardedToBoundFunctor =
1332 std::is_convertible_v<ForwardingType, FunctorParamType>;
1334 // If the bound type can't be forwarded then test if `FunctorParamType` is
1335 // a non-const lvalue reference and a reference to the unwrapped type
1336 // *could* have been successfully forwarded.
1337 static constexpr bool kNonConstRefParamMustBeWrapped =
1338 kCanBeForwardedToBoundFunctor ||
1339 !(std::is_lvalue_reference_v<FunctorParamType> &&
1340 !std::is_const_v<std::remove_reference_t<FunctorParamType>> &&
1341 std::is_convertible_v<std::decay_t<ForwardingType>&,
1344 // Note that this intentionally drops the const qualifier from
1345 // `ForwardingType`, to test if it *could* have been successfully
1346 // forwarded if `Passed()` had been used.
1347 static constexpr bool kMoveOnlyTypeMustUseBasePassed =
1348 kCanBeForwardedToBoundFunctor ||
1349 !std::is_convertible_v<std::decay_t<ForwardingType>&&,
1354 template <typename BoundAsType>
1356 template <typename StorageType>
1358 static constexpr bool kBindArgumentCanBeCaptured =
1359 std::is_constructible_v<StorageType, BoundAsType>;
1360 // Note that this intentionally drops the const qualifier from
1361 // `BoundAsType`, to test if it *could* have been successfully bound if
1362 // `std::move()` had been used.
1363 static constexpr bool kMoveOnlyTypeMustUseStdMove =
1364 kBindArgumentCanBeCaptured ||
1365 !std::is_constructible_v<StorageType, std::decay_t<BoundAsType>&&>;
1369 template <typename FunctionParamType>
1370 struct ToParamWithType {
1371 template <typename StorageType>
1373 template <bool is_method>
1374 // true if we are handling `this` parameter.
1375 static constexpr bool kParamIsThisPointer = is_method && i == 0;
1376 // true if the current parameter is of type `raw_ptr<T>` with
1377 // `RawPtrTraits::kMayDangle` trait (e.g. `MayBeDangling<T>`).
1378 static constexpr bool kParamIsDanglingRawPtr =
1379 IsRawPtrMayDangleV<FunctionParamType>;
1380 // true if the bound parameter is of type
1381 // `UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraits>`.
1382 static constexpr bool kBoundPtrMayDangle =
1383 IsUnretainedMayDangle<StorageType>;
1384 // true if bound parameter of type `UnretainedWrapper` and parameter of
1385 // type `raw_ptr` have compatible `RawPtrTraits`.
1386 static constexpr bool kMayBeDanglingTraitsCorrectness =
1387 UnretainedAndRawPtrHaveCompatibleTraits<StorageType,
1389 // true if the receiver argument **must** be of type `MayBeDangling<T>`.
1390 static constexpr bool kMayBeDanglingMustBeUsed =
1391 kBoundPtrMayDangle && kParamIsDanglingRawPtr;
1394 // - bound parameter is of type
1395 // `UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraits>`
1396 // - the receiving argument is of type `MayBeDangling<T>`
1397 template <bool is_method>
1398 static constexpr bool kMayBeDanglingPtrPassedCorrectly =
1399 kParamIsThisPointer<is_method> ||
1400 kBoundPtrMayDangle == kParamIsDanglingRawPtr;
1403 // - MayBeDangling<T> must not be used as receiver parameter.
1405 // - MayBeDangling<T> must be used as receiver parameter and its traits
1406 // are matching Unretained traits.
1407 static constexpr bool kUnsafeDanglingAndMayBeDanglingHaveMatchingTraits =
1408 !kMayBeDanglingMustBeUsed || kMayBeDanglingTraitsCorrectness;
1413 // Helper to assert that parameter |i| of type |Arg| can be bound, which means:
1414 // - |Arg| can be retained internally as |Storage|.
1415 // - |Arg| can be forwarded as |Unwrapped| to |Param|.
1422 struct AssertConstructible {
1424 // We forbid callbacks to use raw_ptr as a parameter. However, we allow
1425 // MayBeDangling<T> iff the callback argument was created using
1426 // `base::UnsafeDangling`.
1428 BindArgument<i>::template ForwardedAs<
1429 Unwrapped>::template ToParamWithType<Param>::kNotARawPtr ||
1430 BindArgument<i>::template ToParamWithType<Param>::template StoredAs<
1431 Storage>::kMayBeDanglingMustBeUsed,
1432 "base::Bind() target functor has a parameter of type raw_ptr<T>. "
1433 "raw_ptr<T> should not be used for function parameters, please use T* or "
1436 // A bound functor must take a dangling pointer argument (e.g. bound using the
1437 // UnsafeDangling helper) as a MayBeDangling<T>, to make it clear that the
1438 // pointee's lifetime must be externally validated before using it. For
1439 // methods, exempt a bound receiver (i.e. the this pointer) as it is not
1440 // passed as a regular function argument.
1442 BindArgument<i>::template ToParamWithType<Param>::template StoredAs<
1443 Storage>::template kMayBeDanglingPtrPassedCorrectly<is_method>,
1444 "base::UnsafeDangling() pointers must be received by functors with "
1445 "MayBeDangling<T> as parameter.");
1448 BindArgument<i>::template ToParamWithType<Param>::template StoredAs<
1449 Storage>::kUnsafeDanglingAndMayBeDanglingHaveMatchingTraits,
1450 "MayBeDangling<T> parameter must receive the same RawPtrTraits as the "
1451 "one passed to the corresponding base::UnsafeDangling() call.");
1453 // With `BindRepeating`, there are two decision points for how to handle a
1456 // 1. Whether the move-only argument should be moved into the internal
1457 // `BindState`. Either `std::move()` or `Passed` is sufficient to trigger
1458 // move-only semantics.
1459 // 2. Whether or not the bound, move-only argument should be moved to the
1460 // bound functor when invoked. When the argument is bound with `Passed`,
1461 // invoking the callback will destructively move the bound, move-only
1462 // argument to the bound functor. In contrast, if the argument is bound
1463 // with `std::move()`, `RepeatingCallback` will attempt to call the bound
1464 // functor with a constant reference to the bound, move-only argument. This
1465 // will fail if the bound functor accepts that argument by value, since the
1466 // argument cannot be copied. It is this latter case that this
1467 // static_assert aims to catch.
1469 // In contrast, `BindOnce()` only has one decision point. Once a move-only
1470 // type is captured by value into the internal `BindState`, the bound,
1471 // move-only argument will always be moved to the functor when invoked.
1472 // Failure to use std::move will simply fail the `kMoveOnlyTypeMustUseStdMove`
1473 // assert below instead.
1475 // Note: `Passed()` is a legacy of supporting move-only types when repeating
1476 // callbacks were the only callback type. A `RepeatingCallback` with a
1477 // `Passed()` argument is really a `OnceCallback` and should eventually be
1480 BindArgument<i>::template ForwardedAs<Unwrapped>::
1481 template ToParamWithType<Param>::kMoveOnlyTypeMustUseBasePassed,
1482 "base::BindRepeating() argument is a move-only type. Use base::Passed() "
1483 "instead of std::move() to transfer ownership from the callback to the "
1486 BindArgument<i>::template ForwardedAs<Unwrapped>::
1487 template ToParamWithType<Param>::kNonConstRefParamMustBeWrapped,
1488 "Bound argument for non-const reference parameter must be wrapped in "
1489 "std::ref() or base::OwnedRef().");
1491 BindArgument<i>::template ForwardedAs<Unwrapped>::
1492 template ToParamWithType<Param>::kCanBeForwardedToBoundFunctor,
1493 "Type mismatch between bound argument and bound functor's parameter.");
1495 static_assert(BindArgument<i>::template BoundAs<Arg>::template StoredAs<
1496 Storage>::kMoveOnlyTypeMustUseStdMove,
1497 "Attempting to bind a move-only type. Use std::move() to "
1498 "transfer ownership to the created callback.");
1499 // In practice, this static_assert should be quite rare as the storage type
1500 // is deduced from the arguments passed to `BindOnce()`/`BindRepeating()`.
1502 BindArgument<i>::template BoundAs<Arg>::template StoredAs<
1503 Storage>::kBindArgumentCanBeCaptured,
1504 "Cannot capture argument: is the argument copyable or movable?");
1507 // Takes three same-length TypeLists, and applies AssertConstructible for each
1509 template <bool is_method,
1512 typename UnwrappedTypeList,
1513 typename ParamsList>
1514 struct AssertBindArgsValidity;
1516 template <bool is_method,
1519 typename... Unwrapped,
1521 struct AssertBindArgsValidity<is_method,
1522 std::index_sequence<Ns...>,
1524 TypeList<Unwrapped...>,
1525 TypeList<Params...>>
1526 : AssertConstructible<Ns,
1532 static constexpr bool ok = true;
1535 template <typename T>
1536 struct AssertBindArgIsNotBasePassed : public std::true_type {};
1538 template <typename T>
1539 struct AssertBindArgIsNotBasePassed<PassedWrapper<T>> : public std::false_type {
1542 template <template <typename> class CallbackT,
1545 decltype(auto) BindImpl(Functor&& functor, Args&&... args) {
1546 // This block checks if each |args| matches to the corresponding params of the
1547 // target function. This check does not affect the behavior of Bind, but its
1548 // error message should be more readable.
1549 static constexpr bool kIsOnce = IsOnceCallback<CallbackT<void()>>::value;
1550 using Helper = BindTypeHelper<Functor, Args...>;
1551 using FunctorTraits = typename Helper::FunctorTraits;
1552 using BoundArgsList = typename Helper::BoundArgsList;
1553 using UnwrappedArgsList =
1554 MakeUnwrappedTypeList<kIsOnce, FunctorTraits::is_method, Args&&...>;
1555 using BoundParamsList = typename Helper::BoundParamsList;
1557 MakeFunctorTraits<Functor>::is_stateless,
1558 "Capturing lambdas and stateful lambdas are intentionally not supported. "
1559 "Please use base::Bind{Once,Repeating} directly to bind arguments.");
1561 AssertBindArgsValidity<FunctorTraits::is_method,
1562 std::make_index_sequence<Helper::num_bounds>,
1563 BoundArgsList, UnwrappedArgsList,
1564 BoundParamsList>::ok,
1565 "The bound args need to be convertible to the target params.");
1567 using BindState = MakeBindStateType<Functor, Args...>;
1568 using UnboundRunType = MakeUnboundRunType<Functor, Args...>;
1569 using Invoker = Invoker<BindState, UnboundRunType>;
1570 using CallbackType = CallbackT<UnboundRunType>;
1572 // Store the invoke func into PolymorphicInvoke before casting it to
1573 // InvokeFuncStorage, so that we can ensure its type matches to
1574 // PolymorphicInvoke, to which CallbackType will cast back.
1575 using PolymorphicInvoke = typename CallbackType::PolymorphicInvoke;
1576 PolymorphicInvoke invoke_func;
1577 if constexpr (kIsOnce) {
1578 invoke_func = Invoker::RunOnce;
1580 invoke_func = Invoker::Run;
1583 using InvokeFuncStorage = BindStateBase::InvokeFuncStorage;
1584 return CallbackType(BindState::Create(
1585 reinterpret_cast<InvokeFuncStorage>(invoke_func),
1586 std::forward<Functor>(functor), std::forward<Args>(args)...));
1589 // Special cases for binding to a base::{Once, Repeating}Callback without extra
1590 // bound arguments. We CHECK() the validity of callback to guard against null
1591 // pointers accidentally ending up in posted tasks, causing hard-to-debug
1593 template <template <typename> class CallbackT,
1595 std::enable_if_t<std::is_same_v<CallbackT<Signature>,
1596 OnceCallback<Signature>>>* = nullptr>
1597 OnceCallback<Signature> BindImpl(OnceCallback<Signature> callback) {
1602 template <template <typename> class CallbackT,
1604 std::enable_if_t<std::is_same_v<CallbackT<Signature>,
1605 OnceCallback<Signature>>>* = nullptr>
1606 OnceCallback<Signature> BindImpl(RepeatingCallback<Signature> callback) {
1611 template <template <typename> class CallbackT,
1613 std::enable_if_t<std::is_same_v<CallbackT<Signature>,
1614 RepeatingCallback<Signature>>>* =
1616 RepeatingCallback<Signature> BindImpl(RepeatingCallback<Signature> callback) {
1621 template <template <typename> class CallbackT, typename Signature>
1622 auto BindImpl(absl::FunctionRef<Signature>, ...) {
1624 AlwaysFalse<Signature>,
1625 "base::Bind{Once,Repeating} require strong ownership: non-owning "
1626 "function references may not bound as the functor due to potential "
1627 "lifetime issues.");
1631 template <template <typename> class CallbackT, typename Signature>
1632 auto BindImpl(FunctionRef<Signature>, ...) {
1634 AlwaysFalse<Signature>,
1635 "base::Bind{Once,Repeating} require strong ownership: non-owning "
1636 "function references may not bound as the functor due to potential "
1637 "lifetime issues.");
1641 } // namespace internal
1643 // An injection point to control |this| pointer behavior on a method invocation.
1644 // If IsWeakReceiver<> is true_type for |T| and |T| is used for a receiver of a
1645 // method, base::Bind cancels the method invocation if the receiver is tested as
1647 // E.g. Foo::bar() is not called:
1648 // struct Foo : base::SupportsWeakPtr<Foo> {
1652 // WeakPtr<Foo> oo = nullptr;
1653 // base::BindOnce(&Foo::bar, oo).Run();
1654 template <typename T>
1655 struct IsWeakReceiver : std::false_type {};
1657 template <typename T>
1658 struct IsWeakReceiver<std::reference_wrapper<T>> : IsWeakReceiver<T> {};
1660 template <typename T>
1661 struct IsWeakReceiver<WeakPtr<T>> : std::true_type {};
1663 // An injection point to control how objects are checked for maybe validity,
1664 // which is an optimistic thread-safe check for full validity.
1666 struct MaybeValidTraits {
1667 template <typename T>
1668 static bool MaybeValid(const T& o) {
1669 return o.MaybeValid();
1673 // An injection point to control how bound objects passed to the target
1674 // function. BindUnwrapTraits<>::Unwrap() is called for each bound objects right
1675 // before the target function is invoked.
1677 struct BindUnwrapTraits {
1678 template <typename T>
1679 static T&& Unwrap(T&& o) {
1680 return std::forward<T>(o);
1684 template <typename T, typename UnretainedTrait, RawPtrTraits PtrTraits>
1685 struct BindUnwrapTraits<
1686 internal::UnretainedWrapper<T, UnretainedTrait, PtrTraits>> {
1688 const internal::UnretainedWrapper<T, UnretainedTrait, PtrTraits>& o) {
1693 template <typename T, typename UnretainedTrait, RawPtrTraits PtrTraits>
1694 struct BindUnwrapTraits<
1695 internal::UnretainedRefWrapper<T, UnretainedTrait, PtrTraits>> {
1697 const internal::UnretainedRefWrapper<T, UnretainedTrait, PtrTraits>& o) {
1702 template <typename T>
1703 struct BindUnwrapTraits<internal::RetainedRefWrapper<T>> {
1704 static T* Unwrap(const internal::RetainedRefWrapper<T>& o) { return o.get(); }
1707 template <typename T, typename Deleter>
1708 struct BindUnwrapTraits<internal::OwnedWrapper<T, Deleter>> {
1709 static T* Unwrap(const internal::OwnedWrapper<T, Deleter>& o) {
1714 template <typename T>
1715 struct BindUnwrapTraits<internal::OwnedRefWrapper<T>> {
1716 static T& Unwrap(const internal::OwnedRefWrapper<T>& o) { return o.get(); }
1719 template <typename T>
1720 struct BindUnwrapTraits<internal::PassedWrapper<T>> {
1721 static T Unwrap(const internal::PassedWrapper<T>& o) { return o.Take(); }
1724 #if BUILDFLAG(IS_WIN)
1725 template <typename T>
1726 struct BindUnwrapTraits<Microsoft::WRL::ComPtr<T>> {
1727 static T* Unwrap(const Microsoft::WRL::ComPtr<T>& ptr) { return ptr.Get(); }
1731 // CallbackCancellationTraits allows customization of Callback's cancellation
1732 // semantics. By default, callbacks are not cancellable. A specialization should
1733 // set is_cancellable = true and implement an IsCancelled() that returns if the
1734 // callback should be cancelled.
1735 template <typename Functor, typename BoundArgsTuple, typename SFINAE>
1736 struct CallbackCancellationTraits {
1737 static constexpr bool is_cancellable = false;
1740 // Specialization for method bound to weak pointer receiver.
1741 template <typename Functor, typename... BoundArgs>
1742 struct CallbackCancellationTraits<
1744 std::tuple<BoundArgs...>,
1746 internal::IsWeakMethod<internal::FunctorTraits<Functor>::is_method,
1747 BoundArgs...>::value>> {
1748 static constexpr bool is_cancellable = true;
1750 template <typename Receiver, typename... Args>
1751 static bool IsCancelled(const Functor&,
1752 const Receiver& receiver,
1757 template <typename Receiver, typename... Args>
1758 static bool MaybeValid(const Functor&,
1759 const Receiver& receiver,
1761 return MaybeValidTraits<Receiver>::MaybeValid(receiver);
1765 // Specialization for a nested bind.
1766 template <typename Signature, typename... BoundArgs>
1767 struct CallbackCancellationTraits<OnceCallback<Signature>,
1768 std::tuple<BoundArgs...>> {
1769 static constexpr bool is_cancellable = true;
1771 template <typename Functor>
1772 static bool IsCancelled(const Functor& functor, const BoundArgs&...) {
1773 return functor.IsCancelled();
1776 template <typename Functor>
1777 static bool MaybeValid(const Functor& functor, const BoundArgs&...) {
1778 return MaybeValidTraits<Functor>::MaybeValid(functor);
1782 template <typename Signature, typename... BoundArgs>
1783 struct CallbackCancellationTraits<RepeatingCallback<Signature>,
1784 std::tuple<BoundArgs...>> {
1785 static constexpr bool is_cancellable = true;
1787 template <typename Functor>
1788 static bool IsCancelled(const Functor& functor, const BoundArgs&...) {
1789 return functor.IsCancelled();
1792 template <typename Functor>
1793 static bool MaybeValid(const Functor& functor, const BoundArgs&...) {
1794 return MaybeValidTraits<Functor>::MaybeValid(functor);
1800 #endif // BASE_FUNCTIONAL_BIND_INTERNAL_H_