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