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.
5 #ifndef BASE_BIND_INTERNAL_H_
6 #define BASE_BIND_INTERNAL_H_
8 #include "base/bind_helpers.h"
9 #include "base/callback_internal.h"
10 #include "base/memory/raw_scoped_refptr_mismatch_checker.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/template_util.h"
13 #include "base/tuple.h"
14 #include "build/build_config.h"
17 #include "base/bind_internal_win.h"
23 // See base/callback.h for user documentation.
27 // Runnable -- A type (really a type class) that has a single Run() method
28 // and a RunType typedef that corresponds to the type of Run().
29 // A Runnable can declare that it should treated like a method
30 // call by including a typedef named IsMethod. The value of
31 // this typedef is NOT inspected, only the existence. When a
32 // Runnable declares itself a method, Bind() will enforce special
33 // refcounting + WeakPtr handling semantics for the first
34 // parameter which is expected to be an object.
35 // Functor -- A copyable type representing something that should be called.
36 // All function pointers, Callback<>, and Runnables are functors
37 // even if the invocation syntax differs.
38 // RunType -- A function type (as opposed to function _pointer_ type) for
39 // a Run() function. Usually just a convenience typedef.
40 // (Bound)ArgsType -- A function type that is being (ab)used to store the
41 // types of set of arguments. The "return" type is always
42 // void here. We use this hack so that we do not need
43 // a new type name for each arity of type. (eg.,
44 // BindState1, BindState2). This makes forward
45 // declarations and friending much much easier.
48 // RunnableAdapter<> -- Wraps the various "function" pointer types into an
49 // object that adheres to the Runnable interface.
50 // ForceVoidReturn<> -- Helper class for translating function signatures to
51 // equivalent forms with a "void" return type.
52 // FunctorTraits<> -- Type traits used determine the correct RunType and
53 // RunnableType for a Functor. This is where function
54 // signature adapters are applied.
55 // MakeRunnable<> -- Takes a Functor and returns an object in the Runnable
56 // type class that represents the underlying Functor.
57 // There are |O(1)| MakeRunnable types.
58 // InvokeHelper<> -- Take a Runnable + arguments and actully invokes it.
59 // Handle the differing syntaxes needed for WeakPtr<>
60 // support, and for ignoring return values. This is separate
61 // from Invoker to avoid creating multiple version of
63 // Invoker<> -- Unwraps the curried parameters and executes the Runnable.
64 // BindState<> -- Stores the curried parameters, and is the main entry point
65 // into the Bind() system, doing most of the type resolution.
66 // There are ARITY BindState types.
68 // HasNonConstReferenceParam selects true_type when any of the parameters in
69 // |Sig| is a non-const reference.
70 // Implementation note: This non-specialized case handles zero-arity case only.
71 // Non-zero-arity cases should be handled by the specialization below.
72 template <typename Sig
>
73 struct HasNonConstReferenceParam
: false_type
{};
75 // Implementation note: Select true_type if the first parameter is a non-const
76 // reference. Otherwise, skip the first parameter and check rest of parameters
78 template <typename R
, typename T
, typename
... Args
>
79 struct HasNonConstReferenceParam
<R(T
, Args
...)>
80 : SelectType
<is_non_const_reference
<T
>::value
,
82 HasNonConstReferenceParam
<R(Args
...)>>::Type
{};
84 // HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw
85 // pointer to a RefCounted type.
86 // Implementation note: This non-specialized case handles zero-arity case only.
87 // Non-zero-arity cases should be handled by the specialization below.
88 template <typename
... Args
>
89 struct HasRefCountedTypeAsRawPtr
: false_type
{};
91 // Implementation note: Select true_type if the first parameter is a raw pointer
92 // to a RefCounted type. Otherwise, skip the first parameter and check rest of
93 // parameters recursively.
94 template <typename T
, typename
... Args
>
95 struct HasRefCountedTypeAsRawPtr
<T
, Args
...>
96 : SelectType
<NeedsScopedRefptrButGetsRawPtr
<T
>::value
,
98 HasRefCountedTypeAsRawPtr
<Args
...>>::Type
{};
100 // BindsArrayToFirstArg selects true_type when |is_method| is true and the first
101 // item of |Args| is an array type.
102 // Implementation note: This non-specialized case handles !is_method case and
103 // zero-arity case only. Other cases should be handled by the specialization
105 template <bool is_method
, typename
... Args
>
106 struct BindsArrayToFirstArg
: false_type
{};
108 template <typename T
, typename
... Args
>
109 struct BindsArrayToFirstArg
<true, T
, Args
...> : is_array
<T
> {};
111 // HasRefCountedParamAsRawPtr is the same to HasRefCountedTypeAsRawPtr except
112 // when |is_method| is true HasRefCountedParamAsRawPtr skips the first argument.
113 // Implementation note: This non-specialized case handles !is_method case and
114 // zero-arity case only. Other cases should be handled by the specialization
116 template <bool is_method
, typename
... Args
>
117 struct HasRefCountedParamAsRawPtr
: HasRefCountedTypeAsRawPtr
<Args
...> {};
119 template <typename T
, typename
... Args
>
120 struct HasRefCountedParamAsRawPtr
<true, T
, Args
...>
121 : HasRefCountedTypeAsRawPtr
<Args
...> {};
125 // The RunnableAdapter<> templates provide a uniform interface for invoking
126 // a function pointer, method pointer, or const method pointer. The adapter
127 // exposes a Run() method with an appropriate signature. Using this wrapper
128 // allows for writing code that supports all three pointer types without
129 // undue repetition. Without it, a lot of code would need to be repeated 3
132 // For method pointers and const method pointers the first argument to Run()
133 // is considered to be the received of the method. This is similar to STL's
136 // This class also exposes a RunType typedef that is the function type of the
139 // If and only if the wrapper contains a method or const method pointer, an
140 // IsMethod typedef is exposed. The existence of this typedef (NOT the value)
141 // marks that the wrapper should be considered a method wrapper.
143 template <typename Functor
>
144 class RunnableAdapter
;
147 template <typename R
, typename
... Args
>
148 class RunnableAdapter
<R(*)(Args
...)> {
150 typedef R (RunType
)(Args
...);
152 explicit RunnableAdapter(R(*function
)(Args
...))
153 : function_(function
) {
156 R
Run(typename CallbackParamTraits
<Args
>::ForwardType
... args
) {
157 return function_(CallbackForward(args
)...);
161 R (*function_
)(Args
...);
165 template <typename R
, typename T
, typename
... Args
>
166 class RunnableAdapter
<R(T::*)(Args
...)> {
168 typedef R (RunType
)(T
*, Args
...);
169 typedef true_type IsMethod
;
171 explicit RunnableAdapter(R(T::*method
)(Args
...))
175 R
Run(T
* object
, typename CallbackParamTraits
<Args
>::ForwardType
... args
) {
176 return (object
->*method_
)(CallbackForward(args
)...);
180 R (T::*method_
)(Args
...);
184 template <typename R
, typename T
, typename
... Args
>
185 class RunnableAdapter
<R(T::*)(Args
...) const> {
187 typedef R (RunType
)(const T
*, Args
...);
188 typedef true_type IsMethod
;
190 explicit RunnableAdapter(R(T::*method
)(Args
...) const)
194 R
Run(const T
* object
,
195 typename CallbackParamTraits
<Args
>::ForwardType
... args
) {
196 return (object
->*method_
)(CallbackForward(args
)...);
200 R (T::*method_
)(Args
...) const;
206 // Set of templates that support forcing the function return type to void.
207 template <typename Sig
>
208 struct ForceVoidReturn
;
210 template <typename R
, typename
... Args
>
211 struct ForceVoidReturn
<R(Args
...)> {
212 typedef void(RunType
)(Args
...);
218 // See description at top of file.
219 template <typename T
>
220 struct FunctorTraits
{
221 typedef RunnableAdapter
<T
> RunnableType
;
222 typedef typename
RunnableType::RunType RunType
;
225 template <typename T
>
226 struct FunctorTraits
<IgnoreResultHelper
<T
>> {
227 typedef typename FunctorTraits
<T
>::RunnableType RunnableType
;
228 typedef typename ForceVoidReturn
<
229 typename
RunnableType::RunType
>::RunType RunType
;
232 template <typename T
>
233 struct FunctorTraits
<Callback
<T
>> {
234 typedef Callback
<T
> RunnableType
;
235 typedef typename Callback
<T
>::RunType RunType
;
241 // Converts a passed in functor to a RunnableType using type inference.
243 template <typename T
>
244 typename FunctorTraits
<T
>::RunnableType
MakeRunnable(const T
& t
) {
245 return RunnableAdapter
<T
>(t
);
248 template <typename T
>
249 typename FunctorTraits
<T
>::RunnableType
250 MakeRunnable(const IgnoreResultHelper
<T
>& t
) {
251 return MakeRunnable(t
.functor_
);
254 template <typename T
>
255 const typename FunctorTraits
<Callback
<T
>>::RunnableType
&
256 MakeRunnable(const Callback
<T
>& t
) {
257 DCHECK(!t
.is_null());
264 // There are 3 logical InvokeHelper<> specializations: normal, void-return,
267 // The normal type just calls the underlying runnable.
269 // We need a InvokeHelper to handle void return types in order to support
270 // IgnoreResult(). Normally, if the Runnable's RunType had a void return,
271 // the template system would just accept "return functor.Run()" ignoring
272 // the fact that a void function is being used with return. This piece of
273 // sugar breaks though when the Runnable's RunType is not void. Thus, we
274 // need a partial specialization to change the syntax to drop the "return"
275 // from the invocation call.
277 // WeakCalls similarly need special syntax that is applied to the first
278 // argument to check if they should no-op themselves.
279 template <bool IsWeakCall
, typename ReturnType
, typename Runnable
,
283 template <typename ReturnType
, typename Runnable
, typename
... Args
>
284 struct InvokeHelper
<false, ReturnType
, Runnable
, TypeList
<Args
...>> {
285 static ReturnType
MakeItSo(Runnable runnable
, Args
... args
) {
286 return runnable
.Run(CallbackForward(args
)...);
290 template <typename Runnable
, typename
... Args
>
291 struct InvokeHelper
<false, void, Runnable
, TypeList
<Args
...>> {
292 static void MakeItSo(Runnable runnable
, Args
... args
) {
293 runnable
.Run(CallbackForward(args
)...);
297 template <typename Runnable
, typename BoundWeakPtr
, typename
... Args
>
298 struct InvokeHelper
<true, void, Runnable
, TypeList
<BoundWeakPtr
, Args
...>> {
299 static void MakeItSo(Runnable runnable
, BoundWeakPtr weak_ptr
, Args
... args
) {
300 if (!weak_ptr
.get()) {
303 runnable
.Run(weak_ptr
.get(), CallbackForward(args
)...);
307 #if !defined(_MSC_VER)
309 template <typename ReturnType
, typename Runnable
, typename ArgsType
>
310 struct InvokeHelper
<true, ReturnType
, Runnable
, ArgsType
> {
311 // WeakCalls are only supported for functions with a void return type.
312 // Otherwise, the function result would be undefined if the the WeakPtr<>
314 COMPILE_ASSERT(is_void
<ReturnType
>::value
,
315 weak_ptrs_can_only_bind_to_methods_without_return_values
);
322 // See description at the top of the file.
323 template <typename BoundIndices
,
324 typename StorageType
, typename Unwrappers
,
325 typename InvokeHelperType
, typename UnboundForwardRunType
>
328 template <size_t... bound_indices
,
329 typename StorageType
,
330 typename
... Unwrappers
,
331 typename InvokeHelperType
,
333 typename
... UnboundForwardArgs
>
334 struct Invoker
<IndexSequence
<bound_indices
...>,
335 StorageType
, TypeList
<Unwrappers
...>,
336 InvokeHelperType
, R(UnboundForwardArgs
...)> {
337 static R
Run(BindStateBase
* base
,
338 UnboundForwardArgs
... unbound_args
) {
339 StorageType
* storage
= static_cast<StorageType
*>(base
);
340 // Local references to make debugger stepping easier. If in a debugger,
341 // you really want to warp ahead and step through the
342 // InvokeHelper<>::MakeItSo() call below.
343 return InvokeHelperType::MakeItSo(
345 Unwrappers::Unwrap(get
<bound_indices
>(storage
->bound_args_
))...,
346 CallbackForward(unbound_args
)...);
353 // This stores all the state passed into Bind() and is also where most
354 // of the template resolution magic occurs.
356 // Runnable is the functor we are binding arguments to.
357 // RunType is type of the Run() function that the Invoker<> should use.
358 // Normally, this is the same as the RunType of the Runnable, but it can
359 // be different if an adapter like IgnoreResult() has been used.
361 // BoundArgsType contains the storage type for all the bound arguments by
362 // (ab)using a function type.
363 template <typename Runnable
, typename RunType
, typename BoundArgList
>
366 template <typename Runnable
,
367 typename R
, typename
... Args
,
368 typename
... BoundArgs
>
369 struct BindState
<Runnable
, R(Args
...), TypeList
<BoundArgs
...>>
370 : public BindStateBase
{
372 using StorageType
= BindState
<Runnable
, R(Args
...), TypeList
<BoundArgs
...>>;
373 using RunnableType
= Runnable
;
375 // true_type if Runnable is a method invocation and the first bound argument
378 IsWeakMethod
<HasIsMethodTag
<Runnable
>::value
, BoundArgs
...>;
380 using BoundIndices
= MakeIndexSequence
<sizeof...(BoundArgs
)>;
381 using Unwrappers
= TypeList
<UnwrapTraits
<BoundArgs
>...>;
382 using UnboundForwardArgs
= DropTypeListItem
<
383 sizeof...(BoundArgs
),
384 TypeList
<typename CallbackParamTraits
<Args
>::ForwardType
...>>;
385 using UnboundForwardRunType
= MakeFunctionType
<R
, UnboundForwardArgs
>;
387 using InvokeHelperArgs
= ConcatTypeLists
<
388 TypeList
<typename UnwrapTraits
<BoundArgs
>::ForwardType
...>,
390 using InvokeHelperType
=
391 InvokeHelper
<IsWeakCall::value
, R
, Runnable
, InvokeHelperArgs
>;
393 using UnboundArgs
= DropTypeListItem
<sizeof...(BoundArgs
), TypeList
<Args
...>>;
396 using InvokerType
= Invoker
<BoundIndices
, StorageType
, Unwrappers
,
397 InvokeHelperType
, UnboundForwardRunType
>;
398 using UnboundRunType
= MakeFunctionType
<R
, UnboundArgs
>;
400 BindState(const Runnable
& runnable
, const BoundArgs
&... bound_args
)
401 : runnable_(runnable
), ref_(bound_args
...), bound_args_(bound_args
...) {}
403 RunnableType runnable_
;
404 MaybeScopedRefPtr
<HasIsMethodTag
<Runnable
>::value
, BoundArgs
...> ref_
;
405 Tuple
<BoundArgs
...> bound_args_
;
408 ~BindState() override
{}
411 } // namespace internal
414 #endif // BASE_BIND_INTERNAL_H_