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