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