xref: /aosp_15_r20/external/cronet/base/functional/bind_internal.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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.
4 
5 #ifndef BASE_FUNCTIONAL_BIND_INTERNAL_H_
6 #define BASE_FUNCTIONAL_BIND_INTERNAL_H_
7 
8 #include <stddef.h>
9 
10 #include <concepts>
11 #include <functional>
12 #include <memory>
13 #include <tuple>
14 #include <type_traits>
15 #include <utility>
16 
17 #include "base/check.h"
18 #include "base/compiler_specific.h"
19 #include "base/functional/callback_internal.h"
20 #include "base/functional/unretained_traits.h"
21 #include "base/memory/raw_ptr.h"
22 #include "base/memory/raw_ptr_asan_bound_arg_tracker.h"
23 #include "base/memory/raw_ref.h"
24 #include "base/memory/raw_scoped_refptr_mismatch_checker.h"
25 #include "base/memory/weak_ptr.h"
26 #include "base/notreached.h"
27 #include "base/types/always_false.h"
28 #include "base/types/is_complete.h"
29 #include "base/types/is_instantiation.h"
30 #include "base/types/to_address.h"
31 #include "build/build_config.h"
32 #include "partition_alloc/partition_alloc_buildflags.h"
33 #include "partition_alloc/partition_alloc_config.h"
34 #include "third_party/abseil-cpp/absl/functional/function_ref.h"
35 
36 // See docs/callback.md for user documentation.
37 //
38 // Concepts:
39 //  Functor -- A movable type representing something that should be called.
40 //             All function pointers and `Callback<>` are functors even if the
41 //             invocation syntax differs.
42 //  RunType -- A function type (as opposed to function _pointer_ type) for
43 //             a `Callback<>::Run()`.  Usually just a convenience typedef.
44 //  (Bound)Args -- A set of types that stores the arguments.
45 //
46 // Types:
47 //  `ForceVoidReturn<>` -- Helper class for translating function signatures to
48 //                         equivalent forms with a `void` return type.
49 //  `FunctorTraits<>` -- Type traits used to determine the correct RunType and
50 //                       invocation manner for a Functor.  This is where
51 //                       function signature adapters are applied.
52 //  `StorageTraits<>` -- Type traits that determine how a bound argument is
53 //                       stored in `BindState<>`.
54 //  `InvokeHelper<>` -- Takes a Functor + arguments and actually invokes it.
55 //                      Handles the differing syntaxes needed for `WeakPtr<>`
56 //                      support.  This is separate from `Invoker<>` to avoid
57 //                      creating multiple versions of `Invoker<>`.
58 //  `Invoker<>` -- Unwraps the curried parameters and executes the Functor.
59 //  `BindState<>` -- Stores the curried parameters, and is the main entry point
60 //                   into the `Bind()` system.
61 
62 #if BUILDFLAG(IS_WIN)
63 namespace Microsoft {
64 namespace WRL {
65 template <typename>
66 class ComPtr;
67 }  // namespace WRL
68 }  // namespace Microsoft
69 #endif
70 
71 namespace base {
72 
73 template <typename T>
74 struct IsWeakReceiver;
75 
76 template <typename>
77 struct BindUnwrapTraits;
78 
79 template <typename Functor, typename BoundArgsTuple>
80 struct CallbackCancellationTraits;
81 
82 template <typename Signature>
83 class FunctionRef;
84 
85 // A tag type to return when `Bind()` calls fail. In this case we intentionally
86 // don't return `void`, since that would produce spurious errors like "variable
87 // has incomplete type 'void'" when assigning the result of
88 // `Bind{Once,Repeating}()` to an `auto`.
89 struct BindFailedCheckPreviousErrors {};
90 
91 namespace unretained_traits {
92 
93 // `UnretainedWrapper` will check and report if pointer is dangling upon
94 // invocation.
95 struct MayNotDangle {};
96 // `UnretainedWrapper` won't check if pointer is dangling upon invocation. For
97 // extra safety, the receiver must be of type `MayBeDangling<>`.
98 struct MayDangle {};
99 // `UnretainedWrapper` won't check if pointer is dangling upon invocation. The
100 // receiver doesn't have to be a `raw_ptr<>`. This is just a temporary state, to
101 // allow dangling pointers that would otherwise crash if `MayNotDangle` was
102 // used. It should be replaced ASAP with `MayNotDangle` (after fixing the
103 // dangling pointers) or with `MayDangle` if there is really no other way (after
104 // making receivers `MayBeDangling<>`).
105 struct MayDangleUntriaged {};
106 
107 }  // namespace unretained_traits
108 
109 namespace internal {
110 
111 template <typename T,
112           typename UnretainedTrait,
113           RawPtrTraits PtrTraits = RawPtrTraits::kEmpty>
114 class UnretainedWrapper {
115   // Note that if `PtrTraits` already includes `MayDangle`, `DanglingRawPtrType`
116   // will be identical to `raw_ptr<T, PtrTraits>`.
117   using DanglingRawPtrType = MayBeDangling<T, PtrTraits>;
118 
119  public:
120   // We want the getter type to match the receiver parameter that it is passed
121   // into, to minimize `raw_ptr<T>` <-> `T*` conversions. We also would like to
122   // match `StorageType`, but sometimes we can't have both, as shown in
123   // https://docs.google.com/document/d/1dLM34aKqbNBfRdOYxxV_T-zQU4J5wjmXwIBJZr7JvZM/edit
124   // When we can't have both, prefer the former, mostly because
125   // `GetPtrType`=`raw_ptr<T>` would break if e.g. `UnretainedWrapper()` is
126   // constructed using `char*`, but the receiver is of type `std::string&`.
127   // This is enforced by `static_assert()`s in `ParamCanBeBound`.
128   using GetPtrType = std::conditional_t<
129       raw_ptr_traits::IsSupportedType<T>::value &&
130           std::same_as<UnretainedTrait, unretained_traits::MayDangle>,
131       DanglingRawPtrType,
132       T*>;
133 
134   // Raw pointer makes sense only if there are no `PtrTrait`s. If there are,
135   // it means that a `raw_ptr` is being passed, so use the ctors below instead.
UnretainedWrapper(T * o)136   explicit UnretainedWrapper(T* o)
137     requires(PtrTraits == RawPtrTraits::kEmpty)
138       : ptr_(o) {
139     VerifyPreconditions();
140   }
141 
UnretainedWrapper(const raw_ptr<T,PtrTraits> & o)142   explicit UnretainedWrapper(const raw_ptr<T, PtrTraits>& o)
143     requires(raw_ptr_traits::IsSupportedType<T>::value)
144       : ptr_(o) {
145     VerifyPreconditions();
146   }
147 
UnretainedWrapper(raw_ptr<T,PtrTraits> && o)148   explicit UnretainedWrapper(raw_ptr<T, PtrTraits>&& o)
149     requires(raw_ptr_traits::IsSupportedType<T>::value)
150       : ptr_(std::move(o)) {
151     VerifyPreconditions();
152   }
153 
get()154   GetPtrType get() const { return GetInternal(ptr_); }
155 
156   // True if this type is valid. When this is false, a `static_assert` will have
157   // been fired explaining why.
158   static constexpr bool value = SupportsUnretained<T>;
159 
160  private:
161   // `ptr_` is either a `raw_ptr` or a regular C++ pointer.
162   template <typename U>
163     requires std::same_as<T, U>
GetInternal(U * ptr)164   static GetPtrType GetInternal(U* ptr) {
165     return ptr;
166   }
167   template <typename U, RawPtrTraits Traits>
168     requires std::same_as<T, U>
GetInternal(const raw_ptr<U,Traits> & ptr)169   static GetPtrType GetInternal(const raw_ptr<U, Traits>& ptr) {
170     if constexpr (std::same_as<UnretainedTrait,
171                                unretained_traits::MayNotDangle>) {
172       ptr.ReportIfDangling();
173     }
174     return ptr;
175   }
176 
177   // `Unretained()` arguments often dangle by design (a common design pattern
178   // is to manage an object's lifetime inside the callback itself, using
179   // stateful information), so disable direct dangling pointer detection
180   // of `ptr_`.
181   //
182   // If the callback is invoked, dangling pointer detection will be triggered
183   // before invoking the bound functor (unless stated otherwise, see
184   // `UnsafeDangling()` and `UnsafeDanglingUntriaged()`), when retrieving the
185   // pointer value via `get()` above.
186   using StorageType =
187       std::conditional_t<raw_ptr_traits::IsSupportedType<T>::value,
188                          DanglingRawPtrType,
189                          T*>;
190   // Avoid converting between different `raw_ptr` types when calling `get()`.
191   // It is allowable to convert `raw_ptr<T>` -> `T*`, but not in the other
192   // direction. See the comment by `GetPtrType` describing for more details.
193   static_assert(std::is_pointer_v<GetPtrType> ||
194                 std::same_as<GetPtrType, StorageType>);
195 
196   // Forces `value` to be materialized, performing a compile-time check of the
197   // preconditions if it hasn't already occurred. This is called from every
198   // constructor so the wrappers in bind.h don't have to each check it, and so
199   // no one can go around them and construct this underlying type directly.
VerifyPreconditions()200   static constexpr void VerifyPreconditions() {
201     // Using `static_assert(value);` here would work but fire an extra error.
202     std::ignore = value;
203   }
204 
205   StorageType ptr_;
206 };
207 
208 // Storage type for `std::reference_wrapper` so `BindState` can internally store
209 // unprotected references using `raw_ref`.
210 //
211 // `std::reference_wrapper<T>` and `T&` do not work, since the reference
212 // lifetime is not safely protected by MiraclePtr.
213 //
214 // `UnretainedWrapper<T>` and `raw_ptr<T>` do not work, since `BindUnwrapTraits`
215 // would try to pass by `T*` rather than `T&`.
216 template <typename T,
217           typename UnretainedTrait,
218           RawPtrTraits PtrTraits = RawPtrTraits::kEmpty>
219 class UnretainedRefWrapper {
220  public:
221   // Raw reference makes sense only if there are no `PtrTrait`s. If there are,
222   // it means that a `raw_ref` is being passed, so use the ctors below instead.
UnretainedRefWrapper(T & o)223   explicit UnretainedRefWrapper(T& o)
224     requires(PtrTraits == RawPtrTraits::kEmpty)
225       : ref_(o) {
226     VerifyPreconditions();
227   }
228 
UnretainedRefWrapper(const raw_ref<T,PtrTraits> & o)229   explicit UnretainedRefWrapper(const raw_ref<T, PtrTraits>& o)
230     requires(raw_ptr_traits::IsSupportedType<T>::value)
231       : ref_(o) {
232     VerifyPreconditions();
233   }
234 
UnretainedRefWrapper(raw_ref<T,PtrTraits> && o)235   explicit UnretainedRefWrapper(raw_ref<T, PtrTraits>&& o)
236     requires(raw_ptr_traits::IsSupportedType<T>::value)
237       : ref_(std::move(o)) {
238     VerifyPreconditions();
239   }
240 
get()241   T& get() const { return GetInternal(ref_); }
242 
243   // See comments in `UnretainedWrapper` regarding this and
244   // `VerifyPreconditions()`.
245   static constexpr bool value = SupportsUnretained<T>;
246 
247  private:
248   // `ref_` is either a `raw_ref` or a regular C++ reference.
249   template <typename U>
250     requires std::same_as<T, U>
GetInternal(U & ref)251   static T& GetInternal(U& ref) {
252     return ref;
253   }
254   template <typename U, RawPtrTraits Traits>
255     requires std::same_as<T, U>
GetInternal(const raw_ref<U,Traits> & ref)256   static T& GetInternal(const raw_ref<U, Traits>& ref) {
257     // The ultimate goal is to crash when a callback is invoked with a
258     // dangling pointer. This is checked here. For now, it is configured to
259     // either crash, DumpWithoutCrashing or be ignored. This depends on the
260     // `PartitionAllocUnretainedDanglingPtr` feature.
261     if constexpr (std::is_same_v<UnretainedTrait,
262                                  unretained_traits::MayNotDangle>) {
263       ref.ReportIfDangling();
264     }
265     // We can't use `operator*` here, we need to use `raw_ptr`'s
266     // `GetForExtraction` instead of `GetForDereference`. If we did use
267     // `GetForDereference` then we'd crash in ASAN builds on calling a bound
268     // callback with a dangling reference parameter even if that parameter is
269     // not used. This could hide a later unprotected issue that would be reached
270     // in release builds.
271     return ref.get();
272   }
273 
274   // `Unretained()` arguments often dangle by design (a common design pattern
275   // is to manage an object's lifetime inside the callback itself, using
276   // stateful information), so disable direct dangling pointer detection
277   // of `ref_`.
278   //
279   // If the callback is invoked, dangling pointer detection will be triggered
280   // before invoking the bound functor (unless stated otherwise, see
281   // `UnsafeDangling()` and `UnsafeDanglingUntriaged()`), when retrieving the
282   // pointer value via `get()` above.
283   using StorageType =
284       std::conditional_t<raw_ptr_traits::IsSupportedType<T>::value,
285                          raw_ref<T, DisableDanglingPtrDetection>,
286                          T&>;
287 
VerifyPreconditions()288   static constexpr void VerifyPreconditions() { std::ignore = value; }
289 
290   StorageType ref_;
291 };
292 
293 // Can't use `is_instantiation` to detect the unretained wrappers, since they
294 // have non-type template params.
295 template <template <typename, typename, RawPtrTraits> typename WrapperT,
296           typename T>
297 inline constexpr bool kIsUnretainedWrapper = false;
298 
299 template <template <typename, typename, RawPtrTraits> typename WrapperT,
300           typename T,
301           typename UnretainedTrait,
302           RawPtrTraits PtrTraits>
303 inline constexpr bool
304     kIsUnretainedWrapper<WrapperT, WrapperT<T, UnretainedTrait, PtrTraits>> =
305         true;
306 
307 // The class is used to wrap `UnretainedRefWrapper` when the latter is used as
308 // a method receiver (a reference on `this` argument). This is needed because
309 // the internal callback mechanism expects the receiver to have the type
310 // `MyClass*` and to have `operator*`.
311 // This is used as storage.
312 template <typename T, typename UnretainedTrait, RawPtrTraits PtrTraits>
313 class UnretainedRefWrapperReceiver {
314  public:
315   // NOLINTNEXTLINE(google-explicit-constructor)
UnretainedRefWrapperReceiver(UnretainedRefWrapper<T,UnretainedTrait,PtrTraits> && obj)316   UnretainedRefWrapperReceiver(
317       UnretainedRefWrapper<T, UnretainedTrait, PtrTraits>&& obj)
318       : obj_(std::move(obj)) {}
319 
320   T& operator*() const { return obj_.get(); }
321   T* operator->() const { return &obj_.get(); }
322 
323  private:
324   UnretainedRefWrapper<T, UnretainedTrait, PtrTraits> obj_;
325 };
326 
327 // `MethodReceiverStorage` converts the current receiver type to its stored
328 // type. For instance, it converts pointers to `scoped_refptr`, and wraps
329 // `UnretainedRefWrapper` to make it compliant with the internal callback
330 // invocation mechanism.
331 template <typename T>
332 struct MethodReceiverStorage {
333   using Type = std::
334       conditional_t<IsRawPointer<T>, scoped_refptr<RemoveRawPointerT<T>>, T>;
335 };
336 
337 template <typename T, typename UnretainedTrait, RawPtrTraits PtrTraits>
338 struct MethodReceiverStorage<
339     UnretainedRefWrapper<T, UnretainedTrait, PtrTraits>> {
340   // We can't use `UnretainedRefWrapper` as a receiver directly (see
341   // `UnretainedRefWrapperReceiver` for why).
342   using Type = UnretainedRefWrapperReceiver<T, UnretainedTrait, PtrTraits>;
343 };
344 
345 template <typename T>
346 class RetainedRefWrapper {
347  public:
348   explicit RetainedRefWrapper(T* o) : ptr_(o) {}
349   explicit RetainedRefWrapper(scoped_refptr<T> o) : ptr_(std::move(o)) {}
350   T* get() const { return ptr_.get(); }
351 
352  private:
353   scoped_refptr<T> ptr_;
354 };
355 
356 template <typename T>
357 struct IgnoreResultHelper {
358   explicit IgnoreResultHelper(T functor) : functor_(std::move(functor)) {}
359   explicit operator bool() const { return !!functor_; }
360 
361   T functor_;
362 };
363 
364 template <typename T, typename Deleter = std::default_delete<T>>
365 class OwnedWrapper {
366  public:
367   explicit OwnedWrapper(T* o) : ptr_(o) {}
368   explicit OwnedWrapper(std::unique_ptr<T, Deleter>&& ptr)
369       : ptr_(std::move(ptr)) {}
370   T* get() const { return ptr_.get(); }
371 
372  private:
373   std::unique_ptr<T, Deleter> ptr_;
374 };
375 
376 template <typename T>
377 class OwnedRefWrapper {
378  public:
379   explicit OwnedRefWrapper(const T& t) : t_(t) {}
380   explicit OwnedRefWrapper(T&& t) : t_(std::move(t)) {}
381   T& get() const { return t_; }
382 
383  private:
384   mutable T t_;
385 };
386 
387 // `PassedWrapper` is a copyable adapter for a scoper that ignores `const`.
388 //
389 // It is needed to get around the fact that `Bind()` takes a const reference to
390 // all its arguments.  Because `Bind()` takes a const reference to avoid
391 // unnecessary copies, it is incompatible with movable-but-not-copyable
392 // types; doing a destructive "move" of the type into `Bind()` would violate
393 // the const correctness.
394 //
395 // This conundrum cannot be solved without either rvalue references or an O(2^n)
396 // blowup of `Bind()` templates to handle each combination of regular types and
397 // movable-but-not-copyable types.  Thus we introduce a wrapper type that is
398 // copyable to transmit the correct type information down into `BindState<>`.
399 // Ignoring `const` in this type makes sense because it is only created when we
400 // are explicitly trying to do a destructive move.
401 //
402 // Two notes:
403 //  1) `PassedWrapper` supports any type that has a move constructor, however
404 //     the type will need to be specifically allowed in order for it to be
405 //     bound to a `Callback`. We guard this explicitly at the call of `Passed()`
406 //     to make for clear errors. Things not given to `Passed()` will be
407 //     forwarded and stored by value which will not work for general move-only
408 //     types.
409 //  2) `is_valid_` is distinct from `nullptr` because it is valid to bind a null
410 //     scoper to a `Callback` and allow the `Callback` to execute once.
411 //
412 // TODO(crbug.com/1326449): We have rvalue references and such now. Remove.
413 template <typename T>
414 class PassedWrapper {
415  public:
416   explicit PassedWrapper(T&& scoper) : scoper_(std::move(scoper)) {}
417   PassedWrapper(PassedWrapper&& other)
418       : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {}
419   T Take() const {
420     CHECK(is_valid_);
421     is_valid_ = false;
422     return std::move(scoper_);
423   }
424 
425  private:
426   mutable bool is_valid_ = true;
427   mutable T scoper_;
428 };
429 
430 template <typename T>
431 using Unwrapper = BindUnwrapTraits<std::decay_t<T>>;
432 
433 template <typename T>
434 decltype(auto) Unwrap(T&& o) {
435   return Unwrapper<T>::Unwrap(std::forward<T>(o));
436 }
437 
438 // `kIsWeakMethod` is a helper that determines if we are binding a `WeakPtr<>`
439 // to a method. It is used internally by `Bind()` to select the correct
440 // `InvokeHelper` that will no-op itself in the event the `WeakPtr<>` for the
441 // target object is invalidated.
442 //
443 // The first argument should be the type of the object that will be received by
444 // the method.
445 template <bool is_method, typename... Args>
446 inline constexpr bool kIsWeakMethod = false;
447 
448 template <typename T, typename... Args>
449 inline constexpr bool kIsWeakMethod<true, T, Args...> =
450     IsWeakReceiver<T>::value;
451 
452 // Packs a list of types to hold them in a single type.
453 template <typename... Types>
454 struct TypeList {};
455 
456 // Implements `DropTypeListItem`.
457 template <size_t n, typename List>
458   requires is_instantiation<TypeList, List>
459 struct DropTypeListItemImpl {
460   using Type = List;
461 };
462 
463 template <size_t n, typename T, typename... List>
464   requires(n > 0)
465 struct DropTypeListItemImpl<n, TypeList<T, List...>>
466     : DropTypeListItemImpl<n - 1, TypeList<List...>> {};
467 
468 // A type-level function that drops `n` list items from a given `TypeList`.
469 template <size_t n, typename List>
470 using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type;
471 
472 // Implements `TakeTypeListItem`.
473 template <size_t n, typename List, typename... Accum>
474   requires is_instantiation<TypeList, List>
475 struct TakeTypeListItemImpl {
476   using Type = TypeList<Accum...>;
477 };
478 
479 template <size_t n, typename T, typename... List, typename... Accum>
480   requires(n > 0)
481 struct TakeTypeListItemImpl<n, TypeList<T, List...>, Accum...>
482     : TakeTypeListItemImpl<n - 1, TypeList<List...>, Accum..., T> {};
483 
484 // A type-level function that takes the first `n` items from a given `TypeList`;
485 // e.g. `TakeTypeListItem<3, TypeList<A, B, C, D>>` -> `TypeList<A, B, C>`.
486 template <size_t n, typename List>
487 using TakeTypeListItem = typename TakeTypeListItemImpl<n, List>::Type;
488 
489 // Implements `MakeFunctionType`.
490 template <typename R, typename ArgList>
491 struct MakeFunctionTypeImpl;
492 
493 template <typename R, typename... Args>
494 struct MakeFunctionTypeImpl<R, TypeList<Args...>> {
495   using Type = R(Args...);
496 };
497 
498 // A type-level function that constructs a function type that has `R` as its
499 // return type and has a `TypeList`'s items as its arguments.
500 template <typename R, typename ArgList>
501 using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type;
502 
503 // Implements `ExtractArgs` and `ExtractReturnType`.
504 template <typename Signature>
505 struct ExtractArgsImpl;
506 
507 template <typename R, typename... Args>
508 struct ExtractArgsImpl<R(Args...)> {
509   using ReturnType = R;
510   using ArgsList = TypeList<Args...>;
511 };
512 
513 // A type-level function that extracts function arguments into a `TypeList`;
514 // e.g. `ExtractArgs<R(A, B, C)>` -> `TypeList<A, B, C>`.
515 template <typename Signature>
516 using ExtractArgs = typename ExtractArgsImpl<Signature>::ArgsList;
517 
518 // A type-level function that extracts the return type of a function.
519 // e.g. `ExtractReturnType<R(A, B, C)>` -> `R`.
520 template <typename Signature>
521 using ExtractReturnType = typename ExtractArgsImpl<Signature>::ReturnType;
522 
523 template <typename Callable,
524           typename Signature = decltype(&Callable::operator())>
525 struct ExtractCallableRunTypeImpl;
526 
527 #define BIND_INTERNAL_EXTRACT_CALLABLE_RUN_TYPE_WITH_QUALS(quals)     \
528   template <typename Callable, typename R, typename... Args>          \
529   struct ExtractCallableRunTypeImpl<Callable,                         \
530                                     R (Callable::*)(Args...) quals> { \
531     using Type = R(Args...);                                          \
532   }
533 
534 BIND_INTERNAL_EXTRACT_CALLABLE_RUN_TYPE_WITH_QUALS();
535 BIND_INTERNAL_EXTRACT_CALLABLE_RUN_TYPE_WITH_QUALS(const);
536 BIND_INTERNAL_EXTRACT_CALLABLE_RUN_TYPE_WITH_QUALS(noexcept);
537 BIND_INTERNAL_EXTRACT_CALLABLE_RUN_TYPE_WITH_QUALS(const noexcept);
538 
539 #undef BIND_INTERNAL_EXTRACT_CALLABLE_RUN_TYPE_WITH_QUALS
540 
541 // Evaluated to the RunType of the given callable type; e.g.
542 // `ExtractCallableRunType<decltype([](int, char*) { return 0.1; })>` ->
543 //     `double(int, char*)`.
544 template <typename Callable>
545 using ExtractCallableRunType =
546     typename ExtractCallableRunTypeImpl<Callable>::Type;
547 
548 // True when `Functor` has a non-overloaded `operator()()`, e.g.:
549 //   struct S1 {
550 //     int operator()(int);
551 //   };
552 //   static_assert(HasNonOverloadedCallOp<S1>);
553 //
554 //   int i = 0;
555 //   auto f = [i] {};
556 //   static_assert(HasNonOverloadedCallOp<decltype(f)>);
557 //
558 //   struct S2 {
559 //     int operator()(int);
560 //     std::string operator()(std::string);
561 //   };
562 //   static_assert(!HasNonOverloadedCallOp<S2>);
563 //
564 //   static_assert(!HasNonOverloadedCallOp<void(*)()>);
565 //
566 //   struct S3 {};
567 //   static_assert(!HasNonOverloadedCallOp<S3>);
568 // ```
569 template <typename Functor>
570 concept HasNonOverloadedCallOp = requires { &Functor::operator(); };
571 
572 template <typename T>
573 inline constexpr bool IsObjCArcBlockPointer = false;
574 
575 #if __OBJC__ && HAS_FEATURE(objc_arc)
576 template <typename R, typename... Args>
577 inline constexpr bool IsObjCArcBlockPointer<R (^)(Args...)> = true;
578 #endif
579 
580 // True when `Functor` has an overloaded `operator()()` that can be invoked with
581 // the provided `BoundArgs`.
582 //
583 // Do not decay `Functor` before testing this, lest it give an incorrect result
584 // for overloads with different ref-qualifiers.
585 template <typename Functor, typename... BoundArgs>
586 concept HasOverloadedCallOp = requires {
587   // The functor must be invocable with the bound args.
588   requires requires(Functor&& f, BoundArgs&&... args) {
589     std::forward<Functor>(f)(std::forward<BoundArgs>(args)...);
590   };
591   // Now exclude invocables that are not cases of overloaded `operator()()`s:
592   // * `operator()()` exists, but isn't overloaded
593   requires !HasNonOverloadedCallOp<std::decay_t<Functor>>;
594   // * Function pointer (doesn't have `operator()()`)
595   requires !std::is_pointer_v<std::decay_t<Functor>>;
596   // * Block pointer (doesn't have `operator()()`)
597   requires !IsObjCArcBlockPointer<std::decay_t<Functor>>;
598 };
599 
600 // `HasRefCountedTypeAsRawPtr` is true when any of the `Args` is a raw pointer
601 // to a `RefCounted` type.
602 template <typename... Ts>
603 concept HasRefCountedTypeAsRawPtr =
604     std::disjunction_v<NeedsScopedRefptrButGetsRawPtr<Ts>...>;
605 
606 // `ForceVoidReturn<>` converts a signature to have a `void` return type.
607 template <typename Sig>
608 struct ForceVoidReturn;
609 
610 template <typename R, typename... Args>
611 struct ForceVoidReturn<R(Args...)> {
612   using RunType = void(Args...);
613 };
614 
615 // `FunctorTraits<>`
616 //
617 // See description at top of file. This must be declared here so it can be
618 // referenced in `DecayedFunctorTraits`.
619 template <typename Functor, typename... BoundArgs>
620 struct FunctorTraits;
621 
622 // Provides functor traits for pre-decayed functor types.
623 template <typename Functor, typename... BoundArgs>
624 struct DecayedFunctorTraits;
625 
626 // Callable types.
627 // This specialization handles lambdas (captureless and capturing) and functors
628 // with a call operator. Capturing lambdas and stateful functors are explicitly
629 // disallowed by `BindHelper<>::Bind()`; e.g.:
630 // ```
631 //   // Captureless lambda: Allowed
632 //   [] { return 42; };
633 //
634 //   // Capturing lambda: Disallowed
635 //   int x;
636 //   [x] { return x; };
637 //
638 //   // Empty class with `operator()()`: Allowed
639 //   struct Foo {
640 //     void operator()() const {}
641 //     // No non-`static` member variables and no virtual functions.
642 //   };
643 // ```
644 template <typename Functor, typename... BoundArgs>
645   requires HasNonOverloadedCallOp<Functor>
646 struct DecayedFunctorTraits<Functor, BoundArgs...> {
647   using RunType = ExtractCallableRunType<Functor>;
648   static constexpr bool is_method = false;
649   static constexpr bool is_nullable = false;
650   static constexpr bool is_callback = false;
651   static constexpr bool is_stateless = std::is_empty_v<Functor>;
652 
653   template <typename RunFunctor, typename... RunArgs>
654   static ExtractReturnType<RunType> Invoke(RunFunctor&& functor,
655                                            RunArgs&&... args) {
656     return std::forward<RunFunctor>(functor)(std::forward<RunArgs>(args)...);
657   }
658 };
659 
660 // Functions.
661 template <typename R, typename... Args, typename... BoundArgs>
662 struct DecayedFunctorTraits<R (*)(Args...), BoundArgs...> {
663   using RunType = R(Args...);
664   static constexpr bool is_method = false;
665   static constexpr bool is_nullable = true;
666   static constexpr bool is_callback = false;
667   static constexpr bool is_stateless = true;
668 
669   template <typename Function, typename... RunArgs>
670   static R Invoke(Function&& function, RunArgs&&... args) {
671     return std::forward<Function>(function)(std::forward<RunArgs>(args)...);
672   }
673 };
674 
675 template <typename R, typename... Args, typename... BoundArgs>
676 struct DecayedFunctorTraits<R (*)(Args...) noexcept, BoundArgs...>
677     : DecayedFunctorTraits<R (*)(Args...), BoundArgs...> {};
678 
679 #if BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS)
680 
681 // `__stdcall` and `__fastcall` functions.
682 #define BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_WITH_CONV_AND_QUALS(conv, quals) \
683   template <typename R, typename... Args, typename... BoundArgs>              \
684   struct DecayedFunctorTraits<R(conv*)(Args...) quals, BoundArgs...>          \
685       : DecayedFunctorTraits<R (*)(Args...) quals, BoundArgs...> {}
686 
687 BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_WITH_CONV_AND_QUALS(__stdcall, );
688 BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_WITH_CONV_AND_QUALS(__stdcall, noexcept);
689 BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_WITH_CONV_AND_QUALS(__fastcall, );
690 BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_WITH_CONV_AND_QUALS(__fastcall, noexcept);
691 
692 #undef BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_WITH_CONV_AND_QUALS
693 #endif  // BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS)
694 
695 #if __OBJC__ && HAS_FEATURE(objc_arc)
696 
697 // Objective-C blocks. Blocks can be bound as the compiler will ensure their
698 // lifetimes will be correctly managed.
699 template <typename R, typename... Args, typename... BoundArgs>
700 struct DecayedFunctorTraits<R (^)(Args...), BoundArgs...> {
701   using RunType = R(Args...);
702   static constexpr bool is_method = false;
703   static constexpr bool is_nullable = true;
704   static constexpr bool is_callback = false;
705   static constexpr bool is_stateless = true;
706 
707   template <typename BlockType, typename... RunArgs>
708   static R Invoke(BlockType&& block, RunArgs&&... args) {
709     // According to LLVM documentation (§ 6.3), "local variables of automatic
710     // storage duration do not have precise lifetime." Use
711     // `objc_precise_lifetime` to ensure that the Objective-C block is not
712     // deallocated until it has finished executing even if the `Callback<>` is
713     // destroyed during the block execution.
714     // https://clang.llvm.org/docs/AutomaticReferenceCounting.html#precise-lifetime-semantics
715     __attribute__((objc_precise_lifetime)) R (^scoped_block)(Args...) = block;
716     return scoped_block(std::forward<RunArgs>(args)...);
717   }
718 };
719 
720 #endif  // __OBJC__ && HAS_FEATURE(objc_arc)
721 
722 // Methods.
723 template <typename R,
724           typename Receiver,
725           typename... Args,
726           typename... BoundArgs>
727 struct DecayedFunctorTraits<R (Receiver::*)(Args...), BoundArgs...> {
728   using RunType = R(Receiver*, Args...);
729   static constexpr bool is_method = true;
730   static constexpr bool is_nullable = true;
731   static constexpr bool is_callback = false;
732   static constexpr bool is_stateless = true;
733 
734   template <typename Method, typename ReceiverPtr, typename... RunArgs>
735   static R Invoke(Method method,
736                   ReceiverPtr&& receiver_ptr,
737                   RunArgs&&... args) {
738     return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...);
739   }
740 };
741 
742 template <typename R,
743           typename Receiver,
744           typename... Args,
745           typename... BoundArgs>
746 struct DecayedFunctorTraits<R (Receiver::*)(Args...) const, BoundArgs...>
747     : DecayedFunctorTraits<R (Receiver::*)(Args...), BoundArgs...> {
748   using RunType = R(const Receiver*, Args...);
749 };
750 
751 #define BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_WITH_CONST_AND_QUALS(constqual, \
752                                                                   quals)     \
753   template <typename R, typename Receiver, typename... Args,                 \
754             typename... BoundArgs>                                           \
755   struct DecayedFunctorTraits<R (Receiver::*)(Args...) constqual quals,      \
756                               BoundArgs...>                                  \
757       : DecayedFunctorTraits<R (Receiver::*)(Args...) constqual,             \
758                              BoundArgs...> {}
759 
760 BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_WITH_CONST_AND_QUALS(, noexcept);
761 BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_WITH_CONST_AND_QUALS(const, noexcept);
762 
763 #undef BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_WITH_CONST_AND_QUALS
764 
765 #if BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS)
766 
767 // `__stdcall` methods.
768 #define BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_STDCALL_WITH_QUALS(quals)  \
769   template <typename R, typename Receiver, typename... Args,            \
770             typename... BoundArgs>                                      \
771   struct DecayedFunctorTraits<R (__stdcall Receiver::*)(Args...) quals, \
772                               BoundArgs...>                             \
773       : public DecayedFunctorTraits<R (Receiver::*)(Args...) quals,     \
774                                     BoundArgs...> {}
775 
776 BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_STDCALL_WITH_QUALS();
777 BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_STDCALL_WITH_QUALS(const);
778 BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_STDCALL_WITH_QUALS(noexcept);
779 BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_STDCALL_WITH_QUALS(const noexcept);
780 
781 #undef BIND_INTERNAL_DECAYED_FUNCTOR_TRAITS_STDCALL_WITH_QUALS
782 
783 #endif  // BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS)
784 
785 // `IgnoreResult`s.
786 template <typename T, typename... BoundArgs>
787 struct DecayedFunctorTraits<IgnoreResultHelper<T>, BoundArgs...>
788     : FunctorTraits<T, BoundArgs...> {
789   using RunType = typename ForceVoidReturn<
790       typename FunctorTraits<T, BoundArgs...>::RunType>::RunType;
791 
792   template <typename IgnoreResultType, typename... RunArgs>
793   static void Invoke(IgnoreResultType&& ignore_result_helper,
794                      RunArgs&&... args) {
795     FunctorTraits<T, BoundArgs...>::Invoke(
796         std::forward<IgnoreResultType>(ignore_result_helper).functor_,
797         std::forward<RunArgs>(args)...);
798   }
799 };
800 
801 // `OnceCallback`s.
802 template <typename R, typename... Args, typename... BoundArgs>
803 struct DecayedFunctorTraits<OnceCallback<R(Args...)>, BoundArgs...> {
804   using RunType = R(Args...);
805   static constexpr bool is_method = false;
806   static constexpr bool is_nullable = true;
807   static constexpr bool is_callback = true;
808   static constexpr bool is_stateless = true;
809 
810   template <typename CallbackType, typename... RunArgs>
811   static R Invoke(CallbackType&& callback, RunArgs&&... args) {
812     DCHECK(!callback.is_null());
813     return std::forward<CallbackType>(callback).Run(
814         std::forward<RunArgs>(args)...);
815   }
816 };
817 
818 // `RepeatingCallback`s.
819 template <typename R, typename... Args, typename... BoundArgs>
820 struct DecayedFunctorTraits<RepeatingCallback<R(Args...)>, BoundArgs...> {
821   using RunType = R(Args...);
822   static constexpr bool is_method = false;
823   static constexpr bool is_nullable = true;
824   static constexpr bool is_callback = true;
825   static constexpr bool is_stateless = true;
826 
827   template <typename CallbackType, typename... RunArgs>
828   static R Invoke(CallbackType&& callback, RunArgs&&... args) {
829     DCHECK(!callback.is_null());
830     return std::forward<CallbackType>(callback).Run(
831         std::forward<RunArgs>(args)...);
832   }
833 };
834 
835 // For most functors, the traits should not depend on how the functor is passed,
836 // so decay the functor.
837 template <typename Functor, typename... BoundArgs>
838 // This requirement avoids "implicit instantiation of undefined template" errors
839 // when the underlying `DecayedFunctorTraits<>` cannot be instantiated. Instead,
840 // this template will also not be instantiated, and the caller can detect and
841 // handle that.
842   requires IsComplete<DecayedFunctorTraits<std::decay_t<Functor>, BoundArgs...>>
843 struct FunctorTraits<Functor, BoundArgs...>
844     : DecayedFunctorTraits<std::decay_t<Functor>, BoundArgs...> {};
845 
846 // For `overloaded operator()()`s, it's possible the ref qualifiers of the
847 // functor matter, so be careful to use the undecayed type.
848 template <typename Functor, typename... BoundArgs>
849   requires HasOverloadedCallOp<Functor, BoundArgs...>
850 struct FunctorTraits<Functor, BoundArgs...> {
851   // For an overloaded operator()(), it is not possible to resolve the
852   // actual declared type. Since it is invocable with the bound args, make up a
853   // signature based on their types.
854   using RunType = decltype(std::declval<Functor>()(
855       std::declval<BoundArgs>()...))(std::decay_t<BoundArgs>...);
856   static constexpr bool is_method = false;
857   static constexpr bool is_nullable = false;
858   static constexpr bool is_callback = false;
859   static constexpr bool is_stateless = std::is_empty_v<std::decay_t<Functor>>;
860 
861   template <typename RunFunctor, typename... RunArgs>
862   static ExtractReturnType<RunType> Invoke(RunFunctor&& functor,
863                                            RunArgs&&... args) {
864     return std::forward<RunFunctor>(functor)(std::forward<RunArgs>(args)...);
865   }
866 };
867 
868 // `StorageTraits<>`
869 //
870 // See description at top of file.
871 template <typename T>
872 struct StorageTraits {
873   // The type to use for storing the bound arg inside `BindState`.
874   using Type = T;
875 
876   // True iff all compile-time preconditions for using this specialization are
877   // satisfied. Specializations that set this to `false` should ensure a
878   // `static_assert()` explains why.
879   static constexpr bool value = true;
880 };
881 
882 // For `T*`, store as `UnretainedWrapper<T>` for safety, as it internally uses
883 // `raw_ptr<T>` (when possible).
884 template <typename T>
885 struct StorageTraits<T*> {
886   using Type = UnretainedWrapper<T, unretained_traits::MayNotDangle>;
887   static constexpr bool value = Type::value;
888 };
889 
890 // For `raw_ptr<T>`, store as `UnretainedWrapper<T>` for safety. This may seem
891 // contradictory, but this ensures guaranteed protection for the pointer even
892 // during execution of callbacks with parameters of type `raw_ptr<T>`.
893 template <typename T, RawPtrTraits PtrTraits>
894 struct StorageTraits<raw_ptr<T, PtrTraits>> {
895   using Type = UnretainedWrapper<T, unretained_traits::MayNotDangle, PtrTraits>;
896   static constexpr bool value = Type::value;
897 };
898 
899 // Unwrap `std::reference_wrapper` and store it in a custom wrapper so that
900 // references are also protected with `raw_ptr<T>`.
901 template <typename T>
902 struct StorageTraits<std::reference_wrapper<T>> {
903   using Type = UnretainedRefWrapper<T, unretained_traits::MayNotDangle>;
904   static constexpr bool value = Type::value;
905 };
906 
907 template <typename T>
908 using ValidateStorageTraits = StorageTraits<std::decay_t<T>>;
909 
910 // `InvokeHelper<>`
911 //
912 // There are 2 logical `InvokeHelper<>` specializations: normal, weak.
913 //
914 // The normal type just calls the underlying runnable.
915 //
916 // Weak calls need special syntax that is applied to the first argument to check
917 // if they should no-op themselves.
918 template <bool is_weak_call,
919           typename Traits,
920           typename ReturnType,
921           size_t... indices>
922 struct InvokeHelper;
923 
924 template <typename Traits, typename ReturnType, size_t... indices>
925 struct InvokeHelper<false, Traits, ReturnType, indices...> {
926   template <typename Functor, typename BoundArgsTuple, typename... RunArgs>
927   static inline ReturnType MakeItSo(Functor&& functor,
928                                     BoundArgsTuple&& bound,
929                                     RunArgs&&... args) {
930     return Traits::Invoke(
931         Unwrap(std::forward<Functor>(functor)),
932         Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))...,
933         std::forward<RunArgs>(args)...);
934   }
935 };
936 
937 template <typename Traits,
938           typename ReturnType,
939           size_t index_target,
940           size_t... index_tail>
941 struct InvokeHelper<true, Traits, ReturnType, index_target, index_tail...> {
942   template <typename Functor, typename BoundArgsTuple, typename... RunArgs>
943   static inline void MakeItSo(Functor&& functor,
944                               BoundArgsTuple&& bound,
945                               RunArgs&&... args) {
946     static_assert(index_target == 0);
947     // Note the validity of the weak pointer should be tested _after_ it is
948     // unwrapped, otherwise it creates a race for weak pointer implementations
949     // that allow cross-thread usage and perform `Lock()` in `Unwrap()` traits.
950     const auto& target = Unwrap(std::get<0>(bound));
951     if (!target) {
952       return;
953     }
954     Traits::Invoke(
955         Unwrap(std::forward<Functor>(functor)), target,
956         Unwrap(std::get<index_tail>(std::forward<BoundArgsTuple>(bound)))...,
957         std::forward<RunArgs>(args)...);
958   }
959 };
960 
961 // `Invoker<>`
962 //
963 // See description at the top of the file.
964 template <typename Traits, typename StorageType, typename UnboundRunType>
965 struct Invoker;
966 
967 template <typename Traits,
968           typename StorageType,
969           typename R,
970           typename... UnboundArgs>
971 struct Invoker<Traits, StorageType, R(UnboundArgs...)> {
972  private:
973   using Indices = std::make_index_sequence<
974       std::tuple_size_v<decltype(StorageType::bound_args_)>>;
975 
976  public:
977   static R RunOnce(BindStateBase* base,
978                    PassingType<UnboundArgs>... unbound_args) {
979     auto* const storage = static_cast<StorageType*>(base);
980     return RunImpl(std::move(storage->functor_),
981                    std::move(storage->bound_args_), Indices(),
982                    std::forward<UnboundArgs>(unbound_args)...);
983   }
984 
985   static R Run(BindStateBase* base, PassingType<UnboundArgs>... unbound_args) {
986     auto* const storage = static_cast<const StorageType*>(base);
987     return RunImpl(storage->functor_, storage->bound_args_, Indices(),
988                    std::forward<UnboundArgs>(unbound_args)...);
989   }
990 
991  private:
992   // The "templated struct with a lambda that asserts" pattern below is used
993   // repeatedly in Bind/Callback code to verify compile-time preconditions. The
994   // goal is to print only the root cause failure when users violate a
995   // precondition, and not also a host of resulting compile errors.
996   //
997   // There are three key aspects:
998   //   1. By placing the assertion inside a lambda that initializes a variable,
999   //      the assertion will not be verified until the compiler tries to read
1000   //      the value of that variable. This allows the containing types to be
1001   //      complete. As a result, code that needs to know if the assertion failed
1002   //      can read the variable's value and get the right answer. (If we instead
1003   //      placed the assertion at struct scope, the resulting type would be
1004   //      incomplete when the assertion failed; in practice, reading a
1005   //      `constexpr` member of an incomplete type seems to return the default
1006   //      value regardless of what the code tried to set the value to, which
1007   //      makes it impossible for other code to check whether the assertion
1008   //      failed.)
1009   //   2. Code that will not successfully compile unless the assertion holds is
1010   //      guarded by a constexpr if that checks the variable.
1011   //   3. By placing the variable inside an independent, templated struct and
1012   //      naming it `value`, we allow checking multiple conditions via
1013   //      `std::conjunction_v<>`. This short-circuits type instantiation, so
1014   //      that when one condition fails, the others are never examined and thus
1015   //      never assert. As a result, we can verify dependent conditions without
1016   //      worrying that "if one fails, we'll get errors from several others".
1017   //      (This would not be true if we simply checked all the values with `&&`,
1018   //      which would instantiate all the types before evaluating the
1019   //      expression.)
1020   //
1021   // For caller convenience and to avoid potential repetition, the actual
1022   // condition to be checked is always used as the default value of a template
1023   // argument, so callers can simply instantiate the struct with no template
1024   // params to verify the condition.
1025 
1026   // Weak calls are only supported for functions with a `void` return type.
1027   // Otherwise, the desired function result would be unclear if the `WeakPtr<>`
1028   // is invalidated. In theory, we could support default-constructible return
1029   // types (and return the default value) or allow callers to specify a default
1030   // return value via a template arg. It's not clear these are necessary.
1031   template <bool is_weak_call, bool v = !is_weak_call || std::is_void_v<R>>
1032   struct WeakCallReturnsVoid {
1033     static constexpr bool value = [] {
1034       static_assert(v,
1035                     "WeakPtrs can only bind to methods without return values.");
1036       return v;
1037     }();
1038   };
1039 
1040   template <typename Functor, typename BoundArgsTuple, size_t... indices>
1041   static inline R RunImpl(Functor&& functor,
1042                           BoundArgsTuple&& bound,
1043                           std::index_sequence<indices...>,
1044                           UnboundArgs&&... unbound_args) {
1045 #if BUILDFLAG(USE_ASAN_BACKUP_REF_PTR)
1046     RawPtrAsanBoundArgTracker raw_ptr_asan_bound_arg_tracker;
1047     raw_ptr_asan_bound_arg_tracker.AddArgs(
1048         std::get<indices>(std::forward<BoundArgsTuple>(bound))...,
1049         std::forward<UnboundArgs>(unbound_args)...);
1050 #endif  // BUILDFLAG(USE_ASAN_BACKUP_REF_PTR)
1051 
1052     using DecayedArgsTuple = std::decay_t<BoundArgsTuple>;
1053     static constexpr bool kIsWeakCall =
1054         kIsWeakMethod<Traits::is_method,
1055                       std::tuple_element_t<indices, DecayedArgsTuple>...>;
1056     if constexpr (WeakCallReturnsVoid<kIsWeakCall>::value) {
1057       // Do not `Unwrap()` here, as that immediately triggers dangling pointer
1058       // detection. Dangling pointer detection should only be triggered if the
1059       // callback is not cancelled, but cancellation status is not determined
1060       // until later inside the `InvokeHelper::MakeItSo()` specialization for
1061       // weak calls.
1062       //
1063       // Dangling pointers when invoking a cancelled callback are not considered
1064       // a memory safety error because protecting raw pointers usage with weak
1065       // receivers (where the weak receiver usually own the pointed objects) is
1066       // a common and broadly used pattern in the codebase.
1067       return InvokeHelper<kIsWeakCall, Traits, R, indices...>::MakeItSo(
1068           std::forward<Functor>(functor), std::forward<BoundArgsTuple>(bound),
1069           std::forward<UnboundArgs>(unbound_args)...);
1070     }
1071   }
1072 };
1073 
1074 // Allow binding a method call with no receiver.
1075 // TODO(crbug.com/1511757): Remove or make safe.
1076 template <typename... Unused>
1077 void VerifyMethodReceiver(Unused&&...) {}
1078 
1079 template <typename Receiver, typename... Unused>
1080 void VerifyMethodReceiver(Receiver&& receiver, Unused&&...) {
1081   // Asserts that a callback is not the first owner of a ref-counted receiver.
1082   if constexpr (IsRawPointer<std::decay_t<Receiver>> &&
1083                 IsRefCountedType<RemoveRawPointerT<std::decay_t<Receiver>>>) {
1084     DCHECK(receiver);
1085 
1086     // It's error prone to make the implicit first reference to ref-counted
1087     // types. In the example below, `BindOnce()` would make the implicit first
1088     // reference to the ref-counted `Foo`. If `PostTask()` failed or the posted
1089     // task ran fast enough, the newly created instance could be destroyed
1090     // before `oo` makes another reference.
1091     // ```
1092     //   Foo::Foo() {
1093     //     ThreadPool::PostTask(FROM_HERE, BindOnce(&Foo::Bar, this));
1094     //   }
1095     //
1096     //   scoped_refptr<Foo> oo = new Foo();
1097     // ```
1098     //
1099     // Hence, `Bind()` refuses to create the first reference to ref-counted
1100     // objects, and `DCHECK()`s otherwise. As above, that typically happens
1101     // around `PostTask()` in their constructors, and such objects can be
1102     // destroyed before `new` returns if the tasks resolve fast enough.
1103     //
1104     // Instead, consider adding a static factory, and keeping the first
1105     // reference alive explicitly.
1106     // ```
1107     //   // static
1108     //   scoped_refptr<Foo> Foo::Create() {
1109     //     auto foo = base::WrapRefCounted(new Foo());
1110     //     ThreadPool::PostTask(FROM_HERE, BindOnce(&Foo::Bar, foo));
1111     //     return foo;
1112     //   }
1113     //
1114     //   scoped_refptr<Foo> oo = Foo::Create();
1115     // ```
1116     DCHECK(receiver->HasAtLeastOneRef());
1117   }
1118 }
1119 
1120 // `BindState<>`
1121 //
1122 // This stores all the state passed into `Bind()`.
1123 template <bool is_method,
1124           bool is_nullable,
1125           bool is_callback,
1126           typename Functor,
1127           typename... BoundArgs>
1128 struct BindState final : BindStateBase {
1129  private:
1130   using BoundArgsTuple = std::tuple<BoundArgs...>;
1131 
1132  public:
1133   template <typename ForwardFunctor, typename... ForwardBoundArgs>
1134   static BindState* Create(BindStateBase::InvokeFuncStorage invoke_func,
1135                            ForwardFunctor&& functor,
1136                            ForwardBoundArgs&&... bound_args) {
1137     if constexpr (is_method) {
1138       VerifyMethodReceiver(bound_args...);
1139     }
1140     return new BindState(invoke_func, std::forward<ForwardFunctor>(functor),
1141                          std::forward<ForwardBoundArgs>(bound_args)...);
1142   }
1143 
1144   Functor functor_;
1145   BoundArgsTuple bound_args_;
1146 
1147  private:
1148   using CancellationTraits =
1149       CallbackCancellationTraits<Functor, BoundArgsTuple>;
1150 
1151   template <typename ForwardFunctor, typename... ForwardBoundArgs>
1152     requires CancellationTraits::is_cancellable
1153   explicit BindState(BindStateBase::InvokeFuncStorage invoke_func,
1154                      ForwardFunctor&& functor,
1155                      ForwardBoundArgs&&... bound_args)
1156       : BindStateBase(invoke_func, &Destroy, &QueryCancellationTraits),
1157         functor_(std::forward<ForwardFunctor>(functor)),
1158         bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
1159     CheckFunctorIsNonNull();
1160   }
1161 
1162   template <typename ForwardFunctor, typename... ForwardBoundArgs>
1163     requires(!CancellationTraits::is_cancellable)
1164   explicit BindState(BindStateBase::InvokeFuncStorage invoke_func,
1165                      ForwardFunctor&& functor,
1166                      ForwardBoundArgs&&... bound_args)
1167       : BindStateBase(invoke_func, &Destroy),
1168         functor_(std::forward<ForwardFunctor>(functor)),
1169         bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
1170     CheckFunctorIsNonNull();
1171   }
1172 
1173   ~BindState() = default;
1174 
1175   static bool QueryCancellationTraits(
1176       const BindStateBase* base,
1177       BindStateBase::CancellationQueryMode mode) {
1178     auto* const storage = static_cast<const BindState*>(base);
1179     static constexpr std::make_index_sequence<sizeof...(BoundArgs)> kIndices;
1180     return (mode == BindStateBase::CancellationQueryMode::kIsCancelled)
1181                ? storage->IsCancelled(kIndices)
1182                : storage->MaybeValid(kIndices);
1183   }
1184 
1185   static void Destroy(const BindStateBase* self) {
1186     delete static_cast<const BindState*>(self);
1187   }
1188 
1189   // Helpers to do arg tuple expansion.
1190   template <size_t... indices>
1191   bool IsCancelled(std::index_sequence<indices...>) const {
1192     return CancellationTraits::IsCancelled(functor_,
1193                                            std::get<indices>(bound_args_)...);
1194   }
1195 
1196   template <size_t... indices>
1197   bool MaybeValid(std::index_sequence<indices...>) const {
1198     return CancellationTraits::MaybeValid(functor_,
1199                                           std::get<indices>(bound_args_)...);
1200   }
1201 
1202   void CheckFunctorIsNonNull() const {
1203     if constexpr (is_nullable) {
1204       // Check the validity of `functor_` to avoid hard-to-diagnose crashes.
1205       // Ideally we'd do this unconditionally, but release builds limit this to
1206       // the case of nested callbacks (e.g. `Bind(callback, ...)`) to limit
1207       // binary size impact.
1208       if constexpr (is_callback) {
1209         CHECK(!!functor_);
1210       } else {
1211         DCHECK(!!functor_);
1212       }
1213     }
1214   }
1215 };
1216 
1217 // Used to determine and validate the appropriate `BindState`. The
1218 // specializations below cover all cases. The members are similar in intent to
1219 // those in `StorageTraits`; see comments there.
1220 template <bool is_method,
1221           bool is_nullable,
1222           bool is_callback,
1223           typename Functor,
1224           typename... BoundArgs>
1225 struct ValidateBindStateType;
1226 
1227 template <bool is_nullable,
1228           bool is_callback,
1229           typename Functor,
1230           typename... BoundArgs>
1231 struct ValidateBindStateType<false,
1232                              is_nullable,
1233                              is_callback,
1234                              Functor,
1235                              BoundArgs...> {
1236  private:
1237   template <bool v = !HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>>
1238   struct NoRawPtrsToRefCountedTypes {
1239     static constexpr bool value = [] {
1240       static_assert(
1241           v, "A parameter is a refcounted type and needs scoped_refptr.");
1242       return v;
1243     }();
1244   };
1245 
1246  public:
1247   using Type = BindState<false,
1248                          is_nullable,
1249                          is_callback,
1250                          std::decay_t<Functor>,
1251                          typename ValidateStorageTraits<BoundArgs>::Type...>;
1252   static constexpr bool value =
1253       std::conjunction_v<NoRawPtrsToRefCountedTypes<>,
1254                          ValidateStorageTraits<BoundArgs>...>;
1255 };
1256 
1257 template <bool is_nullable, bool is_callback, typename Functor>
1258 struct ValidateBindStateType<true, is_nullable, is_callback, Functor> {
1259   using Type = BindState<true, is_nullable, is_callback, std::decay_t<Functor>>;
1260   static constexpr bool value = true;
1261 };
1262 
1263 template <bool is_nullable,
1264           bool is_callback,
1265           typename Functor,
1266           typename Receiver,
1267           typename... BoundArgs>
1268 struct ValidateBindStateType<true,
1269                              is_nullable,
1270                              is_callback,
1271                              Functor,
1272                              Receiver,
1273                              BoundArgs...> {
1274  private:
1275   using DecayedReceiver = std::decay_t<Receiver>;
1276   using ReceiverStorageType =
1277       typename MethodReceiverStorage<DecayedReceiver>::Type;
1278 
1279   template <bool v = !std::is_array_v<std::remove_reference_t<Receiver>>>
1280   struct FirstBoundArgIsNotArray {
1281     static constexpr bool value = [] {
1282       static_assert(v, "First bound argument to a method cannot be an array.");
1283       return v;
1284     }();
1285   };
1286 
1287   template <bool v = !IsRawRefV<DecayedReceiver>>
1288   struct ReceiverIsNotRawRef {
1289     static constexpr bool value = [] {
1290       static_assert(v, "Receivers may not be raw_ref<T>. If using a raw_ref<T> "
1291                        "here is safe and has no lifetime concerns, use "
1292                        "base::Unretained() and document why it's safe.");
1293       return v;
1294     }();
1295   };
1296 
1297   template <bool v = !IsRawPointer<DecayedReceiver> ||
1298                      IsRefCountedType<RemoveRawPointerT<DecayedReceiver>>>
1299   struct ReceiverIsNotRawPtr {
1300     static constexpr bool value = [] {
1301       static_assert(v,
1302                     "Receivers may not be raw pointers. If using a raw pointer "
1303                     "here is safe and has no lifetime concerns, use "
1304                     "base::Unretained() and document why it's safe.");
1305       return v;
1306     }();
1307   };
1308 
1309   template <bool v = !HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>>
1310   struct NoRawPtrsToRefCountedTypes {
1311     static constexpr bool value = [] {
1312       static_assert(
1313           v, "A parameter is a refcounted type and needs scoped_refptr.");
1314       return v;
1315     }();
1316   };
1317 
1318  public:
1319   using Type = BindState<true,
1320                          is_nullable,
1321                          is_callback,
1322                          std::decay_t<Functor>,
1323                          ReceiverStorageType,
1324                          typename ValidateStorageTraits<BoundArgs>::Type...>;
1325   static constexpr bool value =
1326       std::conjunction_v<FirstBoundArgIsNotArray<>,
1327                          ReceiverIsNotRawRef<>,
1328                          ReceiverIsNotRawPtr<>,
1329                          NoRawPtrsToRefCountedTypes<>,
1330                          ValidateStorageTraits<BoundArgs>...>;
1331 };
1332 
1333 // Transforms `T` into an unwrapped type, which is passed to the target
1334 // function; e.g.:
1335 // * `is_once` cases:
1336 // ** `TransformToUnwrappedType<true, int&&>` -> `int&&`
1337 // ** `TransformToUnwrappedType<true, const int&>` -> `int&&`
1338 // ** `TransformToUnwrappedType<true, OwnedWrapper<int>&>` -> `int*&&`
1339 // * `!is_once` cases:
1340 // ** `TransformToUnwrappedType<false, int&&>` -> `const int&`
1341 // ** `TransformToUnwrappedType<false, const int&>` -> `const int&`
1342 // ** `TransformToUnwrappedType<false, OwnedWrapper<int>&>` -> `int* const &`
1343 template <bool is_once,
1344           typename T,
1345           typename StoredType = std::decay_t<T>,
1346           typename ForwardedType =
1347               std::conditional_t<is_once, StoredType&&, const StoredType&>>
1348 using TransformToUnwrappedType =
1349     decltype(Unwrap(std::declval<ForwardedType>()));
1350 
1351 // Used to convert `this` arguments to underlying pointer types; e.g.:
1352 //   `int*` -> `int*`
1353 //   `std::unique_ptr<int>` -> `int*`
1354 //   `int` -> (assertion failure; `this` must be a pointer-like object)
1355 template <typename T>
1356 struct ValidateReceiverType {
1357  private:
1358   // Pointer-like receivers use a different specialization, so this never
1359   // succeeds.
1360   template <bool v = AlwaysFalse<T>>
1361   struct ReceiverMustBePointerLike {
1362     static constexpr bool value = [] {
1363       static_assert(v,
1364                     "Cannot convert `this` argument to address. Method calls "
1365                     "must be bound using a pointer-like `this` argument.");
1366       return v;
1367     }();
1368   };
1369 
1370  public:
1371   // These members are similar in intent to those in `StorageTraits`; see
1372   // comments there.
1373   using Type = T;
1374   static constexpr bool value = ReceiverMustBePointerLike<>::value;
1375 };
1376 
1377 template <typename T>
1378   requires requires(T&& t) { base::to_address(t); }
1379 struct ValidateReceiverType<T> {
1380   using Type = decltype(base::to_address(std::declval<T>()));
1381   static constexpr bool value = true;
1382 };
1383 
1384 // Transforms `Args` into unwrapped types, and packs them into a `TypeList`. If
1385 // `is_method` is true, tries to dereference the first argument to support smart
1386 // pointers.
1387 template <bool is_once, bool is_method, typename... Args>
1388 struct ValidateUnwrappedTypeList {
1389   // These members are similar in intent to those in `StorageTraits`; see
1390   // comments there.
1391   using Type = TypeList<TransformToUnwrappedType<is_once, Args>...>;
1392   static constexpr bool value = true;
1393 };
1394 
1395 template <bool is_once, typename Receiver, typename... Args>
1396 struct ValidateUnwrappedTypeList<is_once, true, Receiver, Args...> {
1397  private:
1398   using ReceiverStorageType =
1399       typename MethodReceiverStorage<std::decay_t<Receiver>>::Type;
1400   using UnwrappedReceiver =
1401       TransformToUnwrappedType<is_once, ReceiverStorageType>;
1402   using ValidatedReceiver = ValidateReceiverType<UnwrappedReceiver>;
1403 
1404  public:
1405   using Type = TypeList<typename ValidatedReceiver::Type,
1406                         TransformToUnwrappedType<is_once, Args>...>;
1407   static constexpr bool value = ValidatedReceiver::value;
1408 };
1409 
1410 // `IsUnretainedMayDangle` is true iff `StorageType` is marked with
1411 // `unretained_traits::MayDangle`. Note that it is false for
1412 // `unretained_traits::MayDangleUntriaged`.
1413 template <typename StorageType>
1414 inline constexpr bool IsUnretainedMayDangle = false;
1415 
1416 template <typename T, RawPtrTraits PtrTraits>
1417 inline constexpr bool IsUnretainedMayDangle<
1418     UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraits>> = true;
1419 
1420 // `UnretainedAndRawPtrHaveCompatibleTraits` is true iff `StorageType` is marked
1421 // with `unretained_traits::MayDangle`, `FunctionParamType` is a `raw_ptr`, and
1422 // `StorageType::GetPtrType` is the same type as `FunctionParamType`.
1423 template <typename StorageType, typename FunctionParamType>
1424 inline constexpr bool UnretainedAndRawPtrHaveCompatibleTraits = false;
1425 
1426 template <typename T,
1427           RawPtrTraits PtrTraitsInUnretained,
1428           RawPtrTraits PtrTraitsInReceiver>
1429 inline constexpr bool UnretainedAndRawPtrHaveCompatibleTraits<
1430     UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraitsInUnretained>,
1431     raw_ptr<T, PtrTraitsInReceiver>> =
1432     std::same_as<typename UnretainedWrapper<T,
1433                                             unretained_traits::MayDangle,
1434                                             PtrTraitsInUnretained>::GetPtrType,
1435                  raw_ptr<T, PtrTraitsInReceiver>>;
1436 
1437 // Helpers to make error messages slightly more readable.
1438 template <int i>
1439 struct BindArgument {
1440   template <typename ForwardingType>
1441   struct ForwardedAs {
1442     template <typename FunctorParamType>
1443     struct ToParamWithType {
1444       static constexpr bool kRawPtr = IsRawPtrV<FunctorParamType>;
1445       static constexpr bool kRawPtrMayBeDangling =
1446           IsRawPtrMayDangleV<FunctorParamType>;
1447       static constexpr bool kCanBeForwardedToBoundFunctor =
1448           std::is_convertible_v<ForwardingType, FunctorParamType>;
1449 
1450       // If the bound type can't be forwarded, then test if `FunctorParamType`
1451       // is a non-const lvalue reference and a reference to the unwrapped type
1452       // could have been successfully forwarded.
1453       static constexpr bool kIsUnwrappedForwardableNonConstReference =
1454           std::is_lvalue_reference_v<FunctorParamType> &&
1455           !std::is_const_v<std::remove_reference_t<FunctorParamType>> &&
1456           std::is_convertible_v<std::decay_t<ForwardingType>&,
1457                                 FunctorParamType>;
1458 
1459       // Also intentionally drop the `const` qualifier from `ForwardingType`, to
1460       // test if it could have been successfully forwarded if `Passed()` had
1461       // been used.
1462       static constexpr bool kWouldBeForwardableWithPassed =
1463           std::is_convertible_v<std::decay_t<ForwardingType>&&,
1464                                 FunctorParamType>;
1465     };
1466   };
1467 
1468   template <typename BoundAsType>
1469   struct BoundAs {
1470     template <typename StorageType>
1471     struct StoredAs {
1472       static constexpr bool kBindArgumentCanBeCaptured =
1473           std::constructible_from<StorageType, BoundAsType>;
1474 
1475       // If the argument can't be captured, intentionally drop the `const`
1476       // qualifier from `BoundAsType`, to test if it could have been
1477       // successfully captured if `std::move()` had been used.
1478       static constexpr bool kWouldBeCapturableWithStdMove =
1479           std::constructible_from<StorageType, std::decay_t<BoundAsType>&&>;
1480     };
1481   };
1482 
1483   template <typename FunctionParamType>
1484   struct ToParamWithType {
1485     template <typename StorageType>
1486     struct StoredAs {
1487       static constexpr bool kBoundPtrMayDangle =
1488           IsUnretainedMayDangle<StorageType>;
1489 
1490       static constexpr bool kMayDangleAndMayBeDanglingHaveMatchingTraits =
1491           UnretainedAndRawPtrHaveCompatibleTraits<StorageType,
1492                                                   FunctionParamType>;
1493     };
1494   };
1495 };
1496 
1497 // Helper to assert that parameter `i` of type `Arg` can be bound, which means:
1498 // * `Arg` can be retained internally as `Storage`
1499 // * `Arg` can be forwarded as `Unwrapped` to `Param`
1500 template <int i,
1501           bool is_method,
1502           typename Arg,
1503           typename Storage,
1504           typename Unwrapped,
1505           typename Param>
1506 struct ParamCanBeBound {
1507  private:
1508   using UnwrappedParam = BindArgument<i>::template ForwardedAs<
1509       Unwrapped>::template ToParamWithType<Param>;
1510   using ParamStorage = BindArgument<i>::template ToParamWithType<
1511       Param>::template StoredAs<Storage>;
1512   using BoundStorage =
1513       BindArgument<i>::template BoundAs<Arg>::template StoredAs<Storage>;
1514 
1515   template <bool v = !UnwrappedParam::kRawPtr ||
1516                      UnwrappedParam::kRawPtrMayBeDangling>
1517   struct NotRawPtr {
1518     static constexpr bool value = [] {
1519       static_assert(
1520           v, "Use T* or T& instead of raw_ptr<T> for function parameters, "
1521              "unless you must mark the parameter as MayBeDangling<T>.");
1522       return v;
1523     }();
1524   };
1525 
1526   template <bool v = !ParamStorage::kBoundPtrMayDangle ||
1527                      UnwrappedParam::kRawPtrMayBeDangling ||
1528                      // Exempt `this` pointer as it is not passed as a regular
1529                      // function argument.
1530                      (is_method && i == 0)>
1531   struct MayBeDanglingPtrPassedCorrectly {
1532     static constexpr bool value = [] {
1533       static_assert(v, "base::UnsafeDangling() pointers should only be passed "
1534                        "to parameters marked MayBeDangling<T>.");
1535       return v;
1536     }();
1537   };
1538 
1539   template <bool v =
1540                 !UnwrappedParam::kRawPtrMayBeDangling ||
1541                 (ParamStorage::kBoundPtrMayDangle &&
1542                  ParamStorage::kMayDangleAndMayBeDanglingHaveMatchingTraits)>
1543   struct MayDangleAndMayBeDanglingHaveMatchingTraits {
1544     static constexpr bool value = [] {
1545       static_assert(
1546           v, "Pointers passed to MayBeDangling<T> parameters must be created "
1547              "by base::UnsafeDangling() with the same RawPtrTraits.");
1548       return v;
1549     }();
1550   };
1551 
1552   // With `BindRepeating()`, there are two decision points for how to handle a
1553   // move-only type:
1554   //
1555   // 1. Whether the move-only argument should be moved into the internal
1556   //    `BindState`. Either `std::move()` or `Passed()` is sufficient to trigger
1557   //    move-only semantics.
1558   // 2. Whether or not the bound, move-only argument should be moved to the
1559   //    bound functor when invoked. When the argument is bound with `Passed()`,
1560   //    invoking the callback will destructively move the bound, move-only
1561   //    argument to the bound functor. In contrast, if the argument is bound
1562   //    with `std::move()`, `RepeatingCallback` will attempt to call the bound
1563   //    functor with a constant reference to the bound, move-only argument. This
1564   //    will fail if the bound functor accepts that argument by value, since the
1565   //    argument cannot be copied. It is this latter case that this
1566   //    assertion aims to catch.
1567   //
1568   // In contrast, `BindOnce()` only has one decision point. Once a move-only
1569   // type is captured by value into the internal `BindState`, the bound,
1570   // move-only argument will always be moved to the functor when invoked.
1571   // Failure to use `std::move()` will simply fail the
1572   // `MoveOnlyTypeMustUseStdMove` assertion below instead.
1573   //
1574   // Note: `Passed()` is a legacy of supporting move-only types when repeating
1575   // callbacks were the only callback type. A `RepeatingCallback` with a
1576   // `Passed()` argument is really a `OnceCallback` and should eventually be
1577   // migrated.
1578   template <bool v = UnwrappedParam::kCanBeForwardedToBoundFunctor ||
1579                      !UnwrappedParam::kWouldBeForwardableWithPassed>
1580   struct MoveOnlyTypeMustUseBasePassed {
1581     static constexpr bool value = [] {
1582       static_assert(v,
1583                     "base::BindRepeating() argument is a move-only type. Use "
1584                     "base::Passed() instead of std::move() to transfer "
1585                     "ownership from the callback to the bound functor.");
1586       return v;
1587     }();
1588   };
1589 
1590   template <bool v = UnwrappedParam::kCanBeForwardedToBoundFunctor ||
1591                      !UnwrappedParam::kIsUnwrappedForwardableNonConstReference>
1592   struct NonConstRefParamMustBeWrapped {
1593     static constexpr bool value = [] {
1594       static_assert(v,
1595                     "Bound argument for non-const reference parameter must be "
1596                     "wrapped in std::ref() or base::OwnedRef().");
1597       return v;
1598     }();
1599   };
1600 
1601   // Generic failed-to-forward message for cases that didn't match one of the
1602   // two assertions above.
1603   template <bool v = UnwrappedParam::kCanBeForwardedToBoundFunctor>
1604   struct CanBeForwardedToBoundFunctor {
1605     static constexpr bool value = [] {
1606       static_assert(v,
1607                     "Type mismatch between bound argument and bound functor's "
1608                     "parameter.");
1609       return v;
1610     }();
1611   };
1612 
1613   // The most common reason for failing to capture a parameter is attempting to
1614   // pass a move-only type as an lvalue.
1615   template <bool v = BoundStorage::kBindArgumentCanBeCaptured ||
1616                      !BoundStorage::kWouldBeCapturableWithStdMove>
1617   struct MoveOnlyTypeMustUseStdMove {
1618     static constexpr bool value = [] {
1619       static_assert(v,
1620                     "Attempting to bind a move-only type. Use std::move() to "
1621                     "transfer ownership to the created callback.");
1622       return v;
1623     }();
1624   };
1625 
1626   // Any other reason the parameter could not be captured.
1627   template <bool v = BoundStorage::kBindArgumentCanBeCaptured>
1628   struct BindArgumentCanBeCaptured {
1629     static constexpr bool value = [] {
1630       // In practice, failing this precondition should be rare, as the storage
1631       // type is deduced from the arguments passed to `Bind()`.
1632       static_assert(
1633           v, "Cannot capture argument: is the argument copyable or movable?");
1634       return v;
1635     }();
1636   };
1637 
1638  public:
1639   static constexpr bool value =
1640       std::conjunction_v<NotRawPtr<>,
1641                          MayBeDanglingPtrPassedCorrectly<>,
1642                          MayDangleAndMayBeDanglingHaveMatchingTraits<>,
1643                          MoveOnlyTypeMustUseBasePassed<>,
1644                          NonConstRefParamMustBeWrapped<>,
1645                          CanBeForwardedToBoundFunctor<>,
1646                          MoveOnlyTypeMustUseStdMove<>,
1647                          BindArgumentCanBeCaptured<>>;
1648 };
1649 
1650 // Takes three same-length `TypeList`s, and checks `ParamCanBeBound` for each
1651 // triple.
1652 template <bool is_method,
1653           typename Index,
1654           typename Args,
1655           typename UnwrappedTypeList,
1656           typename ParamsList>
1657 struct ParamsCanBeBound {
1658   static constexpr bool value = false;
1659 };
1660 
1661 template <bool is_method,
1662           size_t... Ns,
1663           typename... Args,
1664           typename... UnwrappedTypes,
1665           typename... Params>
1666 struct ParamsCanBeBound<is_method,
1667                         std::index_sequence<Ns...>,
1668                         TypeList<Args...>,
1669                         TypeList<UnwrappedTypes...>,
1670                         TypeList<Params...>> {
1671   static constexpr bool value =
1672       std::conjunction_v<ParamCanBeBound<Ns,
1673                                          is_method,
1674                                          Args,
1675                                          std::decay_t<Args>,
1676                                          UnwrappedTypes,
1677                                          Params>...>;
1678 };
1679 
1680 // Core implementation of `Bind()`, which checks common preconditions before
1681 // returning an appropriate callback.
1682 template <template <typename> class CallbackT>
1683 struct BindHelper {
1684  private:
1685   static constexpr bool kIsOnce =
1686       is_instantiation<OnceCallback, CallbackT<void()>>;
1687 
1688   template <typename Traits, bool v = IsComplete<Traits>>
1689   struct TraitsAreInstantiable {
1690     static constexpr bool value = [] {
1691       static_assert(
1692           v, "Could not determine how to invoke functor. If this functor has "
1693              "an overloaded operator()(), bind all arguments to it, and ensure "
1694              "the result will select a unique overload.");
1695       return v;
1696     }();
1697   };
1698 
1699   template <typename Functor,
1700             bool v = !is_instantiation<OnceCallback, std::decay_t<Functor>> ||
1701                      (kIsOnce && std::is_rvalue_reference_v<Functor&&> &&
1702                       !std::is_const_v<std::remove_reference_t<Functor>>)>
1703   struct OnceCallbackFunctorIsValid {
1704     static constexpr bool value = [] {
1705       if constexpr (kIsOnce) {
1706         static_assert(v,
1707                       "BindOnce() requires non-const rvalue for OnceCallback "
1708                       "binding, i.e. base::BindOnce(std::move(callback)).");
1709       } else {
1710         static_assert(v, "BindRepeating() cannot bind OnceCallback. Use "
1711                          "BindOnce() with std::move().");
1712       }
1713       return v;
1714     }();
1715   };
1716 
1717   template <typename... Args>
1718   struct NoBindArgToOnceCallbackIsBasePassed {
1719     static constexpr bool value = [] {
1720       // Can't use a defaulted template param since it can't come after `Args`.
1721       constexpr bool v =
1722           !kIsOnce ||
1723           (... && !is_instantiation<PassedWrapper, std::decay_t<Args>>);
1724       static_assert(
1725           v,
1726           "Use std::move() instead of base::Passed() with base::BindOnce().");
1727       return v;
1728     }();
1729   };
1730 
1731   template <
1732       typename Functor,
1733       bool v =
1734           !is_instantiation<FunctionRef, std::remove_cvref_t<Functor>> &&
1735           !is_instantiation<absl::FunctionRef, std::remove_cvref_t<Functor>>>
1736   struct NotFunctionRef {
1737     static constexpr bool value = [] {
1738       static_assert(
1739           v,
1740           "Functor may not be a FunctionRef, since that is a non-owning "
1741           "reference that may go out of scope before the callback executes.");
1742       return v;
1743     }();
1744   };
1745 
1746   template <typename Traits, bool v = Traits::is_stateless>
1747   struct IsStateless {
1748     static constexpr bool value = [] {
1749       static_assert(
1750           v, "Capturing lambdas and stateful functors are intentionally not "
1751              "supported. Use a non-capturing lambda or stateless functor (i.e. "
1752              "has no non-static data members) and bind arguments directly.");
1753       return v;
1754     }();
1755   };
1756 
1757   template <typename Functor, typename... Args>
1758   static auto BindImpl(Functor&& functor, Args&&... args) {
1759     // There are a lot of variables and type aliases here. An example will be
1760     // illustrative. Assume we call:
1761     // ```
1762     //   struct S {
1763     //     double f(int, const std::string&);
1764     //   } s;
1765     //   int16_t i;
1766     //   BindOnce(&S::f, Unretained(&s), i);
1767     // ```
1768     // This means our template params are:
1769     // ```
1770     //   template <typename> class CallbackT = OnceCallback
1771     //   typename Functor = double (S::*)(int, const std::string&)
1772     //   typename... Args =
1773     //       UnretainedWrapper<S, unretained_traits::MayNotDangle>, int16_t
1774     // ```
1775     // And the implementation below is effectively:
1776     // ```
1777     //   using Traits = struct {
1778     //     using RunType = double(S*, int, const std::string&);
1779     //     static constexpr bool is_method = true;
1780     //     static constexpr bool is_nullable = true;
1781     //     static constexpr bool is_callback = false;
1782     //     static constexpr bool is_stateless = true;
1783     //     ...
1784     //   };
1785     //   using ValidatedUnwrappedTypes = struct {
1786     //     using Type = TypeList<S*, int16_t>;
1787     //     static constexpr bool value = true;
1788     //   };
1789     //   using BoundArgsList = TypeList<S*, int16_t>;
1790     //   using RunParamsList = TypeList<S*, int, const std::string&>;
1791     //   using BoundParamsList = TypeList<S*, int>;
1792     //   using ValidatedBindState = struct {
1793     //     using Type =
1794     //         BindState<double (S::*)(int, const std::string&),
1795     //                   UnretainedWrapper<S, unretained_traits::MayNotDangle>,
1796     //                   int16_t>;
1797     //     static constexpr bool value = true;
1798     //   };
1799     //   if constexpr (true) {
1800     //     using UnboundRunType = double(const std::string&);
1801     //     using CallbackType = OnceCallback<double(const std::string&)>;
1802     //     ...
1803     // ```
1804     using Traits = FunctorTraits<TransformToUnwrappedType<kIsOnce, Functor&&>,
1805                                  TransformToUnwrappedType<kIsOnce, Args&&>...>;
1806     if constexpr (TraitsAreInstantiable<Traits>::value) {
1807       using ValidatedUnwrappedTypes =
1808           ValidateUnwrappedTypeList<kIsOnce, Traits::is_method, Args&&...>;
1809       using BoundArgsList = TypeList<Args...>;
1810       using RunParamsList = ExtractArgs<typename Traits::RunType>;
1811       using BoundParamsList = TakeTypeListItem<sizeof...(Args), RunParamsList>;
1812       using ValidatedBindState =
1813           ValidateBindStateType<Traits::is_method, Traits::is_nullable,
1814                                 Traits::is_callback, Functor, Args...>;
1815       // This conditional checks if each of the `args` matches to the
1816       // corresponding param of the target function. This check does not affect
1817       // the behavior of `Bind()`, but its error message should be more
1818       // readable.
1819       if constexpr (std::conjunction_v<
1820                         NotFunctionRef<Functor>, IsStateless<Traits>,
1821                         ValidatedUnwrappedTypes,
1822                         ParamsCanBeBound<
1823                             Traits::is_method,
1824                             std::make_index_sequence<sizeof...(Args)>,
1825                             BoundArgsList,
1826                             typename ValidatedUnwrappedTypes::Type,
1827                             BoundParamsList>,
1828                         ValidatedBindState>) {
1829         using UnboundRunType =
1830             MakeFunctionType<ExtractReturnType<typename Traits::RunType>,
1831                              DropTypeListItem<sizeof...(Args), RunParamsList>>;
1832         using CallbackType = CallbackT<UnboundRunType>;
1833 
1834         // Store the invoke func into `PolymorphicInvoke` before casting it to
1835         // `InvokeFuncStorage`, so that we can ensure its type matches to
1836         // `PolymorphicInvoke`, to which `CallbackType` will cast back.
1837         typename CallbackType::PolymorphicInvoke invoke_func;
1838         using Invoker =
1839             Invoker<Traits, typename ValidatedBindState::Type, UnboundRunType>;
1840         if constexpr (kIsOnce) {
1841           invoke_func = Invoker::RunOnce;
1842         } else {
1843           invoke_func = Invoker::Run;
1844         }
1845 
1846         return CallbackType(ValidatedBindState::Type::Create(
1847             reinterpret_cast<BindStateBase::InvokeFuncStorage>(invoke_func),
1848             std::forward<Functor>(functor), std::forward<Args>(args)...));
1849       }
1850     }
1851   }
1852 
1853   // Special cases for binding to a `Callback` without extra bound arguments.
1854 
1855   // `OnceCallback` passed to `OnceCallback`, or `RepeatingCallback` passed to
1856   // `RepeatingCallback`.
1857   template <typename T>
1858     requires is_instantiation<CallbackT, T>
1859   static T BindImpl(T callback) {
1860     // Guard against null pointers accidentally ending up in posted tasks,
1861     // causing hard-to-debug crashes.
1862     CHECK(callback);
1863     return callback;
1864   }
1865 
1866   // `RepeatingCallback` passed to `OnceCallback`. The opposite direction is
1867   // intentionally not supported.
1868   template <typename Signature>
1869     requires is_instantiation<CallbackT, OnceCallback<Signature>>
1870   static OnceCallback<Signature> BindImpl(
1871       RepeatingCallback<Signature> callback) {
1872     return BindImpl(OnceCallback<Signature>(callback));
1873   }
1874 
1875   // Must be defined after `BindImpl()` since it refers to it.
1876   template <typename Functor, typename... Args>
1877   struct BindImplWouldSucceed {
1878     // Can't use a defaulted template param since it can't come after `Args`.
1879     //
1880     // Determining if `BindImpl()` would succeed is not as simple as verifying
1881     // any conditions it checks directly; those only control when it's safe to
1882     // call other methods, which in turn may fail. However, ultimately, any
1883     // failure will result in returning `void`, so check for a non-`void` return
1884     // type.
1885     static constexpr bool value =
1886         !std::same_as<void,
1887                       decltype(BindImpl(std::declval<Functor&&>(),
1888                                         std::declval<Args&&>()...))>;
1889   };
1890 
1891  public:
1892   template <typename Functor, typename... Args>
1893   static auto Bind(Functor&& functor, Args&&... args) {
1894     if constexpr (std::conjunction_v<
1895                       OnceCallbackFunctorIsValid<Functor>,
1896                       NoBindArgToOnceCallbackIsBasePassed<Args...>,
1897                       BindImplWouldSucceed<Functor, Args...>>) {
1898       return BindImpl(std::forward<Functor>(functor),
1899                       std::forward<Args>(args)...);
1900     } else {
1901       return BindFailedCheckPreviousErrors();
1902     }
1903   }
1904 };
1905 
1906 }  // namespace internal
1907 
1908 // An injection point to control `this` pointer behavior on a method invocation.
1909 // If `IsWeakReceiver<T>::value` is `true` and `T` is used as a method receiver,
1910 // `Bind()` cancels the method invocation if the receiver tests as false.
1911 // ```
1912 //   struct S : SupportsWeakPtr<S> {
1913 //     void f() {}
1914 //   };
1915 //
1916 //   WeakPtr<S> weak_s = nullptr;
1917 //   BindOnce(&S::f, weak_s).Run();  // `S::f()` is not called.
1918 // ```
1919 template <typename T>
1920 struct IsWeakReceiver : std::bool_constant<is_instantiation<WeakPtr, T>> {};
1921 
1922 template <typename T>
1923 struct IsWeakReceiver<std::reference_wrapper<T>> : IsWeakReceiver<T> {};
1924 
1925 // An injection point to control how objects are checked for maybe validity,
1926 // which is an optimistic thread-safe check for full validity.
1927 template <typename>
1928 struct MaybeValidTraits {
1929   template <typename T>
1930   static bool MaybeValid(const T& o) {
1931     return o.MaybeValid();
1932   }
1933 };
1934 
1935 // An injection point to control how bound objects passed to the target
1936 // function. `BindUnwrapTraits<>::Unwrap()` is called for each bound object
1937 // right before the target function is invoked.
1938 template <typename>
1939 struct BindUnwrapTraits {
1940   template <typename T>
1941   static T&& Unwrap(T&& o) {
1942     return std::forward<T>(o);
1943   }
1944 };
1945 
1946 template <typename T>
1947   requires internal::kIsUnretainedWrapper<internal::UnretainedWrapper, T> ||
1948            internal::kIsUnretainedWrapper<internal::UnretainedRefWrapper, T> ||
1949            is_instantiation<internal::RetainedRefWrapper, T> ||
1950            is_instantiation<internal::OwnedWrapper, T> ||
1951            is_instantiation<internal::OwnedRefWrapper, T>
1952 struct BindUnwrapTraits<T> {
1953   static decltype(auto) Unwrap(const T& o) { return o.get(); }
1954 };
1955 
1956 template <typename T>
1957 struct BindUnwrapTraits<internal::PassedWrapper<T>> {
1958   static T Unwrap(const internal::PassedWrapper<T>& o) { return o.Take(); }
1959 };
1960 
1961 #if BUILDFLAG(IS_WIN)
1962 template <typename T>
1963 struct BindUnwrapTraits<Microsoft::WRL::ComPtr<T>> {
1964   static T* Unwrap(const Microsoft::WRL::ComPtr<T>& ptr) { return ptr.Get(); }
1965 };
1966 #endif
1967 
1968 // `CallbackCancellationTraits` allows customization of `Callback`'s
1969 // cancellation semantics. By default, callbacks are not cancellable. A
1970 // specialization should set `is_cancellable` and implement an `IsCancelled()`
1971 // that returns whether the callback should be cancelled, as well as a
1972 // `MaybeValid()` that returns whether the underlying functor/object is maybe
1973 // valid.
1974 template <typename Functor, typename BoundArgsTuple>
1975 struct CallbackCancellationTraits {
1976   static constexpr bool is_cancellable = false;
1977 };
1978 
1979 // Specialization for a weak receiver.
1980 template <typename Functor, typename... BoundArgs>
1981   requires internal::kIsWeakMethod<
1982       internal::FunctorTraits<Functor, BoundArgs...>::is_method,
1983       BoundArgs...>
1984 struct CallbackCancellationTraits<Functor, std::tuple<BoundArgs...>> {
1985   static constexpr bool is_cancellable = true;
1986 
1987   template <typename Receiver, typename... Args>
1988   static bool IsCancelled(const Functor&,
1989                           const Receiver& receiver,
1990                           const Args&...) {
1991     return !receiver;
1992   }
1993 
1994   template <typename Receiver, typename... Args>
1995   static bool MaybeValid(const Functor&,
1996                          const Receiver& receiver,
1997                          const Args&...) {
1998     return MaybeValidTraits<Receiver>::MaybeValid(receiver);
1999   }
2000 };
2001 
2002 // Specialization for a nested `Bind()`.
2003 template <typename Functor, typename... BoundArgs>
2004   requires is_instantiation<OnceCallback, Functor> ||
2005            is_instantiation<RepeatingCallback, Functor>
2006 struct CallbackCancellationTraits<Functor, std::tuple<BoundArgs...>> {
2007   static constexpr bool is_cancellable = true;
2008 
2009   static bool IsCancelled(const Functor& functor, const BoundArgs&...) {
2010     return functor.IsCancelled();
2011   }
2012 
2013   static bool MaybeValid(const Functor& functor, const BoundArgs&...) {
2014     return MaybeValidTraits<Functor>::MaybeValid(functor);
2015   }
2016 };
2017 
2018 }  // namespace base
2019 
2020 #endif  // BASE_FUNCTIONAL_BIND_INTERNAL_H_
2021