1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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_BIND_INTERNAL_H_ 6 #define BASE_BIND_INTERNAL_H_ 7 8 #include <stddef.h> 9 10 #include <type_traits> 11 #include <utility> 12 13 #include "base/callback_internal.h" 14 #include "base/compiler_specific.h" 15 #include "base/memory/raw_scoped_refptr_mismatch_checker.h" 16 #include "base/memory/weak_ptr.h" 17 #include "base/template_util.h" 18 #include "build/build_config.h" 19 20 #if defined(OS_MACOSX) && !HAS_FEATURE(objc_arc) 21 #include "base/mac/scoped_block.h" 22 #endif 23 24 // See base/callback.h for user documentation. 25 // 26 // 27 // CONCEPTS: 28 // Functor -- A movable type representing something that should be called. 29 // All function pointers and Callback<> are functors even if the 30 // invocation syntax differs. 31 // RunType -- A function type (as opposed to function _pointer_ type) for 32 // a Callback<>::Run(). Usually just a convenience typedef. 33 // (Bound)Args -- A set of types that stores the arguments. 34 // 35 // Types: 36 // ForceVoidReturn<> -- Helper class for translating function signatures to 37 // equivalent forms with a "void" return type. 38 // FunctorTraits<> -- Type traits used to determine the correct RunType and 39 // invocation manner for a Functor. This is where function 40 // signature adapters are applied. 41 // InvokeHelper<> -- Take a Functor + arguments and actully invokes it. 42 // Handle the differing syntaxes needed for WeakPtr<> 43 // support. This is separate from Invoker to avoid creating 44 // multiple version of Invoker<>. 45 // Invoker<> -- Unwraps the curried parameters and executes the Functor. 46 // BindState<> -- Stores the curried parameters, and is the main entry point 47 // into the Bind() system. 48 49 namespace base { 50 51 template <typename T> 52 struct IsWeakReceiver; 53 54 template <typename> 55 struct BindUnwrapTraits; 56 57 template <typename Functor, typename BoundArgsTuple, typename SFINAE = void> 58 struct CallbackCancellationTraits; 59 60 namespace internal { 61 62 template <typename Functor, typename SFINAE = void> 63 struct FunctorTraits; 64 65 template <typename T> 66 class UnretainedWrapper { 67 public: 68 explicit UnretainedWrapper(T* o) : ptr_(o) {} 69 T* get() const { return ptr_; } 70 71 private: 72 T* ptr_; 73 }; 74 75 template <typename T> 76 class ConstRefWrapper { 77 public: 78 explicit ConstRefWrapper(const T& o) : ptr_(&o) {} 79 const T& get() const { return *ptr_; } 80 81 private: 82 const T* ptr_; 83 }; 84 85 template <typename T> 86 class RetainedRefWrapper { 87 public: 88 explicit RetainedRefWrapper(T* o) : ptr_(o) {} 89 explicit RetainedRefWrapper(scoped_refptr<T> o) : ptr_(std::move(o)) {} 90 T* get() const { return ptr_.get(); } 91 92 private: 93 scoped_refptr<T> ptr_; 94 }; 95 96 template <typename T> 97 struct IgnoreResultHelper { 98 explicit IgnoreResultHelper(T functor) : functor_(std::move(functor)) {} 99 explicit operator bool() const { return !!functor_; } 100 101 T functor_; 102 }; 103 104 // An alternate implementation is to avoid the destructive copy, and instead 105 // specialize ParamTraits<> for OwnedWrapper<> to change the StorageType to 106 // a class that is essentially a std::unique_ptr<>. 107 // 108 // The current implementation has the benefit though of leaving ParamTraits<> 109 // fully in callback_internal.h as well as avoiding type conversions during 110 // storage. 111 template <typename T> 112 class OwnedWrapper { 113 public: 114 explicit OwnedWrapper(T* o) : ptr_(o) {} 115 ~OwnedWrapper() { delete ptr_; } 116 T* get() const { return ptr_; } 117 OwnedWrapper(OwnedWrapper&& other) { 118 ptr_ = other.ptr_; 119 other.ptr_ = NULL; 120 } 121 122 private: 123 mutable T* ptr_; 124 }; 125 126 // PassedWrapper is a copyable adapter for a scoper that ignores const. 127 // 128 // It is needed to get around the fact that Bind() takes a const reference to 129 // all its arguments. Because Bind() takes a const reference to avoid 130 // unnecessary copies, it is incompatible with movable-but-not-copyable 131 // types; doing a destructive "move" of the type into Bind() would violate 132 // the const correctness. 133 // 134 // This conundrum cannot be solved without either C++11 rvalue references or 135 // a O(2^n) blowup of Bind() templates to handle each combination of regular 136 // types and movable-but-not-copyable types. Thus we introduce a wrapper type 137 // that is copyable to transmit the correct type information down into 138 // BindState<>. Ignoring const in this type makes sense because it is only 139 // created when we are explicitly trying to do a destructive move. 140 // 141 // Two notes: 142 // 1) PassedWrapper supports any type that has a move constructor, however 143 // the type will need to be specifically whitelisted in order for it to be 144 // bound to a Callback. We guard this explicitly at the call of Passed() 145 // to make for clear errors. Things not given to Passed() will be forwarded 146 // and stored by value which will not work for general move-only types. 147 // 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL" 148 // scoper to a Callback and allow the Callback to execute once. 149 template <typename T> 150 class PassedWrapper { 151 public: 152 explicit PassedWrapper(T&& scoper) 153 : is_valid_(true), scoper_(std::move(scoper)) {} 154 PassedWrapper(PassedWrapper&& other) 155 : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {} 156 T Take() const { 157 CHECK(is_valid_); 158 is_valid_ = false; 159 return std::move(scoper_); 160 } 161 162 private: 163 mutable bool is_valid_; 164 mutable T scoper_; 165 }; 166 167 template <typename T> 168 using Unwrapper = BindUnwrapTraits<std::decay_t<T>>; 169 170 template <typename T> 171 decltype(auto) Unwrap(T&& o) { 172 return Unwrapper<T>::Unwrap(std::forward<T>(o)); 173 } 174 175 // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a 176 // method. It is used internally by Bind() to select the correct 177 // InvokeHelper that will no-op itself in the event the WeakPtr<> for 178 // the target object is invalidated. 179 // 180 // The first argument should be the type of the object that will be received by 181 // the method. 182 template <bool is_method, typename... Args> 183 struct IsWeakMethod : std::false_type {}; 184 185 template <typename T, typename... Args> 186 struct IsWeakMethod<true, T, Args...> : IsWeakReceiver<T> {}; 187 188 // Packs a list of types to hold them in a single type. 189 template <typename... Types> 190 struct TypeList {}; 191 192 // Used for DropTypeListItem implementation. 193 template <size_t n, typename List> 194 struct DropTypeListItemImpl; 195 196 // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. 197 template <size_t n, typename T, typename... List> 198 struct DropTypeListItemImpl<n, TypeList<T, List...>> 199 : DropTypeListItemImpl<n - 1, TypeList<List...>> {}; 200 201 template <typename T, typename... List> 202 struct DropTypeListItemImpl<0, TypeList<T, List...>> { 203 using Type = TypeList<T, List...>; 204 }; 205 206 template <> 207 struct DropTypeListItemImpl<0, TypeList<>> { 208 using Type = TypeList<>; 209 }; 210 211 // A type-level function that drops |n| list item from given TypeList. 212 template <size_t n, typename List> 213 using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type; 214 215 // Used for TakeTypeListItem implementation. 216 template <size_t n, typename List, typename... Accum> 217 struct TakeTypeListItemImpl; 218 219 // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. 220 template <size_t n, typename T, typename... List, typename... Accum> 221 struct TakeTypeListItemImpl<n, TypeList<T, List...>, Accum...> 222 : TakeTypeListItemImpl<n - 1, TypeList<List...>, Accum..., T> {}; 223 224 template <typename T, typename... List, typename... Accum> 225 struct TakeTypeListItemImpl<0, TypeList<T, List...>, Accum...> { 226 using Type = TypeList<Accum...>; 227 }; 228 229 template <typename... Accum> 230 struct TakeTypeListItemImpl<0, TypeList<>, Accum...> { 231 using Type = TypeList<Accum...>; 232 }; 233 234 // A type-level function that takes first |n| list item from given TypeList. 235 // E.g. TakeTypeListItem<3, TypeList<A, B, C, D>> is evaluated to 236 // TypeList<A, B, C>. 237 template <size_t n, typename List> 238 using TakeTypeListItem = typename TakeTypeListItemImpl<n, List>::Type; 239 240 // Used for ConcatTypeLists implementation. 241 template <typename List1, typename List2> 242 struct ConcatTypeListsImpl; 243 244 template <typename... Types1, typename... Types2> 245 struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> { 246 using Type = TypeList<Types1..., Types2...>; 247 }; 248 249 // A type-level function that concats two TypeLists. 250 template <typename List1, typename List2> 251 using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type; 252 253 // Used for MakeFunctionType implementation. 254 template <typename R, typename ArgList> 255 struct MakeFunctionTypeImpl; 256 257 template <typename R, typename... Args> 258 struct MakeFunctionTypeImpl<R, TypeList<Args...>> { 259 // MSVC 2013 doesn't support Type Alias of function types. 260 // Revisit this after we update it to newer version. 261 typedef R Type(Args...); 262 }; 263 264 // A type-level function that constructs a function type that has |R| as its 265 // return type and has TypeLists items as its arguments. 266 template <typename R, typename ArgList> 267 using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type; 268 269 // Used for ExtractArgs and ExtractReturnType. 270 template <typename Signature> 271 struct ExtractArgsImpl; 272 273 template <typename R, typename... Args> 274 struct ExtractArgsImpl<R(Args...)> { 275 using ReturnType = R; 276 using ArgsList = TypeList<Args...>; 277 }; 278 279 // A type-level function that extracts function arguments into a TypeList. 280 // E.g. ExtractArgs<R(A, B, C)> is evaluated to TypeList<A, B, C>. 281 template <typename Signature> 282 using ExtractArgs = typename ExtractArgsImpl<Signature>::ArgsList; 283 284 // A type-level function that extracts the return type of a function. 285 // E.g. ExtractReturnType<R(A, B, C)> is evaluated to R. 286 template <typename Signature> 287 using ExtractReturnType = typename ExtractArgsImpl<Signature>::ReturnType; 288 289 template <typename Callable, 290 typename Signature = decltype(&Callable::operator())> 291 struct ExtractCallableRunTypeImpl; 292 293 template <typename Callable, typename R, typename... Args> 294 struct ExtractCallableRunTypeImpl<Callable, R (Callable::*)(Args...)> { 295 using Type = R(Args...); 296 }; 297 298 template <typename Callable, typename R, typename... Args> 299 struct ExtractCallableRunTypeImpl<Callable, R (Callable::*)(Args...) const> { 300 using Type = R(Args...); 301 }; 302 303 // Evaluated to RunType of the given callable type. 304 // Example: 305 // auto f = [](int, char*) { return 0.1; }; 306 // ExtractCallableRunType<decltype(f)> 307 // is evaluated to 308 // double(int, char*); 309 template <typename Callable> 310 using ExtractCallableRunType = 311 typename ExtractCallableRunTypeImpl<Callable>::Type; 312 313 // IsCallableObject<Functor> is std::true_type if |Functor| has operator(). 314 // Otherwise, it's std::false_type. 315 // Example: 316 // IsCallableObject<void(*)()>::value is false. 317 // 318 // struct Foo {}; 319 // IsCallableObject<void(Foo::*)()>::value is false. 320 // 321 // int i = 0; 322 // auto f = [i]() {}; 323 // IsCallableObject<decltype(f)>::value is false. 324 template <typename Functor, typename SFINAE = void> 325 struct IsCallableObject : std::false_type {}; 326 327 template <typename Callable> 328 struct IsCallableObject<Callable, void_t<decltype(&Callable::operator())>> 329 : std::true_type {}; 330 331 // HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw 332 // pointer to a RefCounted type. 333 // Implementation note: This non-specialized case handles zero-arity case only. 334 // Non-zero-arity cases should be handled by the specialization below. 335 template <typename... Args> 336 struct HasRefCountedTypeAsRawPtr : std::false_type {}; 337 338 // Implementation note: Select true_type if the first parameter is a raw pointer 339 // to a RefCounted type. Otherwise, skip the first parameter and check rest of 340 // parameters recursively. 341 template <typename T, typename... Args> 342 struct HasRefCountedTypeAsRawPtr<T, Args...> 343 : std::conditional_t<NeedsScopedRefptrButGetsRawPtr<T>::value, 344 std::true_type, 345 HasRefCountedTypeAsRawPtr<Args...>> {}; 346 347 // ForceVoidReturn<> 348 // 349 // Set of templates that support forcing the function return type to void. 350 template <typename Sig> 351 struct ForceVoidReturn; 352 353 template <typename R, typename... Args> 354 struct ForceVoidReturn<R(Args...)> { 355 using RunType = void(Args...); 356 }; 357 358 // FunctorTraits<> 359 // 360 // See description at top of file. 361 template <typename Functor, typename SFINAE> 362 struct FunctorTraits; 363 364 // For empty callable types. 365 // This specialization is intended to allow binding captureless lambdas by 366 // base::Bind(), based on the fact that captureless lambdas are empty while 367 // capturing lambdas are not. This also allows any functors as far as it's an 368 // empty class. 369 // Example: 370 // 371 // // Captureless lambdas are allowed. 372 // []() {return 42;}; 373 // 374 // // Capturing lambdas are *not* allowed. 375 // int x; 376 // [x]() {return x;}; 377 // 378 // // Any empty class with operator() is allowed. 379 // struct Foo { 380 // void operator()() const {} 381 // // No non-static member variable and no virtual functions. 382 // }; 383 template <typename Functor> 384 struct FunctorTraits<Functor, 385 std::enable_if_t<IsCallableObject<Functor>::value && 386 std::is_empty<Functor>::value>> { 387 using RunType = ExtractCallableRunType<Functor>; 388 static constexpr bool is_method = false; 389 static constexpr bool is_nullable = false; 390 391 template <typename RunFunctor, typename... RunArgs> 392 static ExtractReturnType<RunType> Invoke(RunFunctor&& functor, 393 RunArgs&&... args) { 394 return std::forward<RunFunctor>(functor)(std::forward<RunArgs>(args)...); 395 } 396 }; 397 398 // For functions. 399 template <typename R, typename... Args> 400 struct FunctorTraits<R (*)(Args...)> { 401 using RunType = R(Args...); 402 static constexpr bool is_method = false; 403 static constexpr bool is_nullable = true; 404 405 template <typename Function, typename... RunArgs> 406 static R Invoke(Function&& function, RunArgs&&... args) { 407 return std::forward<Function>(function)(std::forward<RunArgs>(args)...); 408 } 409 }; 410 411 #if defined(OS_WIN) && !defined(ARCH_CPU_X86_64) 412 413 // For functions. 414 template <typename R, typename... Args> 415 struct FunctorTraits<R(__stdcall*)(Args...)> { 416 using RunType = R(Args...); 417 static constexpr bool is_method = false; 418 static constexpr bool is_nullable = true; 419 420 template <typename... RunArgs> 421 static R Invoke(R(__stdcall* function)(Args...), RunArgs&&... args) { 422 return function(std::forward<RunArgs>(args)...); 423 } 424 }; 425 426 // For functions. 427 template <typename R, typename... Args> 428 struct FunctorTraits<R(__fastcall*)(Args...)> { 429 using RunType = R(Args...); 430 static constexpr bool is_method = false; 431 static constexpr bool is_nullable = true; 432 433 template <typename... RunArgs> 434 static R Invoke(R(__fastcall* function)(Args...), RunArgs&&... args) { 435 return function(std::forward<RunArgs>(args)...); 436 } 437 }; 438 439 #endif // defined(OS_WIN) && !defined(ARCH_CPU_X86_64) 440 441 #if defined(OS_MACOSX) 442 443 // Support for Objective-C blocks. There are two implementation depending 444 // on whether Automated Reference Counting (ARC) is enabled. When ARC is 445 // enabled, then the block itself can be bound as the compiler will ensure 446 // its lifetime will be correctly managed. Otherwise, require the block to 447 // be wrapped in a base::mac::ScopedBlock (via base::RetainBlock) that will 448 // correctly manage the block lifetime. 449 // 450 // The two implementation ensure that the One Definition Rule (ODR) is not 451 // broken (it is not possible to write a template base::RetainBlock that would 452 // work correctly both with ARC enabled and disabled). 453 454 #if HAS_FEATURE(objc_arc) 455 456 template <typename R, typename... Args> 457 struct FunctorTraits<R (^)(Args...)> { 458 using RunType = R(Args...); 459 static constexpr bool is_method = false; 460 static constexpr bool is_nullable = true; 461 462 template <typename BlockType, typename... RunArgs> 463 static R Invoke(BlockType&& block, RunArgs&&... args) { 464 // According to LLVM documentation ( 6.3), "local variables of automatic 465 // storage duration do not have precise lifetime." Use objc_precise_lifetime 466 // to ensure that the Objective-C block is not deallocated until it has 467 // finished executing even if the Callback<> is destroyed during the block 468 // execution. 469 // https://clang.llvm.org/docs/AutomaticReferenceCounting.html#precise-lifetime-semantics 470 __attribute__((objc_precise_lifetime)) R (^scoped_block)(Args...) = block; 471 return scoped_block(std::forward<RunArgs>(args)...); 472 } 473 }; 474 475 #else // HAS_FEATURE(objc_arc) 476 477 template <typename R, typename... Args> 478 struct FunctorTraits<base::mac::ScopedBlock<R (^)(Args...)>> { 479 using RunType = R(Args...); 480 static constexpr bool is_method = false; 481 static constexpr bool is_nullable = true; 482 483 template <typename BlockType, typename... RunArgs> 484 static R Invoke(BlockType&& block, RunArgs&&... args) { 485 // Copy the block to ensure that the Objective-C block is not deallocated 486 // until it has finished executing even if the Callback<> is destroyed 487 // during the block execution. 488 base::mac::ScopedBlock<R (^)(Args...)> scoped_block(block); 489 return scoped_block.get()(std::forward<RunArgs>(args)...); 490 } 491 }; 492 493 #endif // HAS_FEATURE(objc_arc) 494 #endif // defined(OS_MACOSX) 495 496 // For methods. 497 template <typename R, typename Receiver, typename... Args> 498 struct FunctorTraits<R (Receiver::*)(Args...)> { 499 using RunType = R(Receiver*, Args...); 500 static constexpr bool is_method = true; 501 static constexpr bool is_nullable = true; 502 503 template <typename Method, typename ReceiverPtr, typename... RunArgs> 504 static R Invoke(Method method, 505 ReceiverPtr&& receiver_ptr, 506 RunArgs&&... args) { 507 return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...); 508 } 509 }; 510 511 // For const methods. 512 template <typename R, typename Receiver, typename... Args> 513 struct FunctorTraits<R (Receiver::*)(Args...) const> { 514 using RunType = R(const Receiver*, Args...); 515 static constexpr bool is_method = true; 516 static constexpr bool is_nullable = true; 517 518 template <typename Method, typename ReceiverPtr, typename... RunArgs> 519 static R Invoke(Method method, 520 ReceiverPtr&& receiver_ptr, 521 RunArgs&&... args) { 522 return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...); 523 } 524 }; 525 526 #ifdef __cpp_noexcept_function_type 527 // noexcept makes a distinct function type in C++17. 528 // I.e. `void(*)()` and `void(*)() noexcept` are same in pre-C++17, and 529 // different in C++17. 530 template <typename R, typename... Args> 531 struct FunctorTraits<R (*)(Args...) noexcept> : FunctorTraits<R (*)(Args...)> { 532 }; 533 534 template <typename R, typename Receiver, typename... Args> 535 struct FunctorTraits<R (Receiver::*)(Args...) noexcept> 536 : FunctorTraits<R (Receiver::*)(Args...)> {}; 537 538 template <typename R, typename Receiver, typename... Args> 539 struct FunctorTraits<R (Receiver::*)(Args...) const noexcept> 540 : FunctorTraits<R (Receiver::*)(Args...) const> {}; 541 #endif 542 543 // For IgnoreResults. 544 template <typename T> 545 struct FunctorTraits<IgnoreResultHelper<T>> : FunctorTraits<T> { 546 using RunType = 547 typename ForceVoidReturn<typename FunctorTraits<T>::RunType>::RunType; 548 549 template <typename IgnoreResultType, typename... RunArgs> 550 static void Invoke(IgnoreResultType&& ignore_result_helper, 551 RunArgs&&... args) { 552 FunctorTraits<T>::Invoke( 553 std::forward<IgnoreResultType>(ignore_result_helper).functor_, 554 std::forward<RunArgs>(args)...); 555 } 556 }; 557 558 // For OnceCallbacks. 559 template <typename R, typename... Args> 560 struct FunctorTraits<OnceCallback<R(Args...)>> { 561 using RunType = R(Args...); 562 static constexpr bool is_method = false; 563 static constexpr bool is_nullable = true; 564 565 template <typename CallbackType, typename... RunArgs> 566 static R Invoke(CallbackType&& callback, RunArgs&&... args) { 567 DCHECK(!callback.is_null()); 568 return std::forward<CallbackType>(callback).Run( 569 std::forward<RunArgs>(args)...); 570 } 571 }; 572 573 // For RepeatingCallbacks. 574 template <typename R, typename... Args> 575 struct FunctorTraits<RepeatingCallback<R(Args...)>> { 576 using RunType = R(Args...); 577 static constexpr bool is_method = false; 578 static constexpr bool is_nullable = true; 579 580 template <typename CallbackType, typename... RunArgs> 581 static R Invoke(CallbackType&& callback, RunArgs&&... args) { 582 DCHECK(!callback.is_null()); 583 return std::forward<CallbackType>(callback).Run( 584 std::forward<RunArgs>(args)...); 585 } 586 }; 587 588 template <typename Functor> 589 using MakeFunctorTraits = FunctorTraits<std::decay_t<Functor>>; 590 591 // InvokeHelper<> 592 // 593 // There are 2 logical InvokeHelper<> specializations: normal, WeakCalls. 594 // 595 // The normal type just calls the underlying runnable. 596 // 597 // WeakCalls need special syntax that is applied to the first argument to check 598 // if they should no-op themselves. 599 template <bool is_weak_call, typename ReturnType> 600 struct InvokeHelper; 601 602 template <typename ReturnType> 603 struct InvokeHelper<false, ReturnType> { 604 template <typename Functor, typename... RunArgs> 605 static inline ReturnType MakeItSo(Functor&& functor, RunArgs&&... args) { 606 using Traits = MakeFunctorTraits<Functor>; 607 return Traits::Invoke(std::forward<Functor>(functor), 608 std::forward<RunArgs>(args)...); 609 } 610 }; 611 612 template <typename ReturnType> 613 struct InvokeHelper<true, ReturnType> { 614 // WeakCalls are only supported for functions with a void return type. 615 // Otherwise, the function result would be undefined if the the WeakPtr<> 616 // is invalidated. 617 static_assert(std::is_void<ReturnType>::value, 618 "weak_ptrs can only bind to methods without return values"); 619 620 template <typename Functor, typename BoundWeakPtr, typename... RunArgs> 621 static inline void MakeItSo(Functor&& functor, 622 BoundWeakPtr&& weak_ptr, 623 RunArgs&&... args) { 624 if (!weak_ptr) 625 return; 626 using Traits = MakeFunctorTraits<Functor>; 627 Traits::Invoke(std::forward<Functor>(functor), 628 std::forward<BoundWeakPtr>(weak_ptr), 629 std::forward<RunArgs>(args)...); 630 } 631 }; 632 633 // Invoker<> 634 // 635 // See description at the top of the file. 636 template <typename StorageType, typename UnboundRunType> 637 struct Invoker; 638 639 template <typename StorageType, typename R, typename... UnboundArgs> 640 struct Invoker<StorageType, R(UnboundArgs...)> { 641 static R RunOnce(BindStateBase* base, 642 PassingType<UnboundArgs>... unbound_args) { 643 // Local references to make debugger stepping easier. If in a debugger, 644 // you really want to warp ahead and step through the 645 // InvokeHelper<>::MakeItSo() call below. 646 StorageType* storage = static_cast<StorageType*>(base); 647 static constexpr size_t num_bound_args = 648 std::tuple_size<decltype(storage->bound_args_)>::value; 649 return RunImpl(std::move(storage->functor_), 650 std::move(storage->bound_args_), 651 std::make_index_sequence<num_bound_args>(), 652 std::forward<UnboundArgs>(unbound_args)...); 653 } 654 655 static R Run(BindStateBase* base, PassingType<UnboundArgs>... unbound_args) { 656 // Local references to make debugger stepping easier. If in a debugger, 657 // you really want to warp ahead and step through the 658 // InvokeHelper<>::MakeItSo() call below. 659 const StorageType* storage = static_cast<StorageType*>(base); 660 static constexpr size_t num_bound_args = 661 std::tuple_size<decltype(storage->bound_args_)>::value; 662 return RunImpl(storage->functor_, storage->bound_args_, 663 std::make_index_sequence<num_bound_args>(), 664 std::forward<UnboundArgs>(unbound_args)...); 665 } 666 667 private: 668 template <typename Functor, typename BoundArgsTuple, size_t... indices> 669 static inline R RunImpl(Functor&& functor, 670 BoundArgsTuple&& bound, 671 std::index_sequence<indices...>, 672 UnboundArgs&&... unbound_args) { 673 static constexpr bool is_method = MakeFunctorTraits<Functor>::is_method; 674 675 using DecayedArgsTuple = std::decay_t<BoundArgsTuple>; 676 static constexpr bool is_weak_call = 677 IsWeakMethod<is_method, 678 std::tuple_element_t<indices, DecayedArgsTuple>...>(); 679 680 return InvokeHelper<is_weak_call, R>::MakeItSo( 681 std::forward<Functor>(functor), 682 Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))..., 683 std::forward<UnboundArgs>(unbound_args)...); 684 } 685 }; 686 687 // Extracts necessary type info from Functor and BoundArgs. 688 // Used to implement MakeUnboundRunType, BindOnce and BindRepeating. 689 template <typename Functor, typename... BoundArgs> 690 struct BindTypeHelper { 691 static constexpr size_t num_bounds = sizeof...(BoundArgs); 692 using FunctorTraits = MakeFunctorTraits<Functor>; 693 694 // Example: 695 // When Functor is `double (Foo::*)(int, const std::string&)`, and BoundArgs 696 // is a template pack of `Foo*` and `int16_t`: 697 // - RunType is `double(Foo*, int, const std::string&)`, 698 // - ReturnType is `double`, 699 // - RunParamsList is `TypeList<Foo*, int, const std::string&>`, 700 // - BoundParamsList is `TypeList<Foo*, int>`, 701 // - UnboundParamsList is `TypeList<const std::string&>`, 702 // - BoundArgsList is `TypeList<Foo*, int16_t>`, 703 // - UnboundRunType is `double(const std::string&)`. 704 using RunType = typename FunctorTraits::RunType; 705 using ReturnType = ExtractReturnType<RunType>; 706 707 using RunParamsList = ExtractArgs<RunType>; 708 using BoundParamsList = TakeTypeListItem<num_bounds, RunParamsList>; 709 using UnboundParamsList = DropTypeListItem<num_bounds, RunParamsList>; 710 711 using BoundArgsList = TypeList<BoundArgs...>; 712 713 using UnboundRunType = MakeFunctionType<ReturnType, UnboundParamsList>; 714 }; 715 716 template <typename Functor> 717 std::enable_if_t<FunctorTraits<Functor>::is_nullable, bool> IsNull( 718 const Functor& functor) { 719 return !functor; 720 } 721 722 template <typename Functor> 723 std::enable_if_t<!FunctorTraits<Functor>::is_nullable, bool> IsNull( 724 const Functor&) { 725 return false; 726 } 727 728 // Used by ApplyCancellationTraits below. 729 template <typename Functor, typename BoundArgsTuple, size_t... indices> 730 bool ApplyCancellationTraitsImpl(const Functor& functor, 731 const BoundArgsTuple& bound_args, 732 std::index_sequence<indices...>) { 733 return CallbackCancellationTraits<Functor, BoundArgsTuple>::IsCancelled( 734 functor, std::get<indices>(bound_args)...); 735 } 736 737 // Relays |base| to corresponding CallbackCancellationTraits<>::Run(). Returns 738 // true if the callback |base| represents is canceled. 739 template <typename BindStateType> 740 bool ApplyCancellationTraits(const BindStateBase* base) { 741 const BindStateType* storage = static_cast<const BindStateType*>(base); 742 static constexpr size_t num_bound_args = 743 std::tuple_size<decltype(storage->bound_args_)>::value; 744 return ApplyCancellationTraitsImpl( 745 storage->functor_, storage->bound_args_, 746 std::make_index_sequence<num_bound_args>()); 747 }; 748 749 // BindState<> 750 // 751 // This stores all the state passed into Bind(). 752 template <typename Functor, typename... BoundArgs> 753 struct BindState final : BindStateBase { 754 using IsCancellable = std::integral_constant< 755 bool, 756 CallbackCancellationTraits<Functor, 757 std::tuple<BoundArgs...>>::is_cancellable>; 758 759 template <typename ForwardFunctor, typename... ForwardBoundArgs> 760 explicit BindState(BindStateBase::InvokeFuncStorage invoke_func, 761 ForwardFunctor&& functor, 762 ForwardBoundArgs&&... bound_args) 763 // IsCancellable is std::false_type if 764 // CallbackCancellationTraits<>::IsCancelled returns always false. 765 // Otherwise, it's std::true_type. 766 : BindState(IsCancellable{}, 767 invoke_func, 768 std::forward<ForwardFunctor>(functor), 769 std::forward<ForwardBoundArgs>(bound_args)...) {} 770 771 Functor functor_; 772 std::tuple<BoundArgs...> bound_args_; 773 774 private: 775 template <typename ForwardFunctor, typename... ForwardBoundArgs> 776 explicit BindState(std::true_type, 777 BindStateBase::InvokeFuncStorage invoke_func, 778 ForwardFunctor&& functor, 779 ForwardBoundArgs&&... bound_args) 780 : BindStateBase(invoke_func, 781 &Destroy, 782 &ApplyCancellationTraits<BindState>), 783 functor_(std::forward<ForwardFunctor>(functor)), 784 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) { 785 DCHECK(!IsNull(functor_)); 786 } 787 788 template <typename ForwardFunctor, typename... ForwardBoundArgs> 789 explicit BindState(std::false_type, 790 BindStateBase::InvokeFuncStorage invoke_func, 791 ForwardFunctor&& functor, 792 ForwardBoundArgs&&... bound_args) 793 : BindStateBase(invoke_func, &Destroy), 794 functor_(std::forward<ForwardFunctor>(functor)), 795 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) { 796 DCHECK(!IsNull(functor_)); 797 } 798 799 ~BindState() = default; 800 801 static void Destroy(const BindStateBase* self) { 802 delete static_cast<const BindState*>(self); 803 } 804 }; 805 806 // Used to implement MakeBindStateType. 807 template <bool is_method, typename Functor, typename... BoundArgs> 808 struct MakeBindStateTypeImpl; 809 810 template <typename Functor, typename... BoundArgs> 811 struct MakeBindStateTypeImpl<false, Functor, BoundArgs...> { 812 static_assert(!HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>::value, 813 "A parameter is a refcounted type and needs scoped_refptr."); 814 using Type = BindState<std::decay_t<Functor>, std::decay_t<BoundArgs>...>; 815 }; 816 817 template <typename Functor> 818 struct MakeBindStateTypeImpl<true, Functor> { 819 using Type = BindState<std::decay_t<Functor>>; 820 }; 821 822 template <typename Functor, typename Receiver, typename... BoundArgs> 823 struct MakeBindStateTypeImpl<true, Functor, Receiver, BoundArgs...> { 824 private: 825 using DecayedReceiver = std::decay_t<Receiver>; 826 827 static_assert(!std::is_array<std::remove_reference_t<Receiver>>::value, 828 "First bound argument to a method cannot be an array."); 829 static_assert( 830 !std::is_pointer<DecayedReceiver>::value || 831 IsRefCountedType<std::remove_pointer_t<DecayedReceiver>>::value, 832 "Receivers may not be raw pointers. If using a raw pointer here is safe" 833 " and has no lifetime concerns, use base::Unretained() and document why" 834 " it's safe."); 835 static_assert(!HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>::value, 836 "A parameter is a refcounted type and needs scoped_refptr."); 837 838 public: 839 using Type = BindState< 840 std::decay_t<Functor>, 841 std::conditional_t<std::is_pointer<DecayedReceiver>::value, 842 scoped_refptr<std::remove_pointer_t<DecayedReceiver>>, 843 DecayedReceiver>, 844 std::decay_t<BoundArgs>...>; 845 }; 846 847 template <typename Functor, typename... BoundArgs> 848 using MakeBindStateType = 849 typename MakeBindStateTypeImpl<MakeFunctorTraits<Functor>::is_method, 850 Functor, 851 BoundArgs...>::Type; 852 853 } // namespace internal 854 855 // An injection point to control |this| pointer behavior on a method invocation. 856 // If IsWeakReceiver<> is true_type for |T| and |T| is used for a receiver of a 857 // method, base::Bind cancels the method invocation if the receiver is tested as 858 // false. 859 // E.g. Foo::bar() is not called: 860 // struct Foo : base::SupportsWeakPtr<Foo> { 861 // void bar() {} 862 // }; 863 // 864 // WeakPtr<Foo> oo = nullptr; 865 // base::Bind(&Foo::bar, oo).Run(); 866 template <typename T> 867 struct IsWeakReceiver : std::false_type {}; 868 869 template <typename T> 870 struct IsWeakReceiver<internal::ConstRefWrapper<T>> : IsWeakReceiver<T> {}; 871 872 template <typename T> 873 struct IsWeakReceiver<WeakPtr<T>> : std::true_type {}; 874 875 // An injection point to control how bound objects passed to the target 876 // function. BindUnwrapTraits<>::Unwrap() is called for each bound objects right 877 // before the target function is invoked. 878 template <typename> 879 struct BindUnwrapTraits { 880 template <typename T> 881 static T&& Unwrap(T&& o) { 882 return std::forward<T>(o); 883 } 884 }; 885 886 template <typename T> 887 struct BindUnwrapTraits<internal::UnretainedWrapper<T>> { 888 static T* Unwrap(const internal::UnretainedWrapper<T>& o) { return o.get(); } 889 }; 890 891 template <typename T> 892 struct BindUnwrapTraits<internal::ConstRefWrapper<T>> { 893 static const T& Unwrap(const internal::ConstRefWrapper<T>& o) { 894 return o.get(); 895 } 896 }; 897 898 template <typename T> 899 struct BindUnwrapTraits<internal::RetainedRefWrapper<T>> { 900 static T* Unwrap(const internal::RetainedRefWrapper<T>& o) { return o.get(); } 901 }; 902 903 template <typename T> 904 struct BindUnwrapTraits<internal::OwnedWrapper<T>> { 905 static T* Unwrap(const internal::OwnedWrapper<T>& o) { return o.get(); } 906 }; 907 908 template <typename T> 909 struct BindUnwrapTraits<internal::PassedWrapper<T>> { 910 static T Unwrap(const internal::PassedWrapper<T>& o) { return o.Take(); } 911 }; 912 913 // CallbackCancellationTraits allows customization of Callback's cancellation 914 // semantics. By default, callbacks are not cancellable. A specialization should 915 // set is_cancellable = true and implement an IsCancelled() that returns if the 916 // callback should be cancelled. 917 template <typename Functor, typename BoundArgsTuple, typename SFINAE> 918 struct CallbackCancellationTraits { 919 static constexpr bool is_cancellable = false; 920 }; 921 922 // Specialization for method bound to weak pointer receiver. 923 template <typename Functor, typename... BoundArgs> 924 struct CallbackCancellationTraits< 925 Functor, 926 std::tuple<BoundArgs...>, 927 std::enable_if_t< 928 internal::IsWeakMethod<internal::FunctorTraits<Functor>::is_method, 929 BoundArgs...>::value>> { 930 static constexpr bool is_cancellable = true; 931 932 template <typename Receiver, typename... Args> 933 static bool IsCancelled(const Functor&, 934 const Receiver& receiver, 935 const Args&...) { 936 return !receiver; 937 } 938 }; 939 940 // Specialization for a nested bind. 941 template <typename Signature, typename... BoundArgs> 942 struct CallbackCancellationTraits<OnceCallback<Signature>, 943 std::tuple<BoundArgs...>> { 944 static constexpr bool is_cancellable = true; 945 946 template <typename Functor> 947 static bool IsCancelled(const Functor& functor, const BoundArgs&...) { 948 return functor.IsCancelled(); 949 } 950 }; 951 952 template <typename Signature, typename... BoundArgs> 953 struct CallbackCancellationTraits<RepeatingCallback<Signature>, 954 std::tuple<BoundArgs...>> { 955 static constexpr bool is_cancellable = true; 956 957 template <typename Functor> 958 static bool IsCancelled(const Functor& functor, const BoundArgs&...) { 959 return functor.IsCancelled(); 960 } 961 }; 962 963 // Returns a RunType of bound functor. 964 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C). 965 template <typename Functor, typename... BoundArgs> 966 using MakeUnboundRunType = 967 typename internal::BindTypeHelper<Functor, BoundArgs...>::UnboundRunType; 968 969 } // namespace base 970 971 #endif // BASE_BIND_INTERNAL_H_ 972