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