bind_internal.h (70794B)
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/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr.h" 19 #include "base/check.h" 20 #include "base/compiler_specific.h" 21 #include "base/functional/callback_internal.h" 22 #include "base/functional/disallow_unretained.h" 23 #include "base/functional/unretained_traits.h" 24 #include "base/memory/raw_ptr.h" 25 #include "base/memory/raw_ptr_asan_bound_arg_tracker.h" 26 #include "base/memory/raw_ref.h" 27 #include "base/memory/raw_scoped_refptr_mismatch_checker.h" 28 #include "base/memory/weak_ptr.h" 29 #include "base/notreached.h" 30 #include "base/types/always_false.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, typename SFINAE = void> 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, typename SFINAE = void> 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_asserts in base::internal::AssertConstructible. 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 template <RawPtrTraits PTraits = PtrTraits, 138 typename = std::enable_if_t<PTraits == RawPtrTraits::kEmpty>> 139 explicit UnretainedWrapper(T* o) : ptr_(o) {} 140 141 // Trick to only instantiate these constructors if they are used. Otherwise, 142 // instantiating UnretainedWrapper with a T that is not supported by 143 // raw_ptr would trigger raw_ptr<T>'s static_assert. 144 template <typename U = T> 145 explicit UnretainedWrapper(const raw_ptr<U, PtrTraits>& o) : ptr_(o) {} 146 template <typename U = T> 147 explicit UnretainedWrapper(raw_ptr<U, PtrTraits>&& o) : ptr_(std::move(o)) {} 148 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> 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> 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 template <RawPtrTraits PTraits = PtrTraits, 211 typename = std::enable_if_t<PTraits == RawPtrTraits::kEmpty>> 212 explicit UnretainedRefWrapper(T& o) : ref_(o) {} 213 214 // Trick to only instantiate these constructors if they are used. Otherwise, 215 // instantiating UnretainedWrapper with a T that is not supported by 216 // raw_ref would trigger raw_ref<T>'s static_assert. 217 template <typename U = T> 218 explicit UnretainedRefWrapper(const raw_ref<U, PtrTraits>& o) : ref_(o) {} 219 template <typename U = T> 220 explicit UnretainedRefWrapper(raw_ref<U, PtrTraits>&& o) 221 : ref_(std::move(o)) {} 222 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> 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> 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) 277 UnretainedRefWrapperReceiver( 278 UnretainedRefWrapper<T, UnretainedTrait, PtrTraits>&& obj) 279 : obj_(std::move(obj)) {} 280 // NOLINTNEXTLINE(google-explicit-constructor) 281 T& operator*() const { return obj_.get(); } 282 283 private: 284 UnretainedRefWrapper<T, UnretainedTrait, PtrTraits> obj_; 285 }; 286 287 // MethodReceiverStorageType converts the current receiver type to its stored 288 // type. For instance, it converts pointers to `scoped_refptr`, and wraps 289 // `UnretainedRefWrapper` to make it compliant with the internal callback 290 // invocation mechanism. 291 template <typename T> 292 struct MethodReceiverStorageType { 293 using Type = 294 std::conditional_t<IsPointerV<T>, scoped_refptr<RemovePointerT<T>>, T>; 295 }; 296 297 template <typename T, typename UnretainedTrait, RawPtrTraits PtrTraits> 298 struct MethodReceiverStorageType< 299 UnretainedRefWrapper<T, UnretainedTrait, PtrTraits>> { 300 // We can't use UnretainedRefWrapper as a receiver directly (see 301 // UnretainedRefWrapperReceiver for why). 302 using Type = UnretainedRefWrapperReceiver<T, UnretainedTrait, PtrTraits>; 303 }; 304 305 template <typename T> 306 class RetainedRefWrapper { 307 public: 308 explicit RetainedRefWrapper(T* o) : ptr_(o) {} 309 explicit RetainedRefWrapper(scoped_refptr<T> o) : ptr_(std::move(o)) {} 310 T* get() const { return ptr_.get(); } 311 312 private: 313 scoped_refptr<T> ptr_; 314 }; 315 316 template <typename T> 317 struct IgnoreResultHelper { 318 explicit IgnoreResultHelper(T functor) : functor_(std::move(functor)) {} 319 explicit operator bool() const { return !!functor_; } 320 321 T functor_; 322 }; 323 324 template <typename T, typename Deleter = std::default_delete<T>> 325 class OwnedWrapper { 326 public: 327 explicit OwnedWrapper(T* o) : ptr_(o) {} 328 explicit OwnedWrapper(std::unique_ptr<T, Deleter>&& ptr) 329 : ptr_(std::move(ptr)) {} 330 T* get() const { return ptr_.get(); } 331 332 private: 333 std::unique_ptr<T, Deleter> ptr_; 334 }; 335 336 template <typename T> 337 class OwnedRefWrapper { 338 public: 339 explicit OwnedRefWrapper(const T& t) : t_(t) {} 340 explicit OwnedRefWrapper(T&& t) : t_(std::move(t)) {} 341 T& get() const { return t_; } 342 343 private: 344 mutable T t_; 345 }; 346 347 // PassedWrapper is a copyable adapter for a scoper that ignores const. 348 // 349 // It is needed to get around the fact that Bind() takes a const reference to 350 // all its arguments. Because Bind() takes a const reference to avoid 351 // unnecessary copies, it is incompatible with movable-but-not-copyable 352 // types; doing a destructive "move" of the type into Bind() would violate 353 // the const correctness. 354 // 355 // This conundrum cannot be solved without either C++11 rvalue references or 356 // a O(2^n) blowup of Bind() templates to handle each combination of regular 357 // types and movable-but-not-copyable types. Thus we introduce a wrapper type 358 // that is copyable to transmit the correct type information down into 359 // BindState<>. Ignoring const in this type makes sense because it is only 360 // created when we are explicitly trying to do a destructive move. 361 // 362 // Two notes: 363 // 1) PassedWrapper supports any type that has a move constructor, however 364 // the type will need to be specifically allowed in order for it to be 365 // bound to a Callback. We guard this explicitly at the call of Passed() 366 // to make for clear errors. Things not given to Passed() will be forwarded 367 // and stored by value which will not work for general move-only types. 368 // 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL" 369 // scoper to a Callback and allow the Callback to execute once. 370 template <typename T> 371 class PassedWrapper { 372 public: 373 explicit PassedWrapper(T&& scoper) : scoper_(std::move(scoper)) {} 374 PassedWrapper(PassedWrapper&& other) 375 : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {} 376 T Take() const { 377 CHECK(is_valid_); 378 is_valid_ = false; 379 return std::move(scoper_); 380 } 381 382 private: 383 mutable bool is_valid_ = true; 384 mutable T scoper_; 385 }; 386 387 template <typename T> 388 using Unwrapper = BindUnwrapTraits<std::decay_t<T>>; 389 390 template <typename T> 391 decltype(auto) Unwrap(T&& o) { 392 return Unwrapper<T>::Unwrap(std::forward<T>(o)); 393 } 394 395 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a 396 // method. It is used internally by Bind() to select the correct 397 // InvokeHelper that will no-op itself in the event the WeakPtr<> for 398 // the target object is invalidated. 399 // 400 // The first argument should be the type of the object that will be received by 401 // the method. 402 template <bool is_method, typename... Args> 403 struct IsWeakMethod : std::false_type {}; 404 405 template <typename T, typename... Args> 406 struct IsWeakMethod<true, T, Args...> : IsWeakReceiver<T> {}; 407 408 // Packs a list of types to hold them in a single type. 409 template <typename... Types> 410 struct TypeList {}; 411 412 // Used for DropTypeListItem implementation. 413 template <size_t n, typename List> 414 struct DropTypeListItemImpl; 415 416 // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. 417 template <size_t n, typename T, typename... List> 418 struct DropTypeListItemImpl<n, TypeList<T, List...>> 419 : DropTypeListItemImpl<n - 1, TypeList<List...>> {}; 420 421 template <typename T, typename... List> 422 struct DropTypeListItemImpl<0, TypeList<T, List...>> { 423 using Type = TypeList<T, List...>; 424 }; 425 426 template <> 427 struct DropTypeListItemImpl<0, TypeList<>> { 428 using Type = TypeList<>; 429 }; 430 431 // A type-level function that drops |n| list item from given TypeList. 432 template <size_t n, typename List> 433 using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type; 434 435 // Used for TakeTypeListItem implementation. 436 template <size_t n, typename List, typename... Accum> 437 struct TakeTypeListItemImpl; 438 439 // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. 440 template <size_t n, typename T, typename... List, typename... Accum> 441 struct TakeTypeListItemImpl<n, TypeList<T, List...>, Accum...> 442 : TakeTypeListItemImpl<n - 1, TypeList<List...>, Accum..., T> {}; 443 444 template <typename T, typename... List, typename... Accum> 445 struct TakeTypeListItemImpl<0, TypeList<T, List...>, Accum...> { 446 using Type = TypeList<Accum...>; 447 }; 448 449 template <typename... Accum> 450 struct TakeTypeListItemImpl<0, TypeList<>, Accum...> { 451 using Type = TypeList<Accum...>; 452 }; 453 454 // A type-level function that takes first |n| list item from given TypeList. 455 // E.g. TakeTypeListItem<3, TypeList<A, B, C, D>> is evaluated to 456 // TypeList<A, B, C>. 457 template <size_t n, typename List> 458 using TakeTypeListItem = typename TakeTypeListItemImpl<n, List>::Type; 459 460 // Used for ConcatTypeLists implementation. 461 template <typename List1, typename List2> 462 struct ConcatTypeListsImpl; 463 464 template <typename... Types1, typename... Types2> 465 struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> { 466 using Type = TypeList<Types1..., Types2...>; 467 }; 468 469 // A type-level function that concats two TypeLists. 470 template <typename List1, typename List2> 471 using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type; 472 473 // Used for MakeFunctionType implementation. 474 template <typename R, typename ArgList> 475 struct MakeFunctionTypeImpl; 476 477 template <typename R, typename... Args> 478 struct MakeFunctionTypeImpl<R, TypeList<Args...>> { 479 // MSVC 2013 doesn't support Type Alias of function types. 480 // Revisit this after we update it to newer version. 481 typedef R Type(Args...); 482 }; 483 484 // A type-level function that constructs a function type that has |R| as its 485 // return type and has TypeLists items as its arguments. 486 template <typename R, typename ArgList> 487 using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type; 488 489 // Used for ExtractArgs and ExtractReturnType. 490 template <typename Signature> 491 struct ExtractArgsImpl; 492 493 template <typename R, typename... Args> 494 struct ExtractArgsImpl<R(Args...)> { 495 using ReturnType = R; 496 using ArgsList = TypeList<Args...>; 497 }; 498 499 // A type-level function that extracts function arguments into a TypeList. 500 // E.g. ExtractArgs<R(A, B, C)> is evaluated to TypeList<A, B, C>. 501 template <typename Signature> 502 using ExtractArgs = typename ExtractArgsImpl<Signature>::ArgsList; 503 504 // A type-level function that extracts the return type of a function. 505 // E.g. ExtractReturnType<R(A, B, C)> is evaluated to R. 506 template <typename Signature> 507 using ExtractReturnType = typename ExtractArgsImpl<Signature>::ReturnType; 508 509 template <typename Callable, 510 typename Signature = decltype(&Callable::operator())> 511 struct ExtractCallableRunTypeImpl; 512 513 template <typename Callable, typename R, typename... Args> 514 struct ExtractCallableRunTypeImpl<Callable, R (Callable::*)(Args...)> { 515 using Type = R(Args...); 516 }; 517 518 template <typename Callable, typename R, typename... Args> 519 struct ExtractCallableRunTypeImpl<Callable, R (Callable::*)(Args...) const> { 520 using Type = R(Args...); 521 }; 522 523 template <typename Callable, typename R, typename... Args> 524 struct ExtractCallableRunTypeImpl<Callable, R (Callable::*)(Args...) noexcept> { 525 using Type = R(Args...); 526 }; 527 528 template <typename Callable, typename R, typename... Args> 529 struct ExtractCallableRunTypeImpl<Callable, 530 R (Callable::*)(Args...) const noexcept> { 531 using Type = R(Args...); 532 }; 533 534 // Evaluated to RunType of the given callable type. 535 // Example: 536 // auto f = [](int, char*) { return 0.1; }; 537 // ExtractCallableRunType<decltype(f)> 538 // is evaluated to 539 // double(int, char*); 540 template <typename Callable> 541 using ExtractCallableRunType = 542 typename ExtractCallableRunTypeImpl<Callable>::Type; 543 544 // IsCallableObject<Functor> is std::true_type if |Functor| has operator(). 545 // Otherwise, it's std::false_type. 546 // Example: 547 // IsCallableObject<void(*)()>::value is false. 548 // 549 // struct Foo {}; 550 // IsCallableObject<void(Foo::*)()>::value is false. 551 // 552 // int i = 0; 553 // auto f = [i] {}; 554 // IsCallableObject<decltype(f)>::value is false. 555 template <typename Functor, typename SFINAE = void> 556 struct IsCallableObject : std::false_type {}; 557 558 template <typename Callable> 559 struct IsCallableObject<Callable, std::void_t<decltype(&Callable::operator())>> 560 : std::true_type {}; 561 562 // HasRefCountedTypeAsRawPtr inherits from true_type when any of the |Args| is a 563 // raw pointer to a RefCounted type. 564 template <typename... Ts> 565 struct HasRefCountedTypeAsRawPtr 566 : std::disjunction<NeedsScopedRefptrButGetsRawPtr<Ts>...> {}; 567 568 // ForceVoidReturn<> 569 // 570 // Set of templates that support forcing the function return type to void. 571 template <typename Sig> 572 struct ForceVoidReturn; 573 574 template <typename R, typename... Args> 575 struct ForceVoidReturn<R(Args...)> { 576 using RunType = void(Args...); 577 }; 578 579 // FunctorTraits<> 580 // 581 // See description at top of file. 582 template <typename Functor, typename SFINAE> 583 struct FunctorTraits; 584 585 // For callable types. 586 // This specialization handles lambdas (captureless and capturing) and functors 587 // with a call operator. Capturing lambdas and stateful functors are explicitly 588 // disallowed by BindImpl(). 589 // 590 // Example: 591 // 592 // // Captureless lambdas are allowed. 593 // [] { return 42; }; 594 // 595 // // Capturing lambdas are *not* allowed. 596 // int x; 597 // [x] { return x; }; 598 // 599 // // Any empty class with operator() is allowed. 600 // struct Foo { 601 // void operator()() const {} 602 // // No non-static member variable and no virtual functions. 603 // }; 604 template <typename Functor> 605 struct FunctorTraits<Functor, 606 std::enable_if_t<IsCallableObject<Functor>::value>> { 607 using RunType = ExtractCallableRunType<Functor>; 608 static constexpr bool is_method = false; 609 static constexpr bool is_nullable = false; 610 static constexpr bool is_callback = false; 611 static constexpr bool is_stateless = std::is_empty_v<Functor>; 612 613 template <typename RunFunctor, typename... RunArgs> 614 static ExtractReturnType<RunType> Invoke(RunFunctor&& functor, 615 RunArgs&&... args) { 616 return std::forward<RunFunctor>(functor)(std::forward<RunArgs>(args)...); 617 } 618 }; 619 620 // For functions. 621 template <typename R, typename... Args> 622 struct FunctorTraits<R (*)(Args...)> { 623 using RunType = R(Args...); 624 static constexpr bool is_method = false; 625 static constexpr bool is_nullable = true; 626 static constexpr bool is_callback = false; 627 static constexpr bool is_stateless = true; 628 629 template <typename Function, typename... RunArgs> 630 static R Invoke(Function&& function, RunArgs&&... args) { 631 return std::forward<Function>(function)(std::forward<RunArgs>(args)...); 632 } 633 }; 634 635 #if BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS) 636 637 // For functions. 638 template <typename R, typename... Args> 639 struct FunctorTraits<R(__stdcall*)(Args...)> { 640 using RunType = R(Args...); 641 static constexpr bool is_method = false; 642 static constexpr bool is_nullable = true; 643 static constexpr bool is_callback = false; 644 static constexpr bool is_stateless = true; 645 646 template <typename... RunArgs> 647 static R Invoke(R(__stdcall* function)(Args...), RunArgs&&... args) { 648 return function(std::forward<RunArgs>(args)...); 649 } 650 }; 651 652 // For functions. 653 template <typename R, typename... Args> 654 struct FunctorTraits<R(__fastcall*)(Args...)> { 655 using RunType = R(Args...); 656 static constexpr bool is_method = false; 657 static constexpr bool is_nullable = true; 658 static constexpr bool is_callback = false; 659 static constexpr bool is_stateless = true; 660 661 template <typename... RunArgs> 662 static R Invoke(R(__fastcall* function)(Args...), RunArgs&&... args) { 663 return function(std::forward<RunArgs>(args)...); 664 } 665 }; 666 667 #endif // BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS) 668 669 #if __OBJC__ 670 671 // Support for Objective-C blocks. Blocks can be bound as the compiler will 672 // ensure their lifetimes will be correctly managed. 673 674 #if HAS_FEATURE(objc_arc) 675 676 template <typename R, typename... Args> 677 struct FunctorTraits<R (^)(Args...)> { 678 using RunType = R(Args...); 679 static constexpr bool is_method = false; 680 static constexpr bool is_nullable = true; 681 static constexpr bool is_callback = false; 682 static constexpr bool is_stateless = true; 683 684 template <typename BlockType, typename... RunArgs> 685 static R Invoke(BlockType&& block, RunArgs&&... args) { 686 // According to LLVM documentation (§ 6.3), "local variables of automatic 687 // storage duration do not have precise lifetime." Use objc_precise_lifetime 688 // to ensure that the Objective-C block is not deallocated until it has 689 // finished executing even if the Callback<> is destroyed during the block 690 // execution. 691 // https://clang.llvm.org/docs/AutomaticReferenceCounting.html#precise-lifetime-semantics 692 __attribute__((objc_precise_lifetime)) R (^scoped_block)(Args...) = block; 693 return scoped_block(std::forward<RunArgs>(args)...); 694 } 695 }; 696 697 #endif // HAS_FEATURE(objc_arc) 698 #endif // __OBJC__ 699 700 // For methods. 701 template <typename R, typename Receiver, typename... Args> 702 struct FunctorTraits<R (Receiver::*)(Args...)> { 703 using RunType = R(Receiver*, Args...); 704 static constexpr bool is_method = true; 705 static constexpr bool is_nullable = true; 706 static constexpr bool is_callback = false; 707 static constexpr bool is_stateless = true; 708 709 template <typename Method, typename ReceiverPtr, typename... RunArgs> 710 static R Invoke(Method method, 711 ReceiverPtr&& receiver_ptr, 712 RunArgs&&... args) { 713 return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...); 714 } 715 }; 716 717 // For const methods. 718 template <typename R, typename Receiver, typename... Args> 719 struct FunctorTraits<R (Receiver::*)(Args...) const> { 720 using RunType = R(const Receiver*, Args...); 721 static constexpr bool is_method = true; 722 static constexpr bool is_nullable = true; 723 static constexpr bool is_callback = false; 724 static constexpr bool is_stateless = true; 725 726 template <typename Method, typename ReceiverPtr, typename... RunArgs> 727 static R Invoke(Method method, 728 ReceiverPtr&& receiver_ptr, 729 RunArgs&&... args) { 730 return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...); 731 } 732 }; 733 734 #if BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS) 735 736 // For __stdcall methods. 737 template <typename R, typename Receiver, typename... Args> 738 struct FunctorTraits<R (__stdcall Receiver::*)(Args...)> 739 : public FunctorTraits<R (Receiver::*)(Args...)> {}; 740 741 // For __stdcall const methods. 742 template <typename R, typename Receiver, typename... Args> 743 struct FunctorTraits<R (__stdcall Receiver::*)(Args...) const> 744 : public FunctorTraits<R (Receiver::*)(Args...) const> {}; 745 746 #endif // BUILDFLAG(IS_WIN) && !defined(ARCH_CPU_64_BITS) 747 748 #ifdef __cpp_noexcept_function_type 749 // noexcept makes a distinct function type in C++17. 750 // I.e. `void(*)()` and `void(*)() noexcept` are same in pre-C++17, and 751 // different in C++17. 752 template <typename R, typename... Args> 753 struct FunctorTraits<R (*)(Args...) noexcept> : FunctorTraits<R (*)(Args...)> { 754 }; 755 756 template <typename R, typename Receiver, typename... Args> 757 struct FunctorTraits<R (Receiver::*)(Args...) noexcept> 758 : FunctorTraits<R (Receiver::*)(Args...)> {}; 759 760 template <typename R, typename Receiver, typename... Args> 761 struct FunctorTraits<R (Receiver::*)(Args...) const noexcept> 762 : FunctorTraits<R (Receiver::*)(Args...) const> {}; 763 #endif 764 765 // For IgnoreResults. 766 template <typename T> 767 struct FunctorTraits<IgnoreResultHelper<T>> : FunctorTraits<T> { 768 using RunType = 769 typename ForceVoidReturn<typename FunctorTraits<T>::RunType>::RunType; 770 771 template <typename IgnoreResultType, typename... RunArgs> 772 static void Invoke(IgnoreResultType&& ignore_result_helper, 773 RunArgs&&... args) { 774 FunctorTraits<T>::Invoke( 775 std::forward<IgnoreResultType>(ignore_result_helper).functor_, 776 std::forward<RunArgs>(args)...); 777 } 778 }; 779 780 // For OnceCallbacks. 781 template <typename R, typename... Args> 782 struct FunctorTraits<OnceCallback<R(Args...)>> { 783 using RunType = R(Args...); 784 static constexpr bool is_method = false; 785 static constexpr bool is_nullable = true; 786 static constexpr bool is_callback = true; 787 static constexpr bool is_stateless = true; 788 789 template <typename CallbackType, typename... RunArgs> 790 static R Invoke(CallbackType&& callback, RunArgs&&... args) { 791 DCHECK(!callback.is_null()); 792 return std::forward<CallbackType>(callback).Run( 793 std::forward<RunArgs>(args)...); 794 } 795 }; 796 797 // For RepeatingCallbacks. 798 template <typename R, typename... Args> 799 struct FunctorTraits<RepeatingCallback<R(Args...)>> { 800 using RunType = R(Args...); 801 static constexpr bool is_method = false; 802 static constexpr bool is_nullable = true; 803 static constexpr bool is_callback = true; 804 static constexpr bool is_stateless = true; 805 806 template <typename CallbackType, typename... RunArgs> 807 static R Invoke(CallbackType&& callback, RunArgs&&... args) { 808 DCHECK(!callback.is_null()); 809 return std::forward<CallbackType>(callback).Run( 810 std::forward<RunArgs>(args)...); 811 } 812 }; 813 814 template <typename Functor> 815 using MakeFunctorTraits = FunctorTraits<std::decay_t<Functor>>; 816 817 // StorageTraits<> 818 // 819 // See description at top of file. 820 template <typename T> 821 struct StorageTraits { 822 using Type = T; 823 }; 824 825 // For T*, store as UnretainedWrapper<T> for safety, as it internally uses 826 // raw_ptr<T> (when possible). 827 template <typename T> 828 struct StorageTraits<T*> { 829 using Type = UnretainedWrapper<T, unretained_traits::MayNotDangle>; 830 }; 831 832 // For raw_ptr<T>, store as UnretainedWrapper<T> for safety. This may seem 833 // contradictory, but this ensures guaranteed protection for the pointer even 834 // during execution of callbacks with parameters of type raw_ptr<T>. 835 template <typename T, RawPtrTraits PtrTraits> 836 struct StorageTraits<raw_ptr<T, PtrTraits>> { 837 using Type = UnretainedWrapper<T, unretained_traits::MayNotDangle, PtrTraits>; 838 }; 839 840 // Unwrap std::reference_wrapper and store it in a custom wrapper so that 841 // references are also protected with raw_ptr<T>. 842 template <typename T> 843 struct StorageTraits<std::reference_wrapper<T>> { 844 using Type = UnretainedRefWrapper<T, unretained_traits::MayNotDangle>; 845 }; 846 847 template <typename T> 848 using MakeStorageType = typename StorageTraits<std::decay_t<T>>::Type; 849 850 // InvokeHelper<> 851 // 852 // There are 2 logical InvokeHelper<> specializations: normal, WeakCalls. 853 // 854 // The normal type just calls the underlying runnable. 855 // 856 // WeakCalls need special syntax that is applied to the first argument to check 857 // if they should no-op themselves. 858 template <bool is_weak_call, typename ReturnType, size_t... indices> 859 struct InvokeHelper; 860 861 template <typename ReturnType, size_t... indices> 862 struct InvokeHelper<false, ReturnType, indices...> { 863 template <typename Functor, typename BoundArgsTuple, typename... RunArgs> 864 static inline ReturnType MakeItSo(Functor&& functor, 865 BoundArgsTuple&& bound, 866 RunArgs&&... args) { 867 using Traits = MakeFunctorTraits<Functor>; 868 return Traits::Invoke( 869 std::forward<Functor>(functor), 870 Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))..., 871 std::forward<RunArgs>(args)...); 872 } 873 }; 874 875 template <typename ReturnType, size_t index_target, size_t... index_tail> 876 struct InvokeHelper<true, ReturnType, index_target, index_tail...> { 877 // WeakCalls are only supported for functions with a void return type. 878 // Otherwise, the function result would be undefined if the WeakPtr<> 879 // is invalidated. 880 static_assert(std::is_void_v<ReturnType>, 881 "weak_ptrs can only bind to methods without return values"); 882 883 template <typename Functor, typename BoundArgsTuple, typename... RunArgs> 884 static inline void MakeItSo(Functor&& functor, 885 BoundArgsTuple&& bound, 886 RunArgs&&... args) { 887 static_assert(index_target == 0); 888 // Note the validity of the weak pointer should be tested _after_ it is 889 // unwrapped, otherwise it creates a race for weak pointer implementations 890 // that allow cross-thread usage and perform `Lock()` in Unwrap() traits. 891 const auto& target = Unwrap(std::get<0>(bound)); 892 if (!target) { 893 return; 894 } 895 using Traits = MakeFunctorTraits<Functor>; 896 Traits::Invoke( 897 std::forward<Functor>(functor), target, 898 Unwrap(std::get<index_tail>(std::forward<BoundArgsTuple>(bound)))..., 899 std::forward<RunArgs>(args)...); 900 } 901 }; 902 903 // Invoker<> 904 // 905 // See description at the top of the file. 906 template <typename StorageType, typename UnboundRunType> 907 struct Invoker; 908 909 template <typename StorageType, typename R, typename... UnboundArgs> 910 struct Invoker<StorageType, R(UnboundArgs...)> { 911 static R RunOnce(BindStateBase* base, 912 PassingType<UnboundArgs>... unbound_args) { 913 // Local references to make debugger stepping easier. If in a debugger, 914 // you really want to warp ahead and step through the 915 // InvokeHelper<>::MakeItSo() call below. 916 StorageType* storage = static_cast<StorageType*>(base); 917 static constexpr size_t num_bound_args = 918 std::tuple_size_v<decltype(storage->bound_args_)>; 919 return RunImpl(std::move(storage->functor_), 920 std::move(storage->bound_args_), 921 std::make_index_sequence<num_bound_args>(), 922 std::forward<UnboundArgs>(unbound_args)...); 923 } 924 925 static R Run(BindStateBase* base, PassingType<UnboundArgs>... unbound_args) { 926 // Local references to make debugger stepping easier. If in a debugger, 927 // you really want to warp ahead and step through the 928 // InvokeHelper<>::MakeItSo() call below. 929 const StorageType* storage = static_cast<StorageType*>(base); 930 static constexpr size_t num_bound_args = 931 std::tuple_size_v<decltype(storage->bound_args_)>; 932 return RunImpl(storage->functor_, storage->bound_args_, 933 std::make_index_sequence<num_bound_args>(), 934 std::forward<UnboundArgs>(unbound_args)...); 935 } 936 937 private: 938 template <typename Functor, typename BoundArgsTuple, size_t... indices> 939 static inline R RunImpl(Functor&& functor, 940 BoundArgsTuple&& bound, 941 std::index_sequence<indices...> seq, 942 UnboundArgs&&... unbound_args) { 943 static constexpr bool is_method = MakeFunctorTraits<Functor>::is_method; 944 945 using DecayedArgsTuple = std::decay_t<BoundArgsTuple>; 946 947 #if BUILDFLAG(USE_ASAN_BACKUP_REF_PTR) 948 RawPtrAsanBoundArgTracker raw_ptr_asan_bound_arg_tracker; 949 raw_ptr_asan_bound_arg_tracker.AddArgs( 950 std::get<indices>(std::forward<BoundArgsTuple>(bound))..., 951 std::forward<UnboundArgs>(unbound_args)...); 952 #endif // BUILDFLAG(USE_ASAN_BACKUP_REF_PTR) 953 954 static constexpr bool is_weak_call = 955 IsWeakMethod<is_method, 956 std::tuple_element_t<indices, DecayedArgsTuple>...>(); 957 958 // Do not `Unwrap()` here, as that immediately triggers dangling pointer 959 // detection. Dangling pointer detection should only be triggered if the 960 // callback is not cancelled, but cancellation status is not determined 961 // until later inside the InvokeHelper::MakeItSo specialization for weak 962 // calls. 963 // 964 // Dangling pointers when invoking a cancelled callback are not considered 965 // a memory safety error because protecting raw pointers usage with weak 966 // receivers (where the weak receiver usually own the pointed objects) is a 967 // common and broadly used pattern in the codebase. 968 return InvokeHelper<is_weak_call, R, indices...>::MakeItSo( 969 std::forward<Functor>(functor), std::forward<BoundArgsTuple>(bound), 970 std::forward<UnboundArgs>(unbound_args)...); 971 } 972 }; 973 974 // Extracts necessary type info from Functor and BoundArgs. 975 // Used to implement MakeUnboundRunType, BindOnce and BindRepeating. 976 template <typename Functor, typename... BoundArgs> 977 struct BindTypeHelper { 978 static constexpr size_t num_bounds = sizeof...(BoundArgs); 979 using FunctorTraits = MakeFunctorTraits<Functor>; 980 981 // Example: 982 // When Functor is `double (Foo::*)(int, const std::string&)`, and BoundArgs 983 // is a template pack of `Foo*` and `int16_t`: 984 // - RunType is `double(Foo*, int, const std::string&)`, 985 // - ReturnType is `double`, 986 // - RunParamsList is `TypeList<Foo*, int, const std::string&>`, 987 // - BoundParamsList is `TypeList<Foo*, int>`, 988 // - UnboundParamsList is `TypeList<const std::string&>`, 989 // - BoundArgsList is `TypeList<Foo*, int16_t>`, 990 // - UnboundRunType is `double(const std::string&)`. 991 using RunType = typename FunctorTraits::RunType; 992 using ReturnType = ExtractReturnType<RunType>; 993 994 using RunParamsList = ExtractArgs<RunType>; 995 using BoundParamsList = TakeTypeListItem<num_bounds, RunParamsList>; 996 using UnboundParamsList = DropTypeListItem<num_bounds, RunParamsList>; 997 998 using BoundArgsList = TypeList<BoundArgs...>; 999 1000 using UnboundRunType = MakeFunctionType<ReturnType, UnboundParamsList>; 1001 }; 1002 1003 template <typename Functor> 1004 std::enable_if_t<FunctorTraits<Functor>::is_nullable, bool> IsNull( 1005 const Functor& functor) { 1006 return !functor; 1007 } 1008 1009 template <typename Functor> 1010 std::enable_if_t<!FunctorTraits<Functor>::is_nullable, bool> IsNull( 1011 const Functor&) { 1012 return false; 1013 } 1014 1015 // Used by QueryCancellationTraits below. 1016 template <typename Functor, typename BoundArgsTuple, size_t... indices> 1017 bool QueryCancellationTraitsImpl(BindStateBase::CancellationQueryMode mode, 1018 const Functor& functor, 1019 const BoundArgsTuple& bound_args, 1020 std::index_sequence<indices...>) { 1021 switch (mode) { 1022 case BindStateBase::IS_CANCELLED: 1023 return CallbackCancellationTraits<Functor, BoundArgsTuple>::IsCancelled( 1024 functor, std::get<indices>(bound_args)...); 1025 case BindStateBase::MAYBE_VALID: 1026 return CallbackCancellationTraits<Functor, BoundArgsTuple>::MaybeValid( 1027 functor, std::get<indices>(bound_args)...); 1028 } 1029 NOTREACHED(); 1030 return false; 1031 } 1032 1033 // Relays |base| to corresponding CallbackCancellationTraits<>::Run(). Returns 1034 // true if the callback |base| represents is canceled. 1035 template <typename BindStateType> 1036 bool QueryCancellationTraits(const BindStateBase* base, 1037 BindStateBase::CancellationQueryMode mode) { 1038 const BindStateType* storage = static_cast<const BindStateType*>(base); 1039 static constexpr size_t num_bound_args = 1040 std::tuple_size_v<decltype(storage->bound_args_)>; 1041 return QueryCancellationTraitsImpl( 1042 mode, storage->functor_, storage->bound_args_, 1043 std::make_index_sequence<num_bound_args>()); 1044 } 1045 1046 // The base case of BanUnconstructedRefCountedReceiver that checks nothing. 1047 template <typename Functor, typename Receiver, typename... Unused> 1048 std::enable_if_t< 1049 !(MakeFunctorTraits<Functor>::is_method && 1050 IsPointerV<std::decay_t<Receiver>> && 1051 IsRefCountedType<RemovePointerT<std::decay_t<Receiver>>>::value)> 1052 BanUnconstructedRefCountedReceiver(const Receiver& receiver, Unused&&...) {} 1053 1054 template <typename Functor> 1055 void BanUnconstructedRefCountedReceiver() {} 1056 1057 // Asserts that Callback is not the first owner of a ref-counted receiver. 1058 template <typename Functor, typename Receiver, typename... Unused> 1059 std::enable_if_t< 1060 MakeFunctorTraits<Functor>::is_method && 1061 IsPointerV<std::decay_t<Receiver>> && 1062 IsRefCountedType<RemovePointerT<std::decay_t<Receiver>>>::value> 1063 BanUnconstructedRefCountedReceiver(const Receiver& receiver, Unused&&...) { 1064 DCHECK(receiver); 1065 1066 // It's error prone to make the implicit first reference to ref-counted types. 1067 // In the example below, base::BindOnce() would make the implicit first 1068 // reference to the ref-counted Foo. If PostTask() failed or the posted task 1069 // ran fast enough, the newly created instance could be destroyed before `oo` 1070 // makes another reference. 1071 // Foo::Foo() { 1072 // base::ThreadPool::PostTask(FROM_HERE, base::BindOnce(&Foo::Bar, this)); 1073 // } 1074 // 1075 // scoped_refptr<Foo> oo = new Foo(); 1076 // 1077 // Hence, base::Bind{Once,Repeating}() refuses to create the first reference 1078 // to ref-counted objects, and DCHECK()s otherwise. As above, that typically 1079 // happens around PostTask() in their constructor, and such objects can be 1080 // destroyed before `new` returns if the task resolves fast enough. 1081 // 1082 // Instead of doing the above, please consider adding a static constructor, 1083 // and keep the first reference alive explicitly. 1084 // // static 1085 // scoped_refptr<Foo> Foo::Create() { 1086 // auto foo = base::WrapRefCounted(new Foo()); 1087 // base::ThreadPool::PostTask(FROM_HERE, base::BindOnce(&Foo::Bar, foo)); 1088 // return foo; 1089 // } 1090 // 1091 // Foo::Foo() {} 1092 // 1093 // scoped_refptr<Foo> oo = Foo::Create(); 1094 DCHECK(receiver->HasAtLeastOneRef()); 1095 } 1096 1097 // BindState<> 1098 // 1099 // This stores all the state passed into Bind(). 1100 template <typename Functor, typename... BoundArgs> 1101 struct BindState final : BindStateBase { 1102 using IsCancellable = std::bool_constant< 1103 CallbackCancellationTraits<Functor, 1104 std::tuple<BoundArgs...>>::is_cancellable>; 1105 template <typename ForwardFunctor, typename... ForwardBoundArgs> 1106 static BindState* Create(BindStateBase::InvokeFuncStorage invoke_func, 1107 ForwardFunctor&& functor, 1108 ForwardBoundArgs&&... bound_args) { 1109 // Ban ref counted receivers that were not yet fully constructed to avoid 1110 // a common pattern of racy situation. 1111 BanUnconstructedRefCountedReceiver<ForwardFunctor>(bound_args...); 1112 1113 // IsCancellable is std::false_type if 1114 // CallbackCancellationTraits<>::IsCancelled returns always false. 1115 // Otherwise, it's std::true_type. 1116 return new BindState(IsCancellable{}, invoke_func, 1117 std::forward<ForwardFunctor>(functor), 1118 std::forward<ForwardBoundArgs>(bound_args)...); 1119 } 1120 1121 Functor functor_; 1122 std::tuple<BoundArgs...> bound_args_; 1123 1124 private: 1125 static constexpr bool is_nested_callback = 1126 MakeFunctorTraits<Functor>::is_callback; 1127 1128 template <typename ForwardFunctor, typename... ForwardBoundArgs> 1129 explicit BindState(std::true_type, 1130 BindStateBase::InvokeFuncStorage invoke_func, 1131 ForwardFunctor&& functor, 1132 ForwardBoundArgs&&... bound_args) 1133 : BindStateBase(invoke_func, 1134 &Destroy, 1135 &QueryCancellationTraits<BindState>), 1136 functor_(std::forward<ForwardFunctor>(functor)), 1137 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) { 1138 // We check the validity of nested callbacks (e.g., Bind(callback, ...)) in 1139 // release builds to avoid null pointers from ending up in posted tasks, 1140 // causing hard-to-diagnose crashes. Ideally we'd do this for all functors 1141 // here, but that would have a large binary size impact. 1142 if (is_nested_callback) { 1143 CHECK(!IsNull(functor_)); 1144 } else { 1145 DCHECK(!IsNull(functor_)); 1146 } 1147 } 1148 1149 template <typename ForwardFunctor, typename... ForwardBoundArgs> 1150 explicit BindState(std::false_type, 1151 BindStateBase::InvokeFuncStorage invoke_func, 1152 ForwardFunctor&& functor, 1153 ForwardBoundArgs&&... bound_args) 1154 : BindStateBase(invoke_func, &Destroy), 1155 functor_(std::forward<ForwardFunctor>(functor)), 1156 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) { 1157 // See above for CHECK/DCHECK rationale. 1158 if (is_nested_callback) { 1159 CHECK(!IsNull(functor_)); 1160 } else { 1161 DCHECK(!IsNull(functor_)); 1162 } 1163 } 1164 1165 ~BindState() = default; 1166 1167 static void Destroy(const BindStateBase* self) { 1168 delete static_cast<const BindState*>(self); 1169 } 1170 }; 1171 1172 // Used to implement MakeBindStateType. 1173 template <bool is_method, typename Functor, typename... BoundArgs> 1174 struct MakeBindStateTypeImpl; 1175 1176 template <typename Functor, typename... BoundArgs> 1177 struct MakeBindStateTypeImpl<false, Functor, BoundArgs...> { 1178 static_assert(!HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>::value, 1179 "A parameter is a refcounted type and needs scoped_refptr."); 1180 using Type = BindState<std::decay_t<Functor>, MakeStorageType<BoundArgs>...>; 1181 }; 1182 1183 template <typename Functor> 1184 struct MakeBindStateTypeImpl<true, Functor> { 1185 using Type = BindState<std::decay_t<Functor>>; 1186 }; 1187 1188 template <typename Functor, typename Receiver, typename... BoundArgs> 1189 struct MakeBindStateTypeImpl<true, Functor, Receiver, BoundArgs...> { 1190 private: 1191 using DecayedReceiver = std::decay_t<Receiver>; 1192 static_assert(!std::is_array_v<std::remove_reference_t<Receiver>>, 1193 "First bound argument to a method cannot be an array."); 1194 static_assert( 1195 !IsRawRefV<DecayedReceiver>, 1196 "Receivers may not be raw_ref<T>. If using a raw_ref<T> here is safe" 1197 " and has no lifetime concerns, use base::Unretained() and document why" 1198 " it's safe."); 1199 static_assert( 1200 !IsPointerV<DecayedReceiver> || 1201 IsRefCountedType<RemovePointerT<DecayedReceiver>>::value, 1202 "Receivers may not be raw pointers. If using a raw pointer here is safe" 1203 " and has no lifetime concerns, use base::Unretained() and document why" 1204 " it's safe."); 1205 1206 static_assert(!HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>::value, 1207 "A parameter is a refcounted type and needs scoped_refptr."); 1208 1209 using ReceiverStorageType = 1210 typename MethodReceiverStorageType<DecayedReceiver>::Type; 1211 1212 public: 1213 using Type = BindState<std::decay_t<Functor>, 1214 ReceiverStorageType, 1215 MakeStorageType<BoundArgs>...>; 1216 }; 1217 1218 template <typename Functor, typename... BoundArgs> 1219 using MakeBindStateType = 1220 typename MakeBindStateTypeImpl<MakeFunctorTraits<Functor>::is_method, 1221 Functor, 1222 BoundArgs...>::Type; 1223 1224 // Returns a RunType of bound functor. 1225 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C). 1226 template <typename Functor, typename... BoundArgs> 1227 using MakeUnboundRunType = 1228 typename BindTypeHelper<Functor, BoundArgs...>::UnboundRunType; 1229 1230 // The implementation of TransformToUnwrappedType below. 1231 template <bool is_once, typename T> 1232 struct TransformToUnwrappedTypeImpl; 1233 1234 template <typename T> 1235 struct TransformToUnwrappedTypeImpl<true, T> { 1236 using StoredType = std::decay_t<T>; 1237 using ForwardType = StoredType&&; 1238 using Unwrapped = decltype(Unwrap(std::declval<ForwardType>())); 1239 }; 1240 1241 template <typename T> 1242 struct TransformToUnwrappedTypeImpl<false, T> { 1243 using StoredType = std::decay_t<T>; 1244 using ForwardType = const StoredType&; 1245 using Unwrapped = decltype(Unwrap(std::declval<ForwardType>())); 1246 }; 1247 1248 // Transform |T| into `Unwrapped` type, which is passed to the target function. 1249 // Example: 1250 // In is_once == true case, 1251 // `int&&` -> `int&&`, 1252 // `const int&` -> `int&&`, 1253 // `OwnedWrapper<int>&` -> `int*&&`. 1254 // In is_once == false case, 1255 // `int&&` -> `const int&`, 1256 // `const int&` -> `const int&`, 1257 // `OwnedWrapper<int>&` -> `int* const &`. 1258 template <bool is_once, typename T> 1259 using TransformToUnwrappedType = 1260 typename TransformToUnwrappedTypeImpl<is_once, T>::Unwrapped; 1261 1262 // Transforms |Args| into `Unwrapped` types, and packs them into a TypeList. 1263 // If |is_method| is true, tries to dereference the first argument to support 1264 // smart pointers. 1265 template <bool is_once, bool is_method, typename... Args> 1266 struct MakeUnwrappedTypeListImpl { 1267 using Type = TypeList<TransformToUnwrappedType<is_once, Args>...>; 1268 }; 1269 1270 // Performs special handling for this pointers. 1271 // Example: 1272 // int* -> int*, 1273 // std::unique_ptr<int> -> int*. 1274 template <bool is_once, typename Receiver, typename... Args> 1275 struct MakeUnwrappedTypeListImpl<is_once, true, Receiver, Args...> { 1276 using ReceiverStorageType = 1277 typename MethodReceiverStorageType<std::decay_t<Receiver>>::Type; 1278 using UnwrappedReceiver = 1279 TransformToUnwrappedType<is_once, ReceiverStorageType>; 1280 using Type = TypeList<decltype(&*std::declval<UnwrappedReceiver>()), 1281 TransformToUnwrappedType<is_once, Args>...>; 1282 }; 1283 1284 template <bool is_once, bool is_method, typename... Args> 1285 using MakeUnwrappedTypeList = 1286 typename MakeUnwrappedTypeListImpl<is_once, is_method, Args...>::Type; 1287 1288 // IsOnceCallback<T> is a std::true_type if |T| is a OnceCallback. 1289 template <typename T> 1290 struct IsOnceCallback : std::false_type {}; 1291 1292 template <typename Signature> 1293 struct IsOnceCallback<OnceCallback<Signature>> : std::true_type {}; 1294 1295 // IsUnretainedMayDangle is true if StorageType is of type 1296 // `UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraits>. 1297 // Note that it is false for unretained_traits::MayDangleUntriaged. 1298 template <typename StorageType> 1299 inline constexpr bool IsUnretainedMayDangle = false; 1300 template <typename T, RawPtrTraits PtrTraits> 1301 inline constexpr bool IsUnretainedMayDangle< 1302 UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraits>> = true; 1303 1304 // UnretainedAndRawPtrHaveCompatibleTraits is true if StorageType is of type 1305 // `UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraits1>` and 1306 // FunctionParamType is of type `raw_ptr<T, PtrTraits2>`, and the former's 1307 // ::GetPtrType is the same type as the latter. 1308 template <typename StorageType, typename FunctionParamType> 1309 inline constexpr bool UnretainedAndRawPtrHaveCompatibleTraits = false; 1310 template <typename T, 1311 RawPtrTraits PtrTraitsInUnretained, 1312 RawPtrTraits PtrTraitsInReceiver> 1313 inline constexpr bool UnretainedAndRawPtrHaveCompatibleTraits< 1314 UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraitsInUnretained>, 1315 raw_ptr<T, PtrTraitsInReceiver>> = 1316 std::is_same_v< 1317 typename UnretainedWrapper<T, 1318 unretained_traits::MayDangle, 1319 PtrTraitsInUnretained>::GetPtrType, 1320 raw_ptr<T, PtrTraitsInReceiver>>; 1321 1322 // Helpers to make error messages slightly more readable. 1323 template <int i> 1324 struct BindArgument { 1325 template <typename ForwardingType> 1326 struct ForwardedAs { 1327 template <typename FunctorParamType> 1328 struct ToParamWithType { 1329 static constexpr bool kNotARawPtr = !IsRawPtrV<FunctorParamType>; 1330 1331 static constexpr bool kCanBeForwardedToBoundFunctor = 1332 std::is_convertible_v<ForwardingType, FunctorParamType>; 1333 1334 // If the bound type can't be forwarded then test if `FunctorParamType` is 1335 // a non-const lvalue reference and a reference to the unwrapped type 1336 // *could* have been successfully forwarded. 1337 static constexpr bool kNonConstRefParamMustBeWrapped = 1338 kCanBeForwardedToBoundFunctor || 1339 !(std::is_lvalue_reference_v<FunctorParamType> && 1340 !std::is_const_v<std::remove_reference_t<FunctorParamType>> && 1341 std::is_convertible_v<std::decay_t<ForwardingType>&, 1342 FunctorParamType>); 1343 1344 // Note that this intentionally drops the const qualifier from 1345 // `ForwardingType`, to test if it *could* have been successfully 1346 // forwarded if `Passed()` had been used. 1347 static constexpr bool kMoveOnlyTypeMustUseBasePassed = 1348 kCanBeForwardedToBoundFunctor || 1349 !std::is_convertible_v<std::decay_t<ForwardingType>&&, 1350 FunctorParamType>; 1351 }; 1352 }; 1353 1354 template <typename BoundAsType> 1355 struct BoundAs { 1356 template <typename StorageType> 1357 struct StoredAs { 1358 static constexpr bool kBindArgumentCanBeCaptured = 1359 std::is_constructible_v<StorageType, BoundAsType>; 1360 // Note that this intentionally drops the const qualifier from 1361 // `BoundAsType`, to test if it *could* have been successfully bound if 1362 // `std::move()` had been used. 1363 static constexpr bool kMoveOnlyTypeMustUseStdMove = 1364 kBindArgumentCanBeCaptured || 1365 !std::is_constructible_v<StorageType, std::decay_t<BoundAsType>&&>; 1366 }; 1367 }; 1368 1369 template <typename FunctionParamType> 1370 struct ToParamWithType { 1371 template <typename StorageType> 1372 struct StoredAs { 1373 template <bool is_method> 1374 // true if we are handling `this` parameter. 1375 static constexpr bool kParamIsThisPointer = is_method && i == 0; 1376 // true if the current parameter is of type `raw_ptr<T>` with 1377 // `RawPtrTraits::kMayDangle` trait (e.g. `MayBeDangling<T>`). 1378 static constexpr bool kParamIsDanglingRawPtr = 1379 IsRawPtrMayDangleV<FunctionParamType>; 1380 // true if the bound parameter is of type 1381 // `UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraits>`. 1382 static constexpr bool kBoundPtrMayDangle = 1383 IsUnretainedMayDangle<StorageType>; 1384 // true if bound parameter of type `UnretainedWrapper` and parameter of 1385 // type `raw_ptr` have compatible `RawPtrTraits`. 1386 static constexpr bool kMayBeDanglingTraitsCorrectness = 1387 UnretainedAndRawPtrHaveCompatibleTraits<StorageType, 1388 FunctionParamType>; 1389 // true if the receiver argument **must** be of type `MayBeDangling<T>`. 1390 static constexpr bool kMayBeDanglingMustBeUsed = 1391 kBoundPtrMayDangle && kParamIsDanglingRawPtr; 1392 1393 // true iff: 1394 // - bound parameter is of type 1395 // `UnretainedWrapper<T, unretained_traits::MayDangle, PtrTraits>` 1396 // - the receiving argument is of type `MayBeDangling<T>` 1397 template <bool is_method> 1398 static constexpr bool kMayBeDanglingPtrPassedCorrectly = 1399 kParamIsThisPointer<is_method> || 1400 kBoundPtrMayDangle == kParamIsDanglingRawPtr; 1401 1402 // true if: 1403 // - MayBeDangling<T> must not be used as receiver parameter. 1404 // OR 1405 // - MayBeDangling<T> must be used as receiver parameter and its traits 1406 // are matching Unretained traits. 1407 static constexpr bool kUnsafeDanglingAndMayBeDanglingHaveMatchingTraits = 1408 !kMayBeDanglingMustBeUsed || kMayBeDanglingTraitsCorrectness; 1409 }; 1410 }; 1411 }; 1412 1413 // Helper to assert that parameter |i| of type |Arg| can be bound, which means: 1414 // - |Arg| can be retained internally as |Storage|. 1415 // - |Arg| can be forwarded as |Unwrapped| to |Param|. 1416 template <int i, 1417 bool is_method, 1418 typename Arg, 1419 typename Storage, 1420 typename Unwrapped, 1421 typename Param> 1422 struct AssertConstructible { 1423 private: 1424 // We forbid callbacks to use raw_ptr as a parameter. However, we allow 1425 // MayBeDangling<T> iff the callback argument was created using 1426 // `base::UnsafeDangling`. 1427 static_assert( 1428 BindArgument<i>::template ForwardedAs< 1429 Unwrapped>::template ToParamWithType<Param>::kNotARawPtr || 1430 BindArgument<i>::template ToParamWithType<Param>::template StoredAs< 1431 Storage>::kMayBeDanglingMustBeUsed, 1432 "base::Bind() target functor has a parameter of type raw_ptr<T>. " 1433 "raw_ptr<T> should not be used for function parameters, please use T* or " 1434 "T& instead."); 1435 1436 // A bound functor must take a dangling pointer argument (e.g. bound using the 1437 // UnsafeDangling helper) as a MayBeDangling<T>, to make it clear that the 1438 // pointee's lifetime must be externally validated before using it. For 1439 // methods, exempt a bound receiver (i.e. the this pointer) as it is not 1440 // passed as a regular function argument. 1441 static_assert( 1442 BindArgument<i>::template ToParamWithType<Param>::template StoredAs< 1443 Storage>::template kMayBeDanglingPtrPassedCorrectly<is_method>, 1444 "base::UnsafeDangling() pointers must be received by functors with " 1445 "MayBeDangling<T> as parameter."); 1446 1447 static_assert( 1448 BindArgument<i>::template ToParamWithType<Param>::template StoredAs< 1449 Storage>::kUnsafeDanglingAndMayBeDanglingHaveMatchingTraits, 1450 "MayBeDangling<T> parameter must receive the same RawPtrTraits as the " 1451 "one passed to the corresponding base::UnsafeDangling() call."); 1452 1453 // With `BindRepeating`, there are two decision points for how to handle a 1454 // move-only type: 1455 // 1456 // 1. Whether the move-only argument should be moved into the internal 1457 // `BindState`. Either `std::move()` or `Passed` is sufficient to trigger 1458 // move-only semantics. 1459 // 2. Whether or not the bound, move-only argument should be moved to the 1460 // bound functor when invoked. When the argument is bound with `Passed`, 1461 // invoking the callback will destructively move the bound, move-only 1462 // argument to the bound functor. In contrast, if the argument is bound 1463 // with `std::move()`, `RepeatingCallback` will attempt to call the bound 1464 // functor with a constant reference to the bound, move-only argument. This 1465 // will fail if the bound functor accepts that argument by value, since the 1466 // argument cannot be copied. It is this latter case that this 1467 // static_assert aims to catch. 1468 // 1469 // In contrast, `BindOnce()` only has one decision point. Once a move-only 1470 // type is captured by value into the internal `BindState`, the bound, 1471 // move-only argument will always be moved to the functor when invoked. 1472 // Failure to use std::move will simply fail the `kMoveOnlyTypeMustUseStdMove` 1473 // assert below instead. 1474 // 1475 // Note: `Passed()` is a legacy of supporting move-only types when repeating 1476 // callbacks were the only callback type. A `RepeatingCallback` with a 1477 // `Passed()` argument is really a `OnceCallback` and should eventually be 1478 // migrated. 1479 static_assert( 1480 BindArgument<i>::template ForwardedAs<Unwrapped>:: 1481 template ToParamWithType<Param>::kMoveOnlyTypeMustUseBasePassed, 1482 "base::BindRepeating() argument is a move-only type. Use base::Passed() " 1483 "instead of std::move() to transfer ownership from the callback to the " 1484 "bound functor."); 1485 static_assert( 1486 BindArgument<i>::template ForwardedAs<Unwrapped>:: 1487 template ToParamWithType<Param>::kNonConstRefParamMustBeWrapped, 1488 "Bound argument for non-const reference parameter must be wrapped in " 1489 "std::ref() or base::OwnedRef()."); 1490 static_assert( 1491 BindArgument<i>::template ForwardedAs<Unwrapped>:: 1492 template ToParamWithType<Param>::kCanBeForwardedToBoundFunctor, 1493 "Type mismatch between bound argument and bound functor's parameter."); 1494 1495 static_assert(BindArgument<i>::template BoundAs<Arg>::template StoredAs< 1496 Storage>::kMoveOnlyTypeMustUseStdMove, 1497 "Attempting to bind a move-only type. Use std::move() to " 1498 "transfer ownership to the created callback."); 1499 // In practice, this static_assert should be quite rare as the storage type 1500 // is deduced from the arguments passed to `BindOnce()`/`BindRepeating()`. 1501 static_assert( 1502 BindArgument<i>::template BoundAs<Arg>::template StoredAs< 1503 Storage>::kBindArgumentCanBeCaptured, 1504 "Cannot capture argument: is the argument copyable or movable?"); 1505 }; 1506 1507 // Takes three same-length TypeLists, and applies AssertConstructible for each 1508 // triples. 1509 template <bool is_method, 1510 typename Index, 1511 typename Args, 1512 typename UnwrappedTypeList, 1513 typename ParamsList> 1514 struct AssertBindArgsValidity; 1515 1516 template <bool is_method, 1517 size_t... Ns, 1518 typename... Args, 1519 typename... Unwrapped, 1520 typename... Params> 1521 struct AssertBindArgsValidity<is_method, 1522 std::index_sequence<Ns...>, 1523 TypeList<Args...>, 1524 TypeList<Unwrapped...>, 1525 TypeList<Params...>> 1526 : AssertConstructible<Ns, 1527 is_method, 1528 Args, 1529 std::decay_t<Args>, 1530 Unwrapped, 1531 Params>... { 1532 static constexpr bool ok = true; 1533 }; 1534 1535 template <typename T> 1536 struct AssertBindArgIsNotBasePassed : public std::true_type {}; 1537 1538 template <typename T> 1539 struct AssertBindArgIsNotBasePassed<PassedWrapper<T>> : public std::false_type { 1540 }; 1541 1542 template <template <typename> class CallbackT, 1543 typename Functor, 1544 typename... Args> 1545 decltype(auto) BindImpl(Functor&& functor, Args&&... args) { 1546 // This block checks if each |args| matches to the corresponding params of the 1547 // target function. This check does not affect the behavior of Bind, but its 1548 // error message should be more readable. 1549 static constexpr bool kIsOnce = IsOnceCallback<CallbackT<void()>>::value; 1550 using Helper = BindTypeHelper<Functor, Args...>; 1551 using FunctorTraits = typename Helper::FunctorTraits; 1552 using BoundArgsList = typename Helper::BoundArgsList; 1553 using UnwrappedArgsList = 1554 MakeUnwrappedTypeList<kIsOnce, FunctorTraits::is_method, Args&&...>; 1555 using BoundParamsList = typename Helper::BoundParamsList; 1556 static_assert( 1557 MakeFunctorTraits<Functor>::is_stateless, 1558 "Capturing lambdas and stateful lambdas are intentionally not supported. " 1559 "Please use base::Bind{Once,Repeating} directly to bind arguments."); 1560 static_assert( 1561 AssertBindArgsValidity<FunctorTraits::is_method, 1562 std::make_index_sequence<Helper::num_bounds>, 1563 BoundArgsList, UnwrappedArgsList, 1564 BoundParamsList>::ok, 1565 "The bound args need to be convertible to the target params."); 1566 1567 using BindState = MakeBindStateType<Functor, Args...>; 1568 using UnboundRunType = MakeUnboundRunType<Functor, Args...>; 1569 using Invoker = Invoker<BindState, UnboundRunType>; 1570 using CallbackType = CallbackT<UnboundRunType>; 1571 1572 // Store the invoke func into PolymorphicInvoke before casting it to 1573 // InvokeFuncStorage, so that we can ensure its type matches to 1574 // PolymorphicInvoke, to which CallbackType will cast back. 1575 using PolymorphicInvoke = typename CallbackType::PolymorphicInvoke; 1576 PolymorphicInvoke invoke_func; 1577 if constexpr (kIsOnce) { 1578 invoke_func = Invoker::RunOnce; 1579 } else { 1580 invoke_func = Invoker::Run; 1581 } 1582 1583 using InvokeFuncStorage = BindStateBase::InvokeFuncStorage; 1584 return CallbackType(BindState::Create( 1585 reinterpret_cast<InvokeFuncStorage>(invoke_func), 1586 std::forward<Functor>(functor), std::forward<Args>(args)...)); 1587 } 1588 1589 // Special cases for binding to a base::{Once, Repeating}Callback without extra 1590 // bound arguments. We CHECK() the validity of callback to guard against null 1591 // pointers accidentally ending up in posted tasks, causing hard-to-debug 1592 // crashes. 1593 template <template <typename> class CallbackT, 1594 typename Signature, 1595 std::enable_if_t<std::is_same_v<CallbackT<Signature>, 1596 OnceCallback<Signature>>>* = nullptr> 1597 OnceCallback<Signature> BindImpl(OnceCallback<Signature> callback) { 1598 CHECK(callback); 1599 return callback; 1600 } 1601 1602 template <template <typename> class CallbackT, 1603 typename Signature, 1604 std::enable_if_t<std::is_same_v<CallbackT<Signature>, 1605 OnceCallback<Signature>>>* = nullptr> 1606 OnceCallback<Signature> BindImpl(RepeatingCallback<Signature> callback) { 1607 CHECK(callback); 1608 return callback; 1609 } 1610 1611 template <template <typename> class CallbackT, 1612 typename Signature, 1613 std::enable_if_t<std::is_same_v<CallbackT<Signature>, 1614 RepeatingCallback<Signature>>>* = 1615 nullptr> 1616 RepeatingCallback<Signature> BindImpl(RepeatingCallback<Signature> callback) { 1617 CHECK(callback); 1618 return callback; 1619 } 1620 1621 template <template <typename> class CallbackT, typename Signature> 1622 auto BindImpl(absl::FunctionRef<Signature>, ...) { 1623 static_assert( 1624 AlwaysFalse<Signature>, 1625 "base::Bind{Once,Repeating} require strong ownership: non-owning " 1626 "function references may not bound as the functor due to potential " 1627 "lifetime issues."); 1628 return nullptr; 1629 } 1630 1631 template <template <typename> class CallbackT, typename Signature> 1632 auto BindImpl(FunctionRef<Signature>, ...) { 1633 static_assert( 1634 AlwaysFalse<Signature>, 1635 "base::Bind{Once,Repeating} require strong ownership: non-owning " 1636 "function references may not bound as the functor due to potential " 1637 "lifetime issues."); 1638 return nullptr; 1639 } 1640 1641 } // namespace internal 1642 1643 // An injection point to control |this| pointer behavior on a method invocation. 1644 // If IsWeakReceiver<> is true_type for |T| and |T| is used for a receiver of a 1645 // method, base::Bind cancels the method invocation if the receiver is tested as 1646 // false. 1647 // E.g. Foo::bar() is not called: 1648 // struct Foo : base::SupportsWeakPtr<Foo> { 1649 // void bar() {} 1650 // }; 1651 // 1652 // WeakPtr<Foo> oo = nullptr; 1653 // base::BindOnce(&Foo::bar, oo).Run(); 1654 template <typename T> 1655 struct IsWeakReceiver : std::false_type {}; 1656 1657 template <typename T> 1658 struct IsWeakReceiver<std::reference_wrapper<T>> : IsWeakReceiver<T> {}; 1659 1660 template <typename T> 1661 struct IsWeakReceiver<WeakPtr<T>> : std::true_type {}; 1662 1663 // An injection point to control how objects are checked for maybe validity, 1664 // which is an optimistic thread-safe check for full validity. 1665 template <typename> 1666 struct MaybeValidTraits { 1667 template <typename T> 1668 static bool MaybeValid(const T& o) { 1669 return o.MaybeValid(); 1670 } 1671 }; 1672 1673 // An injection point to control how bound objects passed to the target 1674 // function. BindUnwrapTraits<>::Unwrap() is called for each bound objects right 1675 // before the target function is invoked. 1676 template <typename> 1677 struct BindUnwrapTraits { 1678 template <typename T> 1679 static T&& Unwrap(T&& o) { 1680 return std::forward<T>(o); 1681 } 1682 }; 1683 1684 template <typename T, typename UnretainedTrait, RawPtrTraits PtrTraits> 1685 struct BindUnwrapTraits< 1686 internal::UnretainedWrapper<T, UnretainedTrait, PtrTraits>> { 1687 static auto Unwrap( 1688 const internal::UnretainedWrapper<T, UnretainedTrait, PtrTraits>& o) { 1689 return o.get(); 1690 } 1691 }; 1692 1693 template <typename T, typename UnretainedTrait, RawPtrTraits PtrTraits> 1694 struct BindUnwrapTraits< 1695 internal::UnretainedRefWrapper<T, UnretainedTrait, PtrTraits>> { 1696 static T& Unwrap( 1697 const internal::UnretainedRefWrapper<T, UnretainedTrait, PtrTraits>& o) { 1698 return o.get(); 1699 } 1700 }; 1701 1702 template <typename T> 1703 struct BindUnwrapTraits<internal::RetainedRefWrapper<T>> { 1704 static T* Unwrap(const internal::RetainedRefWrapper<T>& o) { return o.get(); } 1705 }; 1706 1707 template <typename T, typename Deleter> 1708 struct BindUnwrapTraits<internal::OwnedWrapper<T, Deleter>> { 1709 static T* Unwrap(const internal::OwnedWrapper<T, Deleter>& o) { 1710 return o.get(); 1711 } 1712 }; 1713 1714 template <typename T> 1715 struct BindUnwrapTraits<internal::OwnedRefWrapper<T>> { 1716 static T& Unwrap(const internal::OwnedRefWrapper<T>& o) { return o.get(); } 1717 }; 1718 1719 template <typename T> 1720 struct BindUnwrapTraits<internal::PassedWrapper<T>> { 1721 static T Unwrap(const internal::PassedWrapper<T>& o) { return o.Take(); } 1722 }; 1723 1724 #if BUILDFLAG(IS_WIN) 1725 template <typename T> 1726 struct BindUnwrapTraits<Microsoft::WRL::ComPtr<T>> { 1727 static T* Unwrap(const Microsoft::WRL::ComPtr<T>& ptr) { return ptr.Get(); } 1728 }; 1729 #endif 1730 1731 // CallbackCancellationTraits allows customization of Callback's cancellation 1732 // semantics. By default, callbacks are not cancellable. A specialization should 1733 // set is_cancellable = true and implement an IsCancelled() that returns if the 1734 // callback should be cancelled. 1735 template <typename Functor, typename BoundArgsTuple, typename SFINAE> 1736 struct CallbackCancellationTraits { 1737 static constexpr bool is_cancellable = false; 1738 }; 1739 1740 // Specialization for method bound to weak pointer receiver. 1741 template <typename Functor, typename... BoundArgs> 1742 struct CallbackCancellationTraits< 1743 Functor, 1744 std::tuple<BoundArgs...>, 1745 std::enable_if_t< 1746 internal::IsWeakMethod<internal::FunctorTraits<Functor>::is_method, 1747 BoundArgs...>::value>> { 1748 static constexpr bool is_cancellable = true; 1749 1750 template <typename Receiver, typename... Args> 1751 static bool IsCancelled(const Functor&, 1752 const Receiver& receiver, 1753 const Args&...) { 1754 return !receiver; 1755 } 1756 1757 template <typename Receiver, typename... Args> 1758 static bool MaybeValid(const Functor&, 1759 const Receiver& receiver, 1760 const Args&...) { 1761 return MaybeValidTraits<Receiver>::MaybeValid(receiver); 1762 } 1763 }; 1764 1765 // Specialization for a nested bind. 1766 template <typename Signature, typename... BoundArgs> 1767 struct CallbackCancellationTraits<OnceCallback<Signature>, 1768 std::tuple<BoundArgs...>> { 1769 static constexpr bool is_cancellable = true; 1770 1771 template <typename Functor> 1772 static bool IsCancelled(const Functor& functor, const BoundArgs&...) { 1773 return functor.IsCancelled(); 1774 } 1775 1776 template <typename Functor> 1777 static bool MaybeValid(const Functor& functor, const BoundArgs&...) { 1778 return MaybeValidTraits<Functor>::MaybeValid(functor); 1779 } 1780 }; 1781 1782 template <typename Signature, typename... BoundArgs> 1783 struct CallbackCancellationTraits<RepeatingCallback<Signature>, 1784 std::tuple<BoundArgs...>> { 1785 static constexpr bool is_cancellable = true; 1786 1787 template <typename Functor> 1788 static bool IsCancelled(const Functor& functor, const BoundArgs&...) { 1789 return functor.IsCancelled(); 1790 } 1791 1792 template <typename Functor> 1793 static bool MaybeValid(const Functor& functor, const BoundArgs&...) { 1794 return MaybeValidTraits<Functor>::MaybeValid(functor); 1795 } 1796 }; 1797 1798 } // namespace base 1799 1800 #endif // BASE_FUNCTIONAL_BIND_INTERNAL_H_