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