| // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef BASE_BIND_INTERNAL_H_ | 
 | #define BASE_BIND_INTERNAL_H_ | 
 |  | 
 | #include <stddef.h> | 
 |  | 
 | #include <type_traits> | 
 | #include <utility> | 
 |  | 
 | #include "base/callback_internal.h" | 
 | #include "base/memory/raw_scoped_refptr_mismatch_checker.h" | 
 | #include "base/memory/weak_ptr.h" | 
 | #include "base/template_util.h" | 
 | #include "build/build_config.h" | 
 |  | 
 | // See base/callback.h for user documentation. | 
 | // | 
 | // | 
 | // CONCEPTS: | 
 | //  Functor -- A movable type representing something that should be called. | 
 | //             All function pointers and Callback<> are functors even if the | 
 | //             invocation syntax differs. | 
 | //  RunType -- A function type (as opposed to function _pointer_ type) for | 
 | //             a Callback<>::Run().  Usually just a convenience typedef. | 
 | //  (Bound)Args -- A set of types that stores the arguments. | 
 | // | 
 | // Types: | 
 | //  ForceVoidReturn<> -- Helper class for translating function signatures to | 
 | //                       equivalent forms with a "void" return type. | 
 | //  FunctorTraits<> -- Type traits used to determine the correct RunType and | 
 | //                     invocation manner for a Functor.  This is where function | 
 | //                     signature adapters are applied. | 
 | //  InvokeHelper<> -- Take a Functor + arguments and actully invokes it. | 
 | //                    Handle the differing syntaxes needed for WeakPtr<> | 
 | //                    support.  This is separate from Invoker to avoid creating | 
 | //                    multiple version of Invoker<>. | 
 | //  Invoker<> -- Unwraps the curried parameters and executes the Functor. | 
 | //  BindState<> -- Stores the curried parameters, and is the main entry point | 
 | //                 into the Bind() system. | 
 |  | 
 | namespace base { | 
 |  | 
 | template <typename T> | 
 | struct IsWeakReceiver; | 
 |  | 
 | template <typename> | 
 | struct BindUnwrapTraits; | 
 |  | 
 | template <typename Functor, typename BoundArgsTuple, typename SFINAE = void> | 
 | struct CallbackCancellationTraits; | 
 |  | 
 | namespace internal { | 
 |  | 
 | template <typename Functor, typename SFINAE = void> | 
 | struct FunctorTraits; | 
 |  | 
 | template <typename T> | 
 | class UnretainedWrapper { | 
 |  public: | 
 |   explicit UnretainedWrapper(T* o) : ptr_(o) {} | 
 |   T* get() const { return ptr_; } | 
 |  | 
 |  private: | 
 |   T* ptr_; | 
 | }; | 
 |  | 
 | template <typename T> | 
 | class ConstRefWrapper { | 
 |  public: | 
 |   explicit ConstRefWrapper(const T& o) : ptr_(&o) {} | 
 |   const T& get() const { return *ptr_; } | 
 |  | 
 |  private: | 
 |   const T* ptr_; | 
 | }; | 
 |  | 
 | template <typename T> | 
 | class RetainedRefWrapper { | 
 |  public: | 
 |   explicit RetainedRefWrapper(T* o) : ptr_(o) {} | 
 |   explicit RetainedRefWrapper(scoped_refptr<T> o) : ptr_(std::move(o)) {} | 
 |   T* get() const { return ptr_.get(); } | 
 |  | 
 |  private: | 
 |   scoped_refptr<T> ptr_; | 
 | }; | 
 |  | 
 | template <typename T> | 
 | struct IgnoreResultHelper { | 
 |   explicit IgnoreResultHelper(T functor) : functor_(std::move(functor)) {} | 
 |   explicit operator bool() const { return !!functor_; } | 
 |  | 
 |   T functor_; | 
 | }; | 
 |  | 
 | // An alternate implementation is to avoid the destructive copy, and instead | 
 | // specialize ParamTraits<> for OwnedWrapper<> to change the StorageType to | 
 | // a class that is essentially a std::unique_ptr<>. | 
 | // | 
 | // The current implementation has the benefit though of leaving ParamTraits<> | 
 | // fully in callback_internal.h as well as avoiding type conversions during | 
 | // storage. | 
 | template <typename T> | 
 | class OwnedWrapper { | 
 |  public: | 
 |   explicit OwnedWrapper(T* o) : ptr_(o) {} | 
 |   ~OwnedWrapper() { delete ptr_; } | 
 |   T* get() const { return ptr_; } | 
 |   OwnedWrapper(OwnedWrapper&& other) { | 
 |     ptr_ = other.ptr_; | 
 |     other.ptr_ = NULL; | 
 |   } | 
 |  | 
 |  private: | 
 |   mutable T* ptr_; | 
 | }; | 
 |  | 
 | // PassedWrapper is a copyable adapter for a scoper that ignores const. | 
 | // | 
 | // It is needed to get around the fact that Bind() takes a const reference to | 
 | // all its arguments.  Because Bind() takes a const reference to avoid | 
 | // unnecessary copies, it is incompatible with movable-but-not-copyable | 
 | // types; doing a destructive "move" of the type into Bind() would violate | 
 | // the const correctness. | 
 | // | 
 | // This conundrum cannot be solved without either C++11 rvalue references or | 
 | // a O(2^n) blowup of Bind() templates to handle each combination of regular | 
 | // types and movable-but-not-copyable types.  Thus we introduce a wrapper type | 
 | // that is copyable to transmit the correct type information down into | 
 | // BindState<>. Ignoring const in this type makes sense because it is only | 
 | // created when we are explicitly trying to do a destructive move. | 
 | // | 
 | // Two notes: | 
 | //  1) PassedWrapper supports any type that has a move constructor, however | 
 | //     the type will need to be specifically whitelisted in order for it to be | 
 | //     bound to a Callback. We guard this explicitly at the call of Passed() | 
 | //     to make for clear errors. Things not given to Passed() will be forwarded | 
 | //     and stored by value which will not work for general move-only types. | 
 | //  2) is_valid_ is distinct from NULL because it is valid to bind a "NULL" | 
 | //     scoper to a Callback and allow the Callback to execute once. | 
 | template <typename T> | 
 | class PassedWrapper { | 
 |  public: | 
 |   explicit PassedWrapper(T&& scoper) | 
 |       : is_valid_(true), scoper_(std::move(scoper)) {} | 
 |   PassedWrapper(PassedWrapper&& other) | 
 |       : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {} | 
 |   T Take() const { | 
 |     CHECK(is_valid_); | 
 |     is_valid_ = false; | 
 |     return std::move(scoper_); | 
 |   } | 
 |  | 
 |  private: | 
 |   mutable bool is_valid_; | 
 |   mutable T scoper_; | 
 | }; | 
 |  | 
 | template <typename T> | 
 | using Unwrapper = BindUnwrapTraits<std::decay_t<T>>; | 
 |  | 
 | template <typename T> | 
 | decltype(auto) Unwrap(T&& o) { | 
 |   return Unwrapper<T>::Unwrap(std::forward<T>(o)); | 
 | } | 
 |  | 
 | // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a | 
 | // method.  It is used internally by Bind() to select the correct | 
 | // InvokeHelper that will no-op itself in the event the WeakPtr<> for | 
 | // the target object is invalidated. | 
 | // | 
 | // The first argument should be the type of the object that will be received by | 
 | // the method. | 
 | template <bool is_method, typename... Args> | 
 | struct IsWeakMethod : std::false_type {}; | 
 |  | 
 | template <typename T, typename... Args> | 
 | struct IsWeakMethod<true, T, Args...> : IsWeakReceiver<T> {}; | 
 |  | 
 | // Packs a list of types to hold them in a single type. | 
 | template <typename... Types> | 
 | struct TypeList {}; | 
 |  | 
 | // Used for DropTypeListItem implementation. | 
 | template <size_t n, typename List> | 
 | struct DropTypeListItemImpl; | 
 |  | 
 | // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. | 
 | template <size_t n, typename T, typename... List> | 
 | struct DropTypeListItemImpl<n, TypeList<T, List...>> | 
 |     : DropTypeListItemImpl<n - 1, TypeList<List...>> {}; | 
 |  | 
 | template <typename T, typename... List> | 
 | struct DropTypeListItemImpl<0, TypeList<T, List...>> { | 
 |   using Type = TypeList<T, List...>; | 
 | }; | 
 |  | 
 | template <> | 
 | struct DropTypeListItemImpl<0, TypeList<>> { | 
 |   using Type = TypeList<>; | 
 | }; | 
 |  | 
 | // A type-level function that drops |n| list item from given TypeList. | 
 | template <size_t n, typename List> | 
 | using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type; | 
 |  | 
 | // Used for TakeTypeListItem implementation. | 
 | template <size_t n, typename List, typename... Accum> | 
 | struct TakeTypeListItemImpl; | 
 |  | 
 | // Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. | 
 | template <size_t n, typename T, typename... List, typename... Accum> | 
 | struct TakeTypeListItemImpl<n, TypeList<T, List...>, Accum...> | 
 |     : TakeTypeListItemImpl<n - 1, TypeList<List...>, Accum..., T> {}; | 
 |  | 
 | template <typename T, typename... List, typename... Accum> | 
 | struct TakeTypeListItemImpl<0, TypeList<T, List...>, Accum...> { | 
 |   using Type = TypeList<Accum...>; | 
 | }; | 
 |  | 
 | template <typename... Accum> | 
 | struct TakeTypeListItemImpl<0, TypeList<>, Accum...> { | 
 |   using Type = TypeList<Accum...>; | 
 | }; | 
 |  | 
 | // A type-level function that takes first |n| list item from given TypeList. | 
 | // E.g. TakeTypeListItem<3, TypeList<A, B, C, D>> is evaluated to | 
 | // TypeList<A, B, C>. | 
 | template <size_t n, typename List> | 
 | using TakeTypeListItem = typename TakeTypeListItemImpl<n, List>::Type; | 
 |  | 
 | // Used for ConcatTypeLists implementation. | 
 | template <typename List1, typename List2> | 
 | struct ConcatTypeListsImpl; | 
 |  | 
 | template <typename... Types1, typename... Types2> | 
 | struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> { | 
 |   using Type = TypeList<Types1..., Types2...>; | 
 | }; | 
 |  | 
 | // A type-level function that concats two TypeLists. | 
 | template <typename List1, typename List2> | 
 | using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type; | 
 |  | 
 | // Used for MakeFunctionType implementation. | 
 | template <typename R, typename ArgList> | 
 | struct MakeFunctionTypeImpl; | 
 |  | 
 | template <typename R, typename... Args> | 
 | struct MakeFunctionTypeImpl<R, TypeList<Args...>> { | 
 |   // MSVC 2013 doesn't support Type Alias of function types. | 
 |   // Revisit this after we update it to newer version. | 
 |   typedef R Type(Args...); | 
 | }; | 
 |  | 
 | // A type-level function that constructs a function type that has |R| as its | 
 | // return type and has TypeLists items as its arguments. | 
 | template <typename R, typename ArgList> | 
 | using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type; | 
 |  | 
 | // Used for ExtractArgs and ExtractReturnType. | 
 | template <typename Signature> | 
 | struct ExtractArgsImpl; | 
 |  | 
 | template <typename R, typename... Args> | 
 | struct ExtractArgsImpl<R(Args...)> { | 
 |   using ReturnType = R; | 
 |   using ArgsList = TypeList<Args...>; | 
 | }; | 
 |  | 
 | // A type-level function that extracts function arguments into a TypeList. | 
 | // E.g. ExtractArgs<R(A, B, C)> is evaluated to TypeList<A, B, C>. | 
 | template <typename Signature> | 
 | using ExtractArgs = typename ExtractArgsImpl<Signature>::ArgsList; | 
 |  | 
 | // A type-level function that extracts the return type of a function. | 
 | // E.g. ExtractReturnType<R(A, B, C)> is evaluated to R. | 
 | template <typename Signature> | 
 | using ExtractReturnType = typename ExtractArgsImpl<Signature>::ReturnType; | 
 |  | 
 | template <typename Callable, | 
 |           typename Signature = decltype(&Callable::operator())> | 
 | struct ExtractCallableRunTypeImpl; | 
 |  | 
 | template <typename Callable, typename R, typename... Args> | 
 | struct ExtractCallableRunTypeImpl<Callable, R (Callable::*)(Args...)> { | 
 |   using Type = R(Args...); | 
 | }; | 
 |  | 
 | template <typename Callable, typename R, typename... Args> | 
 | struct ExtractCallableRunTypeImpl<Callable, R (Callable::*)(Args...) const> { | 
 |   using Type = R(Args...); | 
 | }; | 
 |  | 
 | // Evaluated to RunType of the given callable type. | 
 | // Example: | 
 | //   auto f = [](int, char*) { return 0.1; }; | 
 | //   ExtractCallableRunType<decltype(f)> | 
 | //   is evaluated to | 
 | //   double(int, char*); | 
 | template <typename Callable> | 
 | using ExtractCallableRunType = | 
 |     typename ExtractCallableRunTypeImpl<Callable>::Type; | 
 |  | 
 | // IsCallableObject<Functor> is std::true_type if |Functor| has operator(). | 
 | // Otherwise, it's std::false_type. | 
 | // Example: | 
 | //   IsCallableObject<void(*)()>::value is false. | 
 | // | 
 | //   struct Foo {}; | 
 | //   IsCallableObject<void(Foo::*)()>::value is false. | 
 | // | 
 | //   int i = 0; | 
 | //   auto f = [i]() {}; | 
 | //   IsCallableObject<decltype(f)>::value is false. | 
 | template <typename Functor, typename SFINAE = void> | 
 | struct IsCallableObject : std::false_type {}; | 
 |  | 
 | template <typename Callable> | 
 | struct IsCallableObject<Callable, void_t<decltype(&Callable::operator())>> | 
 |     : std::true_type {}; | 
 |  | 
 | // HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw | 
 | // pointer to a RefCounted type. | 
 | // Implementation note: This non-specialized case handles zero-arity case only. | 
 | // Non-zero-arity cases should be handled by the specialization below. | 
 | template <typename... Args> | 
 | struct HasRefCountedTypeAsRawPtr : std::false_type {}; | 
 |  | 
 | // Implementation note: Select true_type if the first parameter is a raw pointer | 
 | // to a RefCounted type. Otherwise, skip the first parameter and check rest of | 
 | // parameters recursively. | 
 | template <typename T, typename... Args> | 
 | struct HasRefCountedTypeAsRawPtr<T, Args...> | 
 |     : std::conditional_t<NeedsScopedRefptrButGetsRawPtr<T>::value, | 
 |                          std::true_type, | 
 |                          HasRefCountedTypeAsRawPtr<Args...>> {}; | 
 |  | 
 | // ForceVoidReturn<> | 
 | // | 
 | // Set of templates that support forcing the function return type to void. | 
 | template <typename Sig> | 
 | struct ForceVoidReturn; | 
 |  | 
 | template <typename R, typename... Args> | 
 | struct ForceVoidReturn<R(Args...)> { | 
 |   using RunType = void(Args...); | 
 | }; | 
 |  | 
 | // FunctorTraits<> | 
 | // | 
 | // See description at top of file. | 
 | template <typename Functor, typename SFINAE> | 
 | struct FunctorTraits; | 
 |  | 
 | // For empty callable types. | 
 | // This specialization is intended to allow binding captureless lambdas by | 
 | // base::Bind(), based on the fact that captureless lambdas are empty while | 
 | // capturing lambdas are not. This also allows any functors as far as it's an | 
 | // empty class. | 
 | // Example: | 
 | // | 
 | //   // Captureless lambdas are allowed. | 
 | //   []() {return 42;}; | 
 | // | 
 | //   // Capturing lambdas are *not* allowed. | 
 | //   int x; | 
 | //   [x]() {return x;}; | 
 | // | 
 | //   // Any empty class with operator() is allowed. | 
 | //   struct Foo { | 
 | //     void operator()() const {} | 
 | //     // No non-static member variable and no virtual functions. | 
 | //   }; | 
 | template <typename Functor> | 
 | struct FunctorTraits<Functor, | 
 |                      std::enable_if_t<IsCallableObject<Functor>::value && | 
 |                                       std::is_empty<Functor>::value>> { | 
 |   using RunType = ExtractCallableRunType<Functor>; | 
 |   static constexpr bool is_method = false; | 
 |   static constexpr bool is_nullable = false; | 
 |  | 
 |   template <typename RunFunctor, typename... RunArgs> | 
 |   static ExtractReturnType<RunType> Invoke(RunFunctor&& functor, | 
 |                                            RunArgs&&... args) { | 
 |     return std::forward<RunFunctor>(functor)(std::forward<RunArgs>(args)...); | 
 |   } | 
 | }; | 
 |  | 
 | // For functions. | 
 | template <typename R, typename... Args> | 
 | struct FunctorTraits<R (*)(Args...)> { | 
 |   using RunType = R(Args...); | 
 |   static constexpr bool is_method = false; | 
 |   static constexpr bool is_nullable = true; | 
 |  | 
 |   template <typename Function, typename... RunArgs> | 
 |   static R Invoke(Function&& function, RunArgs&&... args) { | 
 |     return std::forward<Function>(function)(std::forward<RunArgs>(args)...); | 
 |   } | 
 | }; | 
 |  | 
 | #if defined(OS_WIN) && !defined(ARCH_CPU_X86_64) | 
 |  | 
 | // For functions. | 
 | template <typename R, typename... Args> | 
 | struct FunctorTraits<R(__stdcall*)(Args...)> { | 
 |   using RunType = R(Args...); | 
 |   static constexpr bool is_method = false; | 
 |   static constexpr bool is_nullable = true; | 
 |  | 
 |   template <typename... RunArgs> | 
 |   static R Invoke(R(__stdcall* function)(Args...), RunArgs&&... args) { | 
 |     return function(std::forward<RunArgs>(args)...); | 
 |   } | 
 | }; | 
 |  | 
 | // For functions. | 
 | template <typename R, typename... Args> | 
 | struct FunctorTraits<R(__fastcall*)(Args...)> { | 
 |   using RunType = R(Args...); | 
 |   static constexpr bool is_method = false; | 
 |   static constexpr bool is_nullable = true; | 
 |  | 
 |   template <typename... RunArgs> | 
 |   static R Invoke(R(__fastcall* function)(Args...), RunArgs&&... args) { | 
 |     return function(std::forward<RunArgs>(args)...); | 
 |   } | 
 | }; | 
 |  | 
 | #endif  // defined(OS_WIN) && !defined(ARCH_CPU_X86_64) | 
 |  | 
 | // For methods. | 
 | template <typename R, typename Receiver, typename... Args> | 
 | struct FunctorTraits<R (Receiver::*)(Args...)> { | 
 |   using RunType = R(Receiver*, Args...); | 
 |   static constexpr bool is_method = true; | 
 |   static constexpr bool is_nullable = true; | 
 |  | 
 |   template <typename Method, typename ReceiverPtr, typename... RunArgs> | 
 |   static R Invoke(Method method, | 
 |                   ReceiverPtr&& receiver_ptr, | 
 |                   RunArgs&&... args) { | 
 |     return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...); | 
 |   } | 
 | }; | 
 |  | 
 | // For const methods. | 
 | template <typename R, typename Receiver, typename... Args> | 
 | struct FunctorTraits<R (Receiver::*)(Args...) const> { | 
 |   using RunType = R(const Receiver*, Args...); | 
 |   static constexpr bool is_method = true; | 
 |   static constexpr bool is_nullable = true; | 
 |  | 
 |   template <typename Method, typename ReceiverPtr, typename... RunArgs> | 
 |   static R Invoke(Method method, | 
 |                   ReceiverPtr&& receiver_ptr, | 
 |                   RunArgs&&... args) { | 
 |     return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...); | 
 |   } | 
 | }; | 
 |  | 
 | #ifdef __cpp_noexcept_function_type | 
 | // noexcept makes a distinct function type in C++17. | 
 | // I.e. `void(*)()` and `void(*)() noexcept` are same in pre-C++17, and | 
 | // different in C++17. | 
 | template <typename R, typename... Args> | 
 | struct FunctorTraits<R (*)(Args...) noexcept> : FunctorTraits<R (*)(Args...)> { | 
 | }; | 
 |  | 
 | template <typename R, typename Receiver, typename... Args> | 
 | struct FunctorTraits<R (Receiver::*)(Args...) noexcept> | 
 |     : FunctorTraits<R (Receiver::*)(Args...)> {}; | 
 |  | 
 | template <typename R, typename Receiver, typename... Args> | 
 | struct FunctorTraits<R (Receiver::*)(Args...) const noexcept> | 
 |     : FunctorTraits<R (Receiver::*)(Args...) const> {}; | 
 | #endif | 
 |  | 
 | // For IgnoreResults. | 
 | template <typename T> | 
 | struct FunctorTraits<IgnoreResultHelper<T>> : FunctorTraits<T> { | 
 |   using RunType = | 
 |       typename ForceVoidReturn<typename FunctorTraits<T>::RunType>::RunType; | 
 |  | 
 |   template <typename IgnoreResultType, typename... RunArgs> | 
 |   static void Invoke(IgnoreResultType&& ignore_result_helper, | 
 |                      RunArgs&&... args) { | 
 |     FunctorTraits<T>::Invoke( | 
 |         std::forward<IgnoreResultType>(ignore_result_helper).functor_, | 
 |         std::forward<RunArgs>(args)...); | 
 |   } | 
 | }; | 
 |  | 
 | // For OnceCallbacks. | 
 | template <typename R, typename... Args> | 
 | struct FunctorTraits<OnceCallback<R(Args...)>> { | 
 |   using RunType = R(Args...); | 
 |   static constexpr bool is_method = false; | 
 |   static constexpr bool is_nullable = true; | 
 |  | 
 |   template <typename CallbackType, typename... RunArgs> | 
 |   static R Invoke(CallbackType&& callback, RunArgs&&... args) { | 
 |     DCHECK(!callback.is_null()); | 
 |     return std::forward<CallbackType>(callback).Run( | 
 |         std::forward<RunArgs>(args)...); | 
 |   } | 
 | }; | 
 |  | 
 | // For RepeatingCallbacks. | 
 | template <typename R, typename... Args> | 
 | struct FunctorTraits<RepeatingCallback<R(Args...)>> { | 
 |   using RunType = R(Args...); | 
 |   static constexpr bool is_method = false; | 
 |   static constexpr bool is_nullable = true; | 
 |  | 
 |   template <typename CallbackType, typename... RunArgs> | 
 |   static R Invoke(CallbackType&& callback, RunArgs&&... args) { | 
 |     DCHECK(!callback.is_null()); | 
 |     return std::forward<CallbackType>(callback).Run( | 
 |         std::forward<RunArgs>(args)...); | 
 |   } | 
 | }; | 
 |  | 
 | template <typename Functor> | 
 | using MakeFunctorTraits = FunctorTraits<std::decay_t<Functor>>; | 
 |  | 
 | // InvokeHelper<> | 
 | // | 
 | // There are 2 logical InvokeHelper<> specializations: normal, WeakCalls. | 
 | // | 
 | // The normal type just calls the underlying runnable. | 
 | // | 
 | // WeakCalls need special syntax that is applied to the first argument to check | 
 | // if they should no-op themselves. | 
 | template <bool is_weak_call, typename ReturnType> | 
 | struct InvokeHelper; | 
 |  | 
 | template <typename ReturnType> | 
 | struct InvokeHelper<false, ReturnType> { | 
 |   template <typename Functor, typename... RunArgs> | 
 |   static inline ReturnType MakeItSo(Functor&& functor, RunArgs&&... args) { | 
 |     using Traits = MakeFunctorTraits<Functor>; | 
 |     return Traits::Invoke(std::forward<Functor>(functor), | 
 |                           std::forward<RunArgs>(args)...); | 
 |   } | 
 | }; | 
 |  | 
 | template <typename ReturnType> | 
 | struct InvokeHelper<true, ReturnType> { | 
 |   // WeakCalls are only supported for functions with a void return type. | 
 |   // Otherwise, the function result would be undefined if the the WeakPtr<> | 
 |   // is invalidated. | 
 |   static_assert(std::is_void<ReturnType>::value, | 
 |                 "weak_ptrs can only bind to methods without return values"); | 
 |  | 
 |   template <typename Functor, typename BoundWeakPtr, typename... RunArgs> | 
 |   static inline void MakeItSo(Functor&& functor, | 
 |                               BoundWeakPtr&& weak_ptr, | 
 |                               RunArgs&&... args) { | 
 |     if (!weak_ptr) | 
 |       return; | 
 |     using Traits = MakeFunctorTraits<Functor>; | 
 |     Traits::Invoke(std::forward<Functor>(functor), | 
 |                    std::forward<BoundWeakPtr>(weak_ptr), | 
 |                    std::forward<RunArgs>(args)...); | 
 |   } | 
 | }; | 
 |  | 
 | // Invoker<> | 
 | // | 
 | // See description at the top of the file. | 
 | template <typename StorageType, typename UnboundRunType> | 
 | struct Invoker; | 
 |  | 
 | template <typename StorageType, typename R, typename... UnboundArgs> | 
 | struct Invoker<StorageType, R(UnboundArgs...)> { | 
 |   static R RunOnce(BindStateBase* base, | 
 |                    PassingTraitsType<UnboundArgs>... unbound_args) { | 
 |     // Local references to make debugger stepping easier. If in a debugger, | 
 |     // you really want to warp ahead and step through the | 
 |     // InvokeHelper<>::MakeItSo() call below. | 
 |     StorageType* storage = static_cast<StorageType*>(base); | 
 |     static constexpr size_t num_bound_args = | 
 |         std::tuple_size<decltype(storage->bound_args_)>::value; | 
 |     return RunImpl(std::move(storage->functor_), | 
 |                    std::move(storage->bound_args_), | 
 |                    std::make_index_sequence<num_bound_args>(), | 
 |                    std::forward<UnboundArgs>(unbound_args)...); | 
 |   } | 
 |  | 
 |   static R Run(BindStateBase* base, | 
 |                PassingTraitsType<UnboundArgs>... unbound_args) { | 
 |     // Local references to make debugger stepping easier. If in a debugger, | 
 |     // you really want to warp ahead and step through the | 
 |     // InvokeHelper<>::MakeItSo() call below. | 
 |     const StorageType* storage = static_cast<StorageType*>(base); | 
 |     static constexpr size_t num_bound_args = | 
 |         std::tuple_size<decltype(storage->bound_args_)>::value; | 
 |     return RunImpl(storage->functor_, storage->bound_args_, | 
 |                    std::make_index_sequence<num_bound_args>(), | 
 |                    std::forward<UnboundArgs>(unbound_args)...); | 
 |   } | 
 |  | 
 |  private: | 
 |   template <typename Functor, typename BoundArgsTuple, size_t... indices> | 
 |   static inline R RunImpl(Functor&& functor, | 
 |                           BoundArgsTuple&& bound, | 
 |                           std::index_sequence<indices...>, | 
 |                           UnboundArgs&&... unbound_args) { | 
 |     static constexpr bool is_method = MakeFunctorTraits<Functor>::is_method; | 
 |  | 
 |     using DecayedArgsTuple = std::decay_t<BoundArgsTuple>; | 
 |     static constexpr bool is_weak_call = | 
 |         IsWeakMethod<is_method, | 
 |                      std::tuple_element_t<indices, DecayedArgsTuple>...>(); | 
 |  | 
 |     return InvokeHelper<is_weak_call, R>::MakeItSo( | 
 |         std::forward<Functor>(functor), | 
 |         Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))..., | 
 |         std::forward<UnboundArgs>(unbound_args)...); | 
 |   } | 
 | }; | 
 |  | 
 | // Extracts necessary type info from Functor and BoundArgs. | 
 | // Used to implement MakeUnboundRunType, BindOnce and BindRepeating. | 
 | template <typename Functor, typename... BoundArgs> | 
 | struct BindTypeHelper { | 
 |   static constexpr size_t num_bounds = sizeof...(BoundArgs); | 
 |   using FunctorTraits = MakeFunctorTraits<Functor>; | 
 |  | 
 |   // Example: | 
 |   //   When Functor is `double (Foo::*)(int, const std::string&)`, and BoundArgs | 
 |   //   is a template pack of `Foo*` and `int16_t`: | 
 |   //    - RunType is `double(Foo*, int, const std::string&)`, | 
 |   //    - ReturnType is `double`, | 
 |   //    - RunParamsList is `TypeList<Foo*, int, const std::string&>`, | 
 |   //    - BoundParamsList is `TypeList<Foo*, int>`, | 
 |   //    - UnboundParamsList is `TypeList<const std::string&>`, | 
 |   //    - BoundArgsList is `TypeList<Foo*, int16_t>`, | 
 |   //    - UnboundRunType is `double(const std::string&)`. | 
 |   using RunType = typename FunctorTraits::RunType; | 
 |   using ReturnType = ExtractReturnType<RunType>; | 
 |  | 
 |   using RunParamsList = ExtractArgs<RunType>; | 
 |   using BoundParamsList = TakeTypeListItem<num_bounds, RunParamsList>; | 
 |   using UnboundParamsList = DropTypeListItem<num_bounds, RunParamsList>; | 
 |  | 
 |   using BoundArgsList = TypeList<BoundArgs...>; | 
 |  | 
 |   using UnboundRunType = MakeFunctionType<ReturnType, UnboundParamsList>; | 
 | }; | 
 |  | 
 | template <typename Functor> | 
 | std::enable_if_t<FunctorTraits<Functor>::is_nullable, bool> IsNull( | 
 |     const Functor& functor) { | 
 |   return !functor; | 
 | } | 
 |  | 
 | template <typename Functor> | 
 | std::enable_if_t<!FunctorTraits<Functor>::is_nullable, bool> IsNull( | 
 |     const Functor&) { | 
 |   return false; | 
 | } | 
 |  | 
 | // Used by ApplyCancellationTraits below. | 
 | template <typename Functor, typename BoundArgsTuple, size_t... indices> | 
 | bool ApplyCancellationTraitsImpl(const Functor& functor, | 
 |                                  const BoundArgsTuple& bound_args, | 
 |                                  std::index_sequence<indices...>) { | 
 |   return CallbackCancellationTraits<Functor, BoundArgsTuple>::IsCancelled( | 
 |       functor, std::get<indices>(bound_args)...); | 
 | } | 
 |  | 
 | // Relays |base| to corresponding CallbackCancellationTraits<>::Run(). Returns | 
 | // true if the callback |base| represents is canceled. | 
 | template <typename BindStateType> | 
 | bool ApplyCancellationTraits(const BindStateBase* base) { | 
 |   const BindStateType* storage = static_cast<const BindStateType*>(base); | 
 |   static constexpr size_t num_bound_args = | 
 |       std::tuple_size<decltype(storage->bound_args_)>::value; | 
 |   return ApplyCancellationTraitsImpl( | 
 |       storage->functor_, storage->bound_args_, | 
 |       std::make_index_sequence<num_bound_args>()); | 
 | }; | 
 |  | 
 | // BindState<> | 
 | // | 
 | // This stores all the state passed into Bind(). | 
 | template <typename Functor, typename... BoundArgs> | 
 | struct BindState final : BindStateBase { | 
 |   using IsCancellable = std::integral_constant< | 
 |       bool, | 
 |       CallbackCancellationTraits<Functor, | 
 |                                  std::tuple<BoundArgs...>>::is_cancellable>; | 
 |  | 
 |   template <typename ForwardFunctor, typename... ForwardBoundArgs> | 
 |   explicit BindState(BindStateBase::InvokeFuncStorage invoke_func, | 
 |                      ForwardFunctor&& functor, | 
 |                      ForwardBoundArgs&&... bound_args) | 
 |       // IsCancellable is std::false_type if | 
 |       // CallbackCancellationTraits<>::IsCancelled returns always false. | 
 |       // Otherwise, it's std::true_type. | 
 |       : BindState(IsCancellable{}, | 
 |                   invoke_func, | 
 |                   std::forward<ForwardFunctor>(functor), | 
 |                   std::forward<ForwardBoundArgs>(bound_args)...) {} | 
 |  | 
 |   Functor functor_; | 
 |   std::tuple<BoundArgs...> bound_args_; | 
 |  | 
 |  private: | 
 |   template <typename ForwardFunctor, typename... ForwardBoundArgs> | 
 |   explicit BindState(std::true_type, | 
 |                      BindStateBase::InvokeFuncStorage invoke_func, | 
 |                      ForwardFunctor&& functor, | 
 |                      ForwardBoundArgs&&... bound_args) | 
 |       : BindStateBase(invoke_func, | 
 |                       &Destroy, | 
 |                       &ApplyCancellationTraits<BindState>), | 
 |         functor_(std::forward<ForwardFunctor>(functor)), | 
 |         bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) { | 
 |     DCHECK(!IsNull(functor_)); | 
 |   } | 
 |  | 
 |   template <typename ForwardFunctor, typename... ForwardBoundArgs> | 
 |   explicit BindState(std::false_type, | 
 |                      BindStateBase::InvokeFuncStorage invoke_func, | 
 |                      ForwardFunctor&& functor, | 
 |                      ForwardBoundArgs&&... bound_args) | 
 |       : BindStateBase(invoke_func, &Destroy), | 
 |         functor_(std::forward<ForwardFunctor>(functor)), | 
 |         bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) { | 
 |     DCHECK(!IsNull(functor_)); | 
 |   } | 
 |  | 
 |   ~BindState() = default; | 
 |  | 
 |   static void Destroy(const BindStateBase* self) { | 
 |     delete static_cast<const BindState*>(self); | 
 |   } | 
 | }; | 
 |  | 
 | // Used to implement MakeBindStateType. | 
 | template <bool is_method, typename Functor, typename... BoundArgs> | 
 | struct MakeBindStateTypeImpl; | 
 |  | 
 | template <typename Functor, typename... BoundArgs> | 
 | struct MakeBindStateTypeImpl<false, Functor, BoundArgs...> { | 
 |   static_assert(!HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>::value, | 
 |                 "A parameter is a refcounted type and needs scoped_refptr."); | 
 |   using Type = BindState<std::decay_t<Functor>, std::decay_t<BoundArgs>...>; | 
 | }; | 
 |  | 
 | template <typename Functor> | 
 | struct MakeBindStateTypeImpl<true, Functor> { | 
 |   using Type = BindState<std::decay_t<Functor>>; | 
 | }; | 
 |  | 
 | template <typename Functor, typename Receiver, typename... BoundArgs> | 
 | struct MakeBindStateTypeImpl<true, Functor, Receiver, BoundArgs...> { | 
 |  private: | 
 |   using DecayedReceiver = std::decay_t<Receiver>; | 
 |  | 
 |   static_assert(!std::is_array<std::remove_reference_t<Receiver>>::value, | 
 |                 "First bound argument to a method cannot be an array."); | 
 |   static_assert( | 
 |       !std::is_pointer<DecayedReceiver>::value || | 
 |           IsRefCountedType<std::remove_pointer_t<DecayedReceiver>>::value, | 
 |       "Receivers may not be raw pointers. If using a raw pointer here is safe" | 
 |       " and has no lifetime concerns, use base::Unretained() and document why" | 
 |       " it's safe."); | 
 |   static_assert(!HasRefCountedTypeAsRawPtr<std::decay_t<BoundArgs>...>::value, | 
 |                 "A parameter is a refcounted type and needs scoped_refptr."); | 
 |  | 
 |  public: | 
 |   using Type = BindState< | 
 |       std::decay_t<Functor>, | 
 |       std::conditional_t<std::is_pointer<DecayedReceiver>::value, | 
 |                          scoped_refptr<std::remove_pointer_t<DecayedReceiver>>, | 
 |                          DecayedReceiver>, | 
 |       std::decay_t<BoundArgs>...>; | 
 | }; | 
 |  | 
 | template <typename Functor, typename... BoundArgs> | 
 | using MakeBindStateType = | 
 |     typename MakeBindStateTypeImpl<MakeFunctorTraits<Functor>::is_method, | 
 |                                    Functor, | 
 |                                    BoundArgs...>::Type; | 
 |  | 
 | }  // namespace internal | 
 |  | 
 | // An injection point to control |this| pointer behavior on a method invocation. | 
 | // If IsWeakReceiver<> is true_type for |T| and |T| is used for a receiver of a | 
 | // method, base::Bind cancels the method invocation if the receiver is tested as | 
 | // false. | 
 | // E.g. Foo::bar() is not called: | 
 | //   struct Foo : base::SupportsWeakPtr<Foo> { | 
 | //     void bar() {} | 
 | //   }; | 
 | // | 
 | //   WeakPtr<Foo> oo = nullptr; | 
 | //   base::Bind(&Foo::bar, oo).Run(); | 
 | template <typename T> | 
 | struct IsWeakReceiver : std::false_type {}; | 
 |  | 
 | template <typename T> | 
 | struct IsWeakReceiver<internal::ConstRefWrapper<T>> : IsWeakReceiver<T> {}; | 
 |  | 
 | template <typename T> | 
 | struct IsWeakReceiver<WeakPtr<T>> : std::true_type {}; | 
 |  | 
 | // An injection point to control how bound objects passed to the target | 
 | // function. BindUnwrapTraits<>::Unwrap() is called for each bound objects right | 
 | // before the target function is invoked. | 
 | template <typename> | 
 | struct BindUnwrapTraits { | 
 |   template <typename T> | 
 |   static T&& Unwrap(T&& o) { | 
 |     return std::forward<T>(o); | 
 |   } | 
 | }; | 
 |  | 
 | template <typename T> | 
 | struct BindUnwrapTraits<internal::UnretainedWrapper<T>> { | 
 |   static T* Unwrap(const internal::UnretainedWrapper<T>& o) { return o.get(); } | 
 | }; | 
 |  | 
 | template <typename T> | 
 | struct BindUnwrapTraits<internal::ConstRefWrapper<T>> { | 
 |   static const T& Unwrap(const internal::ConstRefWrapper<T>& o) { | 
 |     return o.get(); | 
 |   } | 
 | }; | 
 |  | 
 | template <typename T> | 
 | struct BindUnwrapTraits<internal::RetainedRefWrapper<T>> { | 
 |   static T* Unwrap(const internal::RetainedRefWrapper<T>& o) { return o.get(); } | 
 | }; | 
 |  | 
 | template <typename T> | 
 | struct BindUnwrapTraits<internal::OwnedWrapper<T>> { | 
 |   static T* Unwrap(const internal::OwnedWrapper<T>& o) { return o.get(); } | 
 | }; | 
 |  | 
 | template <typename T> | 
 | struct BindUnwrapTraits<internal::PassedWrapper<T>> { | 
 |   static T Unwrap(const internal::PassedWrapper<T>& o) { return o.Take(); } | 
 | }; | 
 |  | 
 | // CallbackCancellationTraits allows customization of Callback's cancellation | 
 | // semantics. By default, callbacks are not cancellable. A specialization should | 
 | // set is_cancellable = true and implement an IsCancelled() that returns if the | 
 | // callback should be cancelled. | 
 | template <typename Functor, typename BoundArgsTuple, typename SFINAE> | 
 | struct CallbackCancellationTraits { | 
 |   static constexpr bool is_cancellable = false; | 
 | }; | 
 |  | 
 | // Specialization for method bound to weak pointer receiver. | 
 | template <typename Functor, typename... BoundArgs> | 
 | struct CallbackCancellationTraits< | 
 |     Functor, | 
 |     std::tuple<BoundArgs...>, | 
 |     std::enable_if_t< | 
 |         internal::IsWeakMethod<internal::FunctorTraits<Functor>::is_method, | 
 |                                BoundArgs...>::value>> { | 
 |   static constexpr bool is_cancellable = true; | 
 |  | 
 |   template <typename Receiver, typename... Args> | 
 |   static bool IsCancelled(const Functor&, | 
 |                           const Receiver& receiver, | 
 |                           const Args&...) { | 
 |     return !receiver; | 
 |   } | 
 | }; | 
 |  | 
 | // Specialization for a nested bind. | 
 | template <typename Signature, typename... BoundArgs> | 
 | struct CallbackCancellationTraits<OnceCallback<Signature>, | 
 |                                   std::tuple<BoundArgs...>> { | 
 |   static constexpr bool is_cancellable = true; | 
 |  | 
 |   template <typename Functor> | 
 |   static bool IsCancelled(const Functor& functor, const BoundArgs&...) { | 
 |     return functor.IsCancelled(); | 
 |   } | 
 | }; | 
 |  | 
 | template <typename Signature, typename... BoundArgs> | 
 | struct CallbackCancellationTraits<RepeatingCallback<Signature>, | 
 |                                   std::tuple<BoundArgs...>> { | 
 |   static constexpr bool is_cancellable = true; | 
 |  | 
 |   template <typename Functor> | 
 |   static bool IsCancelled(const Functor& functor, const BoundArgs&...) { | 
 |     return functor.IsCancelled(); | 
 |   } | 
 | }; | 
 |  | 
 | // Returns a RunType of bound functor. | 
 | // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C). | 
 | template <typename Functor, typename... BoundArgs> | 
 | using MakeUnboundRunType = | 
 |     typename internal::BindTypeHelper<Functor, BoundArgs...>::UnboundRunType; | 
 |  | 
 | }  // namespace base | 
 |  | 
 | #endif  // BASE_BIND_INTERNAL_H_ |