/src/mozilla-central/security/sandbox/chromium/base/bind_internal.h
Line | Count | Source (jump to first uncovered line) |
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 <tuple> |
11 | | #include <type_traits> |
12 | | |
13 | | #include "base/bind_helpers.h" |
14 | | #include "base/callback_internal.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 "base/tuple.h" |
19 | | #include "build/build_config.h" |
20 | | |
21 | | namespace base { |
22 | | namespace internal { |
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 | | template <typename Callable, |
50 | | typename Signature = decltype(&Callable::operator())> |
51 | | struct ExtractCallableRunTypeImpl; |
52 | | |
53 | | template <typename Callable, typename R, typename... Args> |
54 | | struct ExtractCallableRunTypeImpl<Callable, R(Callable::*)(Args...) const> { |
55 | | using Type = R(Args...); |
56 | | }; |
57 | | |
58 | | // Evaluated to RunType of the given callable type. |
59 | | // Example: |
60 | | // auto f = [](int, char*) { return 0.1; }; |
61 | | // ExtractCallableRunType<decltype(f)> |
62 | | // is evaluated to |
63 | | // double(int, char*); |
64 | | template <typename Callable> |
65 | | using ExtractCallableRunType = |
66 | | typename ExtractCallableRunTypeImpl<Callable>::Type; |
67 | | |
68 | | // IsConvertibleToRunType<Functor> is std::true_type if |Functor| has operator() |
69 | | // and convertible to the corresponding function pointer. Otherwise, it's |
70 | | // std::false_type. |
71 | | // Example: |
72 | | // IsConvertibleToRunType<void(*)()>::value is false. |
73 | | // |
74 | | // struct Foo {}; |
75 | | // IsConvertibleToRunType<void(Foo::*)()>::value is false. |
76 | | // |
77 | | // auto f = []() {}; |
78 | | // IsConvertibleToRunType<decltype(f)>::value is true. |
79 | | // |
80 | | // int i = 0; |
81 | | // auto g = [i]() {}; |
82 | | // IsConvertibleToRunType<decltype(g)>::value is false. |
83 | | template <typename Functor, typename SFINAE = void> |
84 | | struct IsConvertibleToRunType : std::false_type {}; |
85 | | |
86 | | template <typename Callable> |
87 | | struct IsConvertibleToRunType<Callable, void_t<decltype(&Callable::operator())>> |
88 | | : std::is_convertible<Callable, ExtractCallableRunType<Callable>*> {}; |
89 | | |
90 | | // HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw |
91 | | // pointer to a RefCounted type. |
92 | | // Implementation note: This non-specialized case handles zero-arity case only. |
93 | | // Non-zero-arity cases should be handled by the specialization below. |
94 | | template <typename... Args> |
95 | | struct HasRefCountedTypeAsRawPtr : std::false_type {}; |
96 | | |
97 | | // Implementation note: Select true_type if the first parameter is a raw pointer |
98 | | // to a RefCounted type. Otherwise, skip the first parameter and check rest of |
99 | | // parameters recursively. |
100 | | template <typename T, typename... Args> |
101 | | struct HasRefCountedTypeAsRawPtr<T, Args...> |
102 | | : std::conditional<NeedsScopedRefptrButGetsRawPtr<T>::value, |
103 | | std::true_type, |
104 | | HasRefCountedTypeAsRawPtr<Args...>>::type {}; |
105 | | |
106 | | // ForceVoidReturn<> |
107 | | // |
108 | | // Set of templates that support forcing the function return type to void. |
109 | | template <typename Sig> |
110 | | struct ForceVoidReturn; |
111 | | |
112 | | template <typename R, typename... Args> |
113 | | struct ForceVoidReturn<R(Args...)> { |
114 | | using RunType = void(Args...); |
115 | | }; |
116 | | |
117 | | // FunctorTraits<> |
118 | | // |
119 | | // See description at top of file. |
120 | | template <typename Functor, typename SFINAE> |
121 | | struct FunctorTraits; |
122 | | |
123 | | // For a callable type that is convertible to the corresponding function type. |
124 | | // This specialization is intended to allow binding captureless lambdas by |
125 | | // base::Bind(), based on the fact that captureless lambdas can be convertible |
126 | | // to the function type while capturing lambdas can't. |
127 | | template <typename Functor> |
128 | | struct FunctorTraits< |
129 | | Functor, |
130 | | typename std::enable_if<IsConvertibleToRunType<Functor>::value>::type> { |
131 | | using RunType = ExtractCallableRunType<Functor>; |
132 | | static constexpr bool is_method = false; |
133 | | static constexpr bool is_nullable = false; |
134 | | |
135 | | template <typename... RunArgs> |
136 | | static ExtractReturnType<RunType> |
137 | | Invoke(const Functor& functor, RunArgs&&... args) { |
138 | | return functor(std::forward<RunArgs>(args)...); |
139 | | } |
140 | | }; |
141 | | |
142 | | // For functions. |
143 | | template <typename R, typename... Args> |
144 | | struct FunctorTraits<R (*)(Args...)> { |
145 | | using RunType = R(Args...); |
146 | | static constexpr bool is_method = false; |
147 | | static constexpr bool is_nullable = true; |
148 | | |
149 | | template <typename... RunArgs> |
150 | 0 | static R Invoke(R (*function)(Args...), RunArgs&&... args) { |
151 | 0 | return function(std::forward<RunArgs>(args)...); |
152 | 0 | } |
153 | | }; |
154 | | |
155 | | #if defined(OS_WIN) && !defined(ARCH_CPU_X86_64) |
156 | | |
157 | | // For functions. |
158 | | template <typename R, typename... Args> |
159 | | struct FunctorTraits<R(__stdcall*)(Args...)> { |
160 | | using RunType = R(Args...); |
161 | | static constexpr bool is_method = false; |
162 | | static constexpr bool is_nullable = true; |
163 | | |
164 | | template <typename... RunArgs> |
165 | | static R Invoke(R(__stdcall* function)(Args...), RunArgs&&... args) { |
166 | | return function(std::forward<RunArgs>(args)...); |
167 | | } |
168 | | }; |
169 | | |
170 | | // For functions. |
171 | | template <typename R, typename... Args> |
172 | | struct FunctorTraits<R(__fastcall*)(Args...)> { |
173 | | using RunType = R(Args...); |
174 | | static constexpr bool is_method = false; |
175 | | static constexpr bool is_nullable = true; |
176 | | |
177 | | template <typename... RunArgs> |
178 | | static R Invoke(R(__fastcall* function)(Args...), RunArgs&&... args) { |
179 | | return function(std::forward<RunArgs>(args)...); |
180 | | } |
181 | | }; |
182 | | |
183 | | #endif // defined(OS_WIN) && !defined(ARCH_CPU_X86_64) |
184 | | |
185 | | // For methods. |
186 | | template <typename R, typename Receiver, typename... Args> |
187 | | struct FunctorTraits<R (Receiver::*)(Args...)> { |
188 | | using RunType = R(Receiver*, Args...); |
189 | | static constexpr bool is_method = true; |
190 | | static constexpr bool is_nullable = true; |
191 | | |
192 | | template <typename ReceiverPtr, typename... RunArgs> |
193 | | static R Invoke(R (Receiver::*method)(Args...), |
194 | | ReceiverPtr&& receiver_ptr, |
195 | | RunArgs&&... args) { |
196 | | return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...); |
197 | | } |
198 | | }; |
199 | | |
200 | | // For const methods. |
201 | | template <typename R, typename Receiver, typename... Args> |
202 | | struct FunctorTraits<R (Receiver::*)(Args...) const> { |
203 | | using RunType = R(const Receiver*, Args...); |
204 | | static constexpr bool is_method = true; |
205 | | static constexpr bool is_nullable = true; |
206 | | |
207 | | template <typename ReceiverPtr, typename... RunArgs> |
208 | | static R Invoke(R (Receiver::*method)(Args...) const, |
209 | | ReceiverPtr&& receiver_ptr, |
210 | | RunArgs&&... args) { |
211 | | return ((*receiver_ptr).*method)(std::forward<RunArgs>(args)...); |
212 | | } |
213 | | }; |
214 | | |
215 | | // For IgnoreResults. |
216 | | template <typename T> |
217 | | struct FunctorTraits<IgnoreResultHelper<T>> : FunctorTraits<T> { |
218 | | using RunType = |
219 | | typename ForceVoidReturn<typename FunctorTraits<T>::RunType>::RunType; |
220 | | |
221 | | template <typename IgnoreResultType, typename... RunArgs> |
222 | | static void Invoke(IgnoreResultType&& ignore_result_helper, |
223 | | RunArgs&&... args) { |
224 | | FunctorTraits<T>::Invoke( |
225 | | std::forward<IgnoreResultType>(ignore_result_helper).functor_, |
226 | | std::forward<RunArgs>(args)...); |
227 | | } |
228 | | }; |
229 | | |
230 | | // For OnceCallbacks. |
231 | | template <typename R, typename... Args> |
232 | | struct FunctorTraits<OnceCallback<R(Args...)>> { |
233 | | using RunType = R(Args...); |
234 | | static constexpr bool is_method = false; |
235 | | static constexpr bool is_nullable = true; |
236 | | |
237 | | template <typename CallbackType, typename... RunArgs> |
238 | | static R Invoke(CallbackType&& callback, RunArgs&&... args) { |
239 | | DCHECK(!callback.is_null()); |
240 | | return std::forward<CallbackType>(callback).Run( |
241 | | std::forward<RunArgs>(args)...); |
242 | | } |
243 | | }; |
244 | | |
245 | | // For RepeatingCallbacks. |
246 | | template <typename R, typename... Args> |
247 | | struct FunctorTraits<RepeatingCallback<R(Args...)>> { |
248 | | using RunType = R(Args...); |
249 | | static constexpr bool is_method = false; |
250 | | static constexpr bool is_nullable = true; |
251 | | |
252 | | template <typename CallbackType, typename... RunArgs> |
253 | | static R Invoke(CallbackType&& callback, RunArgs&&... args) { |
254 | | DCHECK(!callback.is_null()); |
255 | | return std::forward<CallbackType>(callback).Run( |
256 | | std::forward<RunArgs>(args)...); |
257 | | } |
258 | | }; |
259 | | |
260 | | template <typename Functor> |
261 | | using MakeFunctorTraits = FunctorTraits<typename std::decay<Functor>::type>; |
262 | | |
263 | | // InvokeHelper<> |
264 | | // |
265 | | // There are 2 logical InvokeHelper<> specializations: normal, WeakCalls. |
266 | | // |
267 | | // The normal type just calls the underlying runnable. |
268 | | // |
269 | | // WeakCalls need special syntax that is applied to the first argument to check |
270 | | // if they should no-op themselves. |
271 | | template <bool is_weak_call, typename ReturnType> |
272 | | struct InvokeHelper; |
273 | | |
274 | | template <typename ReturnType> |
275 | | struct InvokeHelper<false, ReturnType> { |
276 | | template <typename Functor, typename... RunArgs> |
277 | 0 | static inline ReturnType MakeItSo(Functor&& functor, RunArgs&&... args) { |
278 | 0 | using Traits = MakeFunctorTraits<Functor>; |
279 | 0 | return Traits::Invoke(std::forward<Functor>(functor), |
280 | 0 | std::forward<RunArgs>(args)...); |
281 | 0 | } |
282 | | }; |
283 | | |
284 | | template <typename ReturnType> |
285 | | struct InvokeHelper<true, ReturnType> { |
286 | | // WeakCalls are only supported for functions with a void return type. |
287 | | // Otherwise, the function result would be undefined if the the WeakPtr<> |
288 | | // is invalidated. |
289 | | static_assert(std::is_void<ReturnType>::value, |
290 | | "weak_ptrs can only bind to methods without return values"); |
291 | | |
292 | | template <typename Functor, typename BoundWeakPtr, typename... RunArgs> |
293 | | static inline void MakeItSo(Functor&& functor, |
294 | | BoundWeakPtr&& weak_ptr, |
295 | | RunArgs&&... args) { |
296 | | if (!weak_ptr) |
297 | | return; |
298 | | using Traits = MakeFunctorTraits<Functor>; |
299 | | Traits::Invoke(std::forward<Functor>(functor), |
300 | | std::forward<BoundWeakPtr>(weak_ptr), |
301 | | std::forward<RunArgs>(args)...); |
302 | | } |
303 | | }; |
304 | | |
305 | | // Invoker<> |
306 | | // |
307 | | // See description at the top of the file. |
308 | | template <typename StorageType, typename UnboundRunType> |
309 | | struct Invoker; |
310 | | |
311 | | template <typename StorageType, typename R, typename... UnboundArgs> |
312 | | struct Invoker<StorageType, R(UnboundArgs...)> { |
313 | | static R RunOnce(BindStateBase* base, UnboundArgs&&... unbound_args) { |
314 | | // Local references to make debugger stepping easier. If in a debugger, |
315 | | // you really want to warp ahead and step through the |
316 | | // InvokeHelper<>::MakeItSo() call below. |
317 | | StorageType* storage = static_cast<StorageType*>(base); |
318 | | static constexpr size_t num_bound_args = |
319 | | std::tuple_size<decltype(storage->bound_args_)>::value; |
320 | | return RunImpl(std::move(storage->functor_), |
321 | | std::move(storage->bound_args_), |
322 | | MakeIndexSequence<num_bound_args>(), |
323 | | std::forward<UnboundArgs>(unbound_args)...); |
324 | | } |
325 | | |
326 | 0 | static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) { |
327 | 0 | // Local references to make debugger stepping easier. If in a debugger, |
328 | 0 | // you really want to warp ahead and step through the |
329 | 0 | // InvokeHelper<>::MakeItSo() call below. |
330 | 0 | const StorageType* storage = static_cast<StorageType*>(base); |
331 | 0 | static constexpr size_t num_bound_args = |
332 | 0 | std::tuple_size<decltype(storage->bound_args_)>::value; |
333 | 0 | return RunImpl(storage->functor_, storage->bound_args_, |
334 | 0 | MakeIndexSequence<num_bound_args>(), |
335 | 0 | std::forward<UnboundArgs>(unbound_args)...); |
336 | 0 | } |
337 | | |
338 | | private: |
339 | | template <typename Functor, typename BoundArgsTuple, size_t... indices> |
340 | | static inline R RunImpl(Functor&& functor, |
341 | | BoundArgsTuple&& bound, |
342 | | IndexSequence<indices...>, |
343 | 0 | UnboundArgs&&... unbound_args) { |
344 | 0 | static constexpr bool is_method = MakeFunctorTraits<Functor>::is_method; |
345 | 0 |
|
346 | 0 | using DecayedArgsTuple = typename std::decay<BoundArgsTuple>::type; |
347 | 0 | static constexpr bool is_weak_call = |
348 | 0 | IsWeakMethod<is_method, |
349 | 0 | typename std::tuple_element< |
350 | 0 | indices, |
351 | 0 | DecayedArgsTuple>::type...>::value; |
352 | 0 |
|
353 | 0 | return InvokeHelper<is_weak_call, R>::MakeItSo( |
354 | 0 | std::forward<Functor>(functor), |
355 | 0 | Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))..., |
356 | 0 | std::forward<UnboundArgs>(unbound_args)...); |
357 | 0 | } |
358 | | }; |
359 | | |
360 | | // Extracts necessary type info from Functor and BoundArgs. |
361 | | // Used to implement MakeUnboundRunType, BindOnce and BindRepeating. |
362 | | template <typename Functor, typename... BoundArgs> |
363 | | struct BindTypeHelper { |
364 | | static constexpr size_t num_bounds = sizeof...(BoundArgs); |
365 | | using FunctorTraits = MakeFunctorTraits<Functor>; |
366 | | |
367 | | // Example: |
368 | | // When Functor is `double (Foo::*)(int, const std::string&)`, and BoundArgs |
369 | | // is a template pack of `Foo*` and `int16_t`: |
370 | | // - RunType is `double(Foo*, int, const std::string&)`, |
371 | | // - ReturnType is `double`, |
372 | | // - RunParamsList is `TypeList<Foo*, int, const std::string&>`, |
373 | | // - BoundParamsList is `TypeList<Foo*, int>`, |
374 | | // - UnboundParamsList is `TypeList<const std::string&>`, |
375 | | // - BoundArgsList is `TypeList<Foo*, int16_t>`, |
376 | | // - UnboundRunType is `double(const std::string&)`. |
377 | | using RunType = typename FunctorTraits::RunType; |
378 | | using ReturnType = ExtractReturnType<RunType>; |
379 | | |
380 | | using RunParamsList = ExtractArgs<RunType>; |
381 | | using BoundParamsList = TakeTypeListItem<num_bounds, RunParamsList>; |
382 | | using UnboundParamsList = DropTypeListItem<num_bounds, RunParamsList>; |
383 | | |
384 | | using BoundArgsList = TypeList<BoundArgs...>; |
385 | | |
386 | | using UnboundRunType = MakeFunctionType<ReturnType, UnboundParamsList>; |
387 | | }; |
388 | | |
389 | | template <typename Functor> |
390 | | typename std::enable_if<FunctorTraits<Functor>::is_nullable, bool>::type |
391 | 0 | IsNull(const Functor& functor) { |
392 | 0 | return !functor; |
393 | 0 | } |
394 | | |
395 | | template <typename Functor> |
396 | | typename std::enable_if<!FunctorTraits<Functor>::is_nullable, bool>::type |
397 | | IsNull(const Functor&) { |
398 | | return false; |
399 | | } |
400 | | |
401 | | // Used by ApplyCancellationTraits below. |
402 | | template <typename Functor, typename BoundArgsTuple, size_t... indices> |
403 | | bool ApplyCancellationTraitsImpl(const Functor& functor, |
404 | | const BoundArgsTuple& bound_args, |
405 | | IndexSequence<indices...>) { |
406 | | return CallbackCancellationTraits<Functor, BoundArgsTuple>::IsCancelled( |
407 | | functor, std::get<indices>(bound_args)...); |
408 | | } |
409 | | |
410 | | // Relays |base| to corresponding CallbackCancellationTraits<>::Run(). Returns |
411 | | // true if the callback |base| represents is canceled. |
412 | | template <typename BindStateType> |
413 | | bool ApplyCancellationTraits(const BindStateBase* base) { |
414 | | const BindStateType* storage = static_cast<const BindStateType*>(base); |
415 | | static constexpr size_t num_bound_args = |
416 | | std::tuple_size<decltype(storage->bound_args_)>::value; |
417 | | return ApplyCancellationTraitsImpl( |
418 | | storage->functor_, storage->bound_args_, |
419 | | MakeIndexSequence<num_bound_args>()); |
420 | | }; |
421 | | |
422 | | // BindState<> |
423 | | // |
424 | | // This stores all the state passed into Bind(). |
425 | | template <typename Functor, typename... BoundArgs> |
426 | | struct BindState final : BindStateBase { |
427 | | using IsCancellable = std::integral_constant< |
428 | | bool, |
429 | | CallbackCancellationTraits<Functor, |
430 | | std::tuple<BoundArgs...>>::is_cancellable>; |
431 | | |
432 | | template <typename ForwardFunctor, typename... ForwardBoundArgs> |
433 | | explicit BindState(BindStateBase::InvokeFuncStorage invoke_func, |
434 | | ForwardFunctor&& functor, |
435 | | ForwardBoundArgs&&... bound_args) |
436 | | // IsCancellable is std::false_type if |
437 | | // CallbackCancellationTraits<>::IsCancelled returns always false. |
438 | | // Otherwise, it's std::true_type. |
439 | | : BindState(IsCancellable{}, |
440 | | invoke_func, |
441 | | std::forward<ForwardFunctor>(functor), |
442 | 0 | std::forward<ForwardBoundArgs>(bound_args)...) { |
443 | 0 | } |
444 | | |
445 | | Functor functor_; |
446 | | std::tuple<BoundArgs...> bound_args_; |
447 | | |
448 | | private: |
449 | | template <typename ForwardFunctor, typename... ForwardBoundArgs> |
450 | | explicit BindState(std::true_type, |
451 | | BindStateBase::InvokeFuncStorage invoke_func, |
452 | | ForwardFunctor&& functor, |
453 | | ForwardBoundArgs&&... bound_args) |
454 | | : BindStateBase(invoke_func, |
455 | | &Destroy, |
456 | | &ApplyCancellationTraits<BindState>), |
457 | | functor_(std::forward<ForwardFunctor>(functor)), |
458 | | bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) { |
459 | | DCHECK(!IsNull(functor_)); |
460 | | } |
461 | | |
462 | | template <typename ForwardFunctor, typename... ForwardBoundArgs> |
463 | | explicit BindState(std::false_type, |
464 | | BindStateBase::InvokeFuncStorage invoke_func, |
465 | | ForwardFunctor&& functor, |
466 | | ForwardBoundArgs&&... bound_args) |
467 | | : BindStateBase(invoke_func, &Destroy), |
468 | | functor_(std::forward<ForwardFunctor>(functor)), |
469 | 0 | bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) { |
470 | 0 | DCHECK(!IsNull(functor_)); |
471 | 0 | } |
472 | | |
473 | | ~BindState() {} |
474 | | |
475 | 0 | static void Destroy(const BindStateBase* self) { |
476 | 0 | delete static_cast<const BindState*>(self); |
477 | 0 | } |
478 | | }; |
479 | | |
480 | | // Used to implement MakeBindStateType. |
481 | | template <bool is_method, typename Functor, typename... BoundArgs> |
482 | | struct MakeBindStateTypeImpl; |
483 | | |
484 | | template <typename Functor, typename... BoundArgs> |
485 | | struct MakeBindStateTypeImpl<false, Functor, BoundArgs...> { |
486 | | static_assert(!HasRefCountedTypeAsRawPtr< |
487 | | typename std::decay<BoundArgs>::type...>::value, |
488 | | "A parameter is a refcounted type and needs scoped_refptr."); |
489 | | using Type = BindState<typename std::decay<Functor>::type, |
490 | | typename std::decay<BoundArgs>::type...>; |
491 | | }; |
492 | | |
493 | | template <typename Functor> |
494 | | struct MakeBindStateTypeImpl<true, Functor> { |
495 | | using Type = BindState<typename std::decay<Functor>::type>; |
496 | | }; |
497 | | |
498 | | template <typename Functor, typename Receiver, typename... BoundArgs> |
499 | | struct MakeBindStateTypeImpl<true, Functor, Receiver, BoundArgs...> { |
500 | | static_assert( |
501 | | !std::is_array<typename std::remove_reference<Receiver>::type>::value, |
502 | | "First bound argument to a method cannot be an array."); |
503 | | static_assert(!HasRefCountedTypeAsRawPtr< |
504 | | typename std::decay<BoundArgs>::type...>::value, |
505 | | "A parameter is a refcounted type and needs scoped_refptr."); |
506 | | |
507 | | private: |
508 | | using DecayedReceiver = typename std::decay<Receiver>::type; |
509 | | |
510 | | public: |
511 | | using Type = BindState< |
512 | | typename std::decay<Functor>::type, |
513 | | typename std::conditional< |
514 | | std::is_pointer<DecayedReceiver>::value, |
515 | | scoped_refptr<typename std::remove_pointer<DecayedReceiver>::type>, |
516 | | DecayedReceiver>::type, |
517 | | typename std::decay<BoundArgs>::type...>; |
518 | | }; |
519 | | |
520 | | template <typename Functor, typename... BoundArgs> |
521 | | using MakeBindStateType = |
522 | | typename MakeBindStateTypeImpl<MakeFunctorTraits<Functor>::is_method, |
523 | | Functor, |
524 | | BoundArgs...>::Type; |
525 | | |
526 | | } // namespace internal |
527 | | |
528 | | // Returns a RunType of bound functor. |
529 | | // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C). |
530 | | template <typename Functor, typename... BoundArgs> |
531 | | using MakeUnboundRunType = |
532 | | typename internal::BindTypeHelper<Functor, BoundArgs...>::UnboundRunType; |
533 | | |
534 | | } // namespace base |
535 | | |
536 | | #endif // BASE_BIND_INTERNAL_H_ |