Home | History | Annotate | Download | only in base
      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