• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
UnretainedWrapper(T * o)68   explicit UnretainedWrapper(T* o) : ptr_(o) {}
get()69   T* get() const { return ptr_; }
70 
71  private:
72   T* ptr_;
73 };
74 
75 template <typename T>
76 class ConstRefWrapper {
77  public:
ConstRefWrapper(const T & o)78   explicit ConstRefWrapper(const T& o) : ptr_(&o) {}
get()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:
RetainedRefWrapper(T * o)88   explicit RetainedRefWrapper(T* o) : ptr_(o) {}
RetainedRefWrapper(scoped_refptr<T> o)89   explicit RetainedRefWrapper(scoped_refptr<T> o) : ptr_(std::move(o)) {}
get()90   T* get() const { return ptr_.get(); }
91 
92  private:
93   scoped_refptr<T> ptr_;
94 };
95 
96 template <typename T>
97 struct IgnoreResultHelper {
IgnoreResultHelperIgnoreResultHelper98   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:
OwnedWrapper(T * o)114   explicit OwnedWrapper(T* o) : ptr_(o) {}
~OwnedWrapper()115   ~OwnedWrapper() { delete ptr_; }
get()116   T* get() const { return ptr_; }
OwnedWrapper(OwnedWrapper && other)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:
PassedWrapper(T && scoper)152   explicit PassedWrapper(T&& scoper)
153       : is_valid_(true), scoper_(std::move(scoper)) {}
PassedWrapper(PassedWrapper && other)154   PassedWrapper(PassedWrapper&& other)
155       : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {}
Take()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>
decltype(auto)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