OLD | NEW |
1 $$ This is a pump file for generating file templates. Pump is a python | 1 $$ This is a pump file for generating file templates. Pump is a python |
2 $$ script that is part of the Google Test suite of utilities. Description | 2 $$ script that is part of the Google Test suite of utilities. Description |
3 $$ can be found here: | 3 $$ can be found here: |
4 $$ | 4 $$ |
5 $$ http://code.google.com/p/googletest/wiki/PumpManual | 5 $$ http://code.google.com/p/googletest/wiki/PumpManual |
6 $$ | 6 $$ |
7 | 7 |
| 8 // TODO(ajwong): If you create an fully unbound method, is there a way to |
| 9 // enforce the first argument must be refcounted? Or do we just say |
| 10 // "oh well"? |
| 11 // |
| 12 // Do we want to allow creating a fully unbound method?? |
| 13 |
8 $var MAX_ARITY = 6 | 14 $var MAX_ARITY = 6 |
| 15 $range ARITY 0..MAX_ARITY |
9 | 16 |
10 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 17 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
11 // Use of this source code is governed by a BSD-style license that can be | 18 // Use of this source code is governed by a BSD-style license that can be |
12 // found in the LICENSE file. | 19 // found in the LICENSE file. |
13 | 20 |
14 #ifndef BASE_BIND_INTERNAL_H_ | 21 #ifndef BASE_BIND_INTERNAL_H_ |
15 #define BASE_BIND_INTERNAL_H_ | 22 #define BASE_BIND_INTERNAL_H_ |
16 #pragma once | 23 #pragma once |
17 | 24 |
18 #include "base/bind_helpers.h" | 25 #include "base/bind_helpers.h" |
19 #include "base/callback_internal.h" | 26 #include "base/callback_internal.h" |
20 #include "base/memory/raw_scoped_refptr_mismatch_checker.h" | 27 #include "base/memory/raw_scoped_refptr_mismatch_checker.h" |
21 #include "base/memory/weak_ptr.h" | 28 #include "base/memory/weak_ptr.h" |
22 #include "base/template_util.h" | 29 #include "base/template_util.h" |
23 #include "build/build_config.h" | 30 #include "build/build_config.h" |
24 | 31 |
25 #if defined(OS_WIN) | 32 #if defined(OS_WIN) |
26 #include "base/bind_internal_win.h" | 33 #include "base/bind_internal_win.h" |
27 #endif | 34 #endif |
28 | 35 |
29 namespace base { | 36 namespace base { |
30 namespace internal { | 37 namespace internal { |
31 | 38 |
32 // The method by which a function is invoked is determined by 3 different | 39 // CONCEPTS: |
33 // dimensions: | 40 // Runnable -- A type (really a type class) that has a single Run() method |
34 // | 41 // and a RunType typedef that corresponds to the type of Run(). |
35 // 1) The type of function (normal or method). | 42 // A Runnable can declare that it should treated like a method |
36 // 2) The arity of the function. | 43 // call by including a typedef named IsMethod. The value of |
37 // 3) The number of bound parameters. | 44 // this typedef is NOT inspected, only the existence. When a |
38 // | 45 // Runnable declares itself a method, Bind() will enforce special |
39 // The templates below handle the determination of each of these dimensions. | 46 // refcounting + WeakPtr handling semantics for the first |
40 // In brief: | 47 // parameter which is expected to be an object. |
41 // | 48 // Functor -- A copyable type representing something that should be called. |
42 // FunctionTraits<> -- Provides a normalied signature, and other traits. | 49 // All function pointers, Callback<>, and Runnables are functors |
43 // InvokerN<> -- Provides a DoInvoke() function that actually executes | 50 // even if the invocation syntax differs. |
44 // a calback. | 51 // RunType -- A function type (as opposed to function _pointer_ type) for |
45 // InvokerStorageN<> -- Provides storage for the bound parameters, and | 52 // a Run() function. Usually just a convenience typedef. |
46 // typedefs to the above. | 53 // (Bound)ArgsType -- A function type that is being (ab)used to store the |
47 // IsWeakMethod<> -- Determines if we are binding a method to a WeakPtr<>. | 54 // types of set of arguments. The "return" type is always |
48 // | 55 // void here. We use this hack so that we do not need |
49 // More details about the design of each class is included in a comment closer | 56 // a new type name for each arity of type. (eg., |
50 // to their defition. | 57 // BindState1, BindState2). This makes forward |
51 | 58 // declarations and friending much much easier. |
52 | 59 // |
53 // IsWeakMethod determines if we are binding a method to a WeakPtr<> for an | 60 // Types: |
54 // object. It is used to select an InvokerN that will no-op itself in the | 61 // RunnableAdapter<> -- Wraps the various "function" pointer types into an |
55 // event the WeakPtr<> for the target object is invalidated. | 62 // object that adheres to the Runnable interface. |
56 template <bool IsMethod, typename T> | 63 // There are |3*ARITY| RunnableAdapter types. |
57 struct IsWeakMethod : public false_type {}; | 64 // FunctionTraits<> -- Type traits that unwrap a function signature into a |
58 | 65 // a set of easier to use typedefs. Used mainly for |
59 template <typename T> | 66 // compile time asserts. |
60 struct IsWeakMethod<true, WeakPtr<T> > : public true_type {}; | 67 // There are |ARITY| FunctionTraits types. |
| 68 // ForceVoidReturn<> -- Helper class for translating function signatures to |
| 69 // equivalent forms with a "void" return type. |
| 70 // There are |ARITY| ForceVoidReturn types. |
| 71 // FunctorTraits<> -- Type traits used determine the correct RunType and |
| 72 // RunnableType for a Functor. This is where function |
| 73 // signature adapters are applied. |
| 74 // There are |ARITY| ForceVoidReturn types. |
| 75 // MakeRunnable<> -- Takes a Functor and returns an object in the Runnable |
| 76 // type class that represents the underlying Functor. |
| 77 // There are |O(1)| MakeRunnable types. |
| 78 // InvokeHelper<> -- Take a Runnable + arguments and actully invokes it. |
| 79 // Handle the differing syntaxes needed for WeakPtr<> support
, |
| 80 // and for ignoring return values. This is separate from |
| 81 // Invoker to avoid creating multiple version of Invoker<> |
| 82 // which grows at O(n^2) with the arity. |
| 83 // There are |k*ARITY| InvokeHelper types. |
| 84 // Invoker<> -- Unwraps the curried parameters and executes the Runnable. |
| 85 // There are |(ARITY^2 + ARITY)/2| Invoketypes. |
| 86 // BindState<> -- Stores the curried parameters, and is the main entry point |
| 87 // into the Bind() system, doing most of the type resolution. |
| 88 // There are ARITY BindState types. |
| 89 |
| 90 |
| 91 // RunnableAdapter<> |
| 92 // |
| 93 // The RunnableAdapter<> templates provide a uniform interface for invoking |
| 94 // a function pointer, method pointer, or const method pointer. The adapter |
| 95 // exposes a Run() method with an appropriate signature. Using this wrapper |
| 96 // allows for writing code that supports all three pointer types without |
| 97 // undue repetition. Without it, a lot of code would need to be repeated 3 |
| 98 // times. |
| 99 // |
| 100 // For method pointers and const method pointers the first argument to Run() |
| 101 // is considered to be the received of the method. This is similar to STL's |
| 102 // mem_fun(). |
| 103 // |
| 104 // This class also exposes a RunType typedef that is the function type of the |
| 105 // Run() function. |
| 106 // |
| 107 // If and only if the wrapper contains a method or const method pointer, an |
| 108 // IsMethod typedef is exposed. The existence of this typedef (NOT the value) |
| 109 // marks that the wrapper should be considered a method wrapper. |
| 110 |
| 111 template <typename Functor> |
| 112 class RunnableAdapter; |
| 113 |
| 114 $for ARITY [[ |
| 115 $range ARG 1..ARITY |
| 116 |
| 117 // Function: Arity $(ARITY). |
| 118 template <typename R[[]] |
| 119 $if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]> |
| 120 class RunnableAdapter<R(*)($for ARG , [[A$(ARG)]])> { |
| 121 public: |
| 122 typedef R (RunType)($for ARG , [[A$(ARG)]]); |
| 123 |
| 124 explicit RunnableAdapter(R(*function)($for ARG , [[A$(ARG)]])) |
| 125 : function_(function) { |
| 126 } |
| 127 |
| 128 R Run($for ARG , [[typename CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]
]) { |
| 129 return function_($for ARG , [[a$(ARG)]]); |
| 130 } |
| 131 |
| 132 private: |
| 133 R (*function_)($for ARG , [[A$(ARG)]]); |
| 134 }; |
| 135 |
| 136 // Method: Arity $(ARITY). |
| 137 template <typename R, typename T[[]] |
| 138 $if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]> |
| 139 class RunnableAdapter<R(T::*)($for ARG , [[A$(ARG)]])> { |
| 140 public: |
| 141 typedef R (RunType)(T*[[]] |
| 142 $if ARITY > 0[[, ]] $for ARG , [[A$(ARG)]]); |
| 143 typedef true_type IsMethod; |
| 144 |
| 145 explicit RunnableAdapter(R(T::*method)($for ARG , [[A$(ARG)]])) |
| 146 : method_(method) { |
| 147 } |
| 148 |
| 149 R Run(T* object[[]] |
| 150 $if ARITY > 0[[, ]] $for ARG, [[typename CallbackParamTraits<A$(ARG)>::ForwardT
ype a$(ARG)]]) { |
| 151 return (object->*method_)($for ARG , [[a$(ARG)]]); |
| 152 } |
| 153 |
| 154 private: |
| 155 R (T::*method_)($for ARG , [[A$(ARG)]]); |
| 156 }; |
| 157 |
| 158 // Const Method: Arity $(ARITY). |
| 159 template <typename R, typename T[[]] |
| 160 $if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]> |
| 161 class RunnableAdapter<R(T::*)($for ARG , [[A$(ARG)]]) const> { |
| 162 public: |
| 163 typedef R (RunType)(const T*[[]] |
| 164 $if ARITY > 0[[, ]] $for ARG , [[A$(ARG)]]); |
| 165 typedef true_type IsMethod; |
| 166 |
| 167 explicit RunnableAdapter(R(T::*method)($for ARG , [[A$(ARG)]]) const) |
| 168 : method_(method) { |
| 169 } |
| 170 |
| 171 R Run(const T* object[[]] |
| 172 $if ARITY > 0[[, ]] $for ARG, [[typename CallbackParamTraits<A$(ARG)>::ForwardT
ype a$(ARG)]]) { |
| 173 return (object->*method_)($for ARG , [[a$(ARG)]]); |
| 174 } |
| 175 |
| 176 private: |
| 177 R (T::*method_)($for ARG , [[A$(ARG)]]) const; |
| 178 }; |
| 179 |
| 180 ]] $$ for ARITY |
| 181 |
61 | 182 |
62 // FunctionTraits<> | 183 // FunctionTraits<> |
63 // | 184 // |
64 // The FunctionTraits<> template determines the type of function, and also | 185 // Breaks a function signature apart into typedefs for easier introspection. |
65 // creates a NormalizedType used to select the InvokerN classes. It turns out | |
66 // that syntactically, you only really have 2 variations when invoking a | |
67 // funciton pointer: normal, and method. One is invoked func_ptr(arg1). The | |
68 // other is invoked (*obj_->method_ptr(arg1)). | |
69 // | |
70 // However, in the type system, there are many more distinctions. In standard | |
71 // C++, there's all variations of const, and volatile on the function pointer. | |
72 // In Windows, there are additional calling conventions (eg., __stdcall, | |
73 // __fastcall, etc.). FunctionTraits<> handles categorizing each of these into | |
74 // a normalized signature. | |
75 // | |
76 // Having a NormalizedSignature signature, reduces the combinatoric | |
77 // complexity of defintions for the InvokerN<> later. Even though there are | |
78 // only 2 syntactic variations on invoking a function, without normalizing the | |
79 // signature, there would need to be one specialization of InvokerN for each | |
80 // unique (function_type, bound_arg, unbound_args) tuple in order to match all | |
81 // function signatures. | |
82 // | |
83 // By normalizing the function signature, we reduce function_type to exactly 2. | |
84 | |
85 template <typename Sig> | 186 template <typename Sig> |
86 struct FunctionTraits; | 187 struct FunctionTraits; |
87 | 188 |
88 $range ARITY 0..MAX_ARITY | 189 $for ARITY [[ |
89 $for ARITY [[ | 190 $range ARG 1..ARITY |
90 $range ARG 1..ARITY | 191 |
91 | |
92 // Function: Arity $(ARITY). | |
93 template <typename R[[]] | 192 template <typename R[[]] |
94 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]> | 193 $if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]> |
95 struct FunctionTraits<R(*)($for ARG , [[X$(ARG)]])> { | 194 struct FunctionTraits<R($for ARG , [[A$(ARG)]])> { |
96 typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]); | 195 typedef R ReturnType; |
97 typedef false_type IsMethod; | 196 $for ARG [[ |
98 | 197 |
99 typedef R Return; | 198 typedef A$(ARG) A$(ARG)Type; |
| 199 ]] |
| 200 |
| 201 }; |
| 202 |
| 203 ]] |
| 204 |
| 205 |
| 206 // ForceVoidReturn<> |
| 207 // |
| 208 // Set of templates that support forcing the function return type to void. |
| 209 template <typename Sig> |
| 210 struct ForceVoidReturn; |
| 211 |
| 212 $for ARITY [[ |
| 213 $range ARG 1..ARITY |
| 214 |
| 215 template <typename R[[]] |
| 216 $if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]> |
| 217 struct ForceVoidReturn<R($for ARG , [[A$(ARG)]])> { |
| 218 typedef void(RunType)($for ARG , [[A$(ARG)]]); |
| 219 }; |
| 220 |
| 221 ]] $$ for ARITY |
| 222 |
| 223 |
| 224 // FunctorTraits<> |
| 225 // |
| 226 // See description at top of file. |
| 227 template <typename T> |
| 228 struct FunctorTraits { |
| 229 typedef RunnableAdapter<T> RunnableType; |
| 230 typedef typename RunnableType::RunType RunType; |
| 231 }; |
| 232 |
| 233 template <typename T> |
| 234 struct FunctorTraits<IgnoreResultHelper<T> > { |
| 235 typedef typename FunctorTraits<T>::RunnableType RunnableType; |
| 236 typedef typename ForceVoidReturn< |
| 237 typename RunnableType::RunType>::RunType RunType; |
| 238 }; |
| 239 |
| 240 template <typename T> |
| 241 struct FunctorTraits<Callback<T> > { |
| 242 typedef Callback<T> RunnableType; |
| 243 typedef typename Callback<T>::RunType RunType; |
| 244 }; |
| 245 |
| 246 |
| 247 // MakeRunnable<> |
| 248 // |
| 249 // Converts a passed in functor to a RunnableType using type inference. |
| 250 |
| 251 template <typename T> |
| 252 typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) { |
| 253 return RunnableAdapter<T>(t); |
| 254 } |
| 255 |
| 256 template <typename T> |
| 257 typename FunctorTraits<T>::RunnableType |
| 258 MakeRunnable(const IgnoreResultHelper<T>& t) { |
| 259 return MakeRunnable(t.functor_); |
| 260 } |
| 261 |
| 262 template <typename T> |
| 263 const typename FunctorTraits<Callback<T> >::RunnableType& |
| 264 MakeRunnable(const Callback<T>& t) { |
| 265 return t; |
| 266 } |
| 267 |
| 268 |
| 269 // InvokeHelper<> |
| 270 // |
| 271 // There are 3 logical InvokeHelper<> specializations: normal, void-return, |
| 272 // WeakCalls. |
| 273 // |
| 274 // The normal type just calls the underlying runnable. |
| 275 // |
| 276 // We need a InvokeHelper to handle void return types in order to support |
| 277 // IgnoreResult(). Normally, if the Runnable's RunType had a void return, |
| 278 // the template system would just accept "return functor.Run()" ignoring |
| 279 // the fact that a void function is being used with return. This piece of |
| 280 // sugar breaks though when the Runnable's RunType is not void. Thus, we |
| 281 // need a partial specialization to change the syntax to drop the "return" |
| 282 // from the invocation call. |
| 283 // |
| 284 // WeakCalls similarly need special syntax that is applied to the first |
| 285 // argument to check if they should no-op themselves. |
| 286 template <bool IsWeakCall, typename ReturnType, typename Runnable, |
| 287 typename ArgsType> |
| 288 struct InvokeHelper; |
| 289 |
| 290 $for ARITY [[ |
| 291 $range ARG 1..ARITY |
| 292 |
| 293 template <typename ReturnType, typename Runnable[[]] |
| 294 $if ARITY > 0 [[,]] $for ARG , [[typename A$(ARG)]]> |
| 295 struct InvokeHelper<false, ReturnType, Runnable, |
| 296 void($for ARG , [[A$(ARG)]])> { |
| 297 static ReturnType MakeItSo(Runnable runnable[[]] |
| 298 $if ARITY > 0[[, ]] $for ARG , [[A$(ARG) a$(ARG)]]) { |
| 299 return runnable.Run($for ARG , [[a$(ARG)]]); |
| 300 } |
| 301 }; |
| 302 |
| 303 template <typename Runnable[[]] |
| 304 $if ARITY > 0 [[,]] $for ARG , [[typename A$(ARG)]]> |
| 305 struct InvokeHelper<false, void, Runnable, |
| 306 void($for ARG , [[A$(ARG)]])> { |
| 307 static void MakeItSo(Runnable runnable[[]] |
| 308 $if ARITY > 0[[, ]] $for ARG , [[A$(ARG) a$(ARG)]]) { |
| 309 runnable.Run($for ARG , [[a$(ARG)]]); |
| 310 } |
| 311 }; |
100 | 312 |
101 $if ARITY > 0 [[ | 313 $if ARITY > 0 [[ |
102 | 314 |
103 // Target type for each bound parameter. | 315 template <typename Runnable[[]], $for ARG , [[typename A$(ARG)]]> |
104 | 316 struct InvokeHelper<true, void, Runnable, |
105 $for ARG [[ | 317 void($for ARG , [[A$(ARG)]])> { |
106 typedef X$(ARG) B$(ARG); | 318 static void MakeItSo(Runnable runnable[[]] |
107 | 319 $if ARITY > 0[[, ]] $for ARG , [[A$(ARG) a$(ARG)]]) { |
108 ]] $$ for ARG | 320 if (!a1.get()) { |
109 ]] $$ if ARITY > 0 | 321 return; |
110 | 322 } |
111 }; | 323 |
112 | 324 runnable.Run($for ARG , [[a$(ARG)]]); |
113 // Method: Arity $(ARITY). | 325 } |
114 template <typename R, typename T[[]] | 326 }; |
115 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]> | 327 |
116 struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]])> { | 328 ]] |
117 typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]); | 329 |
118 typedef true_type IsMethod; | 330 ]] $$ for ARITY |
119 | 331 |
120 typedef R Return; | 332 #if !defined(_MSC_VER) |
121 | 333 |
122 // Target type for each bound parameter. | 334 template <typename ReturnType, typename Runnable, typename ArgsType> |
123 typedef T B1; | 335 struct InvokeHelper<true, ReturnType, Runnable, ArgsType> { |
124 | 336 // WeakCalls are only supported for functions with a void return type. |
125 $for ARG [[ | 337 // Otherwise, the function result would be undefined if the the WeakPtr<> |
126 typedef X$(ARG) B$(ARG + 1); | 338 // is invalidated. |
127 | 339 COMPILE_ASSERT(is_void<ReturnType>::value, |
128 ]] $$ for ARG | 340 weak_ptrs_can_only_bind_to_methods_without_return_values); |
129 | 341 }; |
130 }; | 342 |
131 | 343 #endif |
132 // Const Method: Arity $(ARITY). | 344 |
133 template <typename R, typename T[[]] | 345 // Invoker<> |
134 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]> | 346 // |
135 struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]]) const> { | 347 // See description at the top of the file. |
136 typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]); | 348 template <int NumBound, typename Storage, typename RunType> |
137 typedef true_type IsMethod; | 349 struct Invoker; |
138 | 350 |
139 typedef R Return; | 351 $for ARITY [[ |
140 | 352 |
141 // Target type for each bound parameter. | 353 $$ Number of bound arguments. |
142 typedef T B1; | 354 $range BOUND 0..ARITY |
143 | |
144 $for ARG [[ | |
145 typedef X$(ARG) B$(ARG + 1); | |
146 | |
147 ]] $$ for ARG | |
148 | |
149 }; | |
150 | |
151 ]] $$for ARITY | |
152 | |
153 // InvokerN<> | |
154 // | |
155 // The InvokerN templates contain a static DoInvoke() function that is the key | |
156 // to implementing type erasure in the Callback() classes. | |
157 // | |
158 // DoInvoke() is a static function with a fixed signature that is independent | |
159 // of StorageType; its first argument is a pointer to the non-templated common | |
160 // baseclass of StorageType. This lets us store pointer to DoInvoke() in a | |
161 // function pointer that has knowledge of the specific StorageType, and thus | |
162 // no knowledge of the bound function and bound parameter types. | |
163 // | |
164 // As long as we ensure that DoInvoke() is only used with pointers there were | |
165 // upcasted from the correct StorageType, we can be sure that execution is | |
166 // safe. | |
167 // | |
168 // The InvokerN templates are the only point that knows the number of bound | |
169 // and unbound arguments. This is intentional because it allows the other | |
170 // templates classes in the system to only have as many specializations as | |
171 // the max arity of function we wish to support. | |
172 | |
173 $range BOUND 0..MAX_ARITY | |
174 $for BOUND [[ | 355 $for BOUND [[ |
175 | 356 |
176 template <bool IsWeak, typename StorageType, typename NormalizedSig> | |
177 struct Invoker$(BOUND); | |
178 | |
179 $range ARITY 0..MAX_ARITY | |
180 $for ARITY [[ | |
181 | |
182 $var UNBOUND = ARITY - BOUND | 357 $var UNBOUND = ARITY - BOUND |
183 $if UNBOUND >= 0 [[ | |
184 | |
185 $$ Variables for function traits generation. | |
186 $range ARG 1..ARITY | 358 $range ARG 1..ARITY |
187 $range BOUND_ARG 1..BOUND | 359 $range BOUND_ARG 1..BOUND |
188 $range UNBOUND_ARG (ARITY - UNBOUND + 1)..ARITY | 360 $range UNBOUND_ARG (ARITY - UNBOUND + 1)..ARITY |
189 | 361 |
190 $$ Variables for method traits generation. We are always short one arity since | 362 // Arity $(ARITY) -> $(UNBOUND). |
191 $$ the first bound parameter is the object. | |
192 $var M_ARITY = ARITY - 1 | |
193 $range M_ARG 1..M_ARITY | |
194 $range M_BOUND_ARG 2..BOUND | |
195 $range M_UNBOUND_ARG (M_ARITY - UNBOUND + 1)..M_ARITY | |
196 | |
197 // Function: Arity $(ARITY) -> $(UNBOUND). | |
198 template <typename StorageType, typename R[[]] | 363 template <typename StorageType, typename R[[]] |
199 $if ARITY > 0 [[,]][[]] | 364 $if ARITY > 0 [[,]][[]] |
200 $for ARG , [[typename X$(ARG)]]> | 365 $for ARG , [[typename X$(ARG)]]> |
201 struct Invoker$(BOUND)<false, StorageType, R(*)($for ARG , [[X$(ARG)]])> { | 366 struct Invoker<$(BOUND), StorageType, R($for ARG , [[X$(ARG)]])> { |
202 typedef R(*DoInvokeType)( | 367 typedef R(RunType)(BindStateBase*[[]] |
203 internal::InvokerStorageBase*[[]] | |
204 $if UNBOUND != 0 [[, ]] | 368 $if UNBOUND != 0 [[, ]] |
205 $for UNBOUND_ARG , [[typename internal::ParamTraits<X$(UNBOUND_ARG)>::ForwardTyp
e]]); | 369 $for UNBOUND_ARG , [[typename CallbackParamTraits<X$(UNBOUND_ARG)>::ForwardType]
]); |
206 | 370 |
207 static R DoInvoke(InvokerStorageBase* base[[]] | 371 typedef R(UnboundRunType)($for UNBOUND_ARG , [[X$(UNBOUND_ARG)]]); |
| 372 |
| 373 static R Run(BindStateBase* base[[]] |
208 $if UNBOUND != 0 [[, ]][[]] | 374 $if UNBOUND != 0 [[, ]][[]] |
209 $for UNBOUND_ARG , [[typename internal::ParamTraits<X$(UNBOUND_ARG)>::ForwardTyp
e x$(UNBOUND_ARG)]]) { | 375 $for UNBOUND_ARG , [[ |
210 StorageType* invoker = static_cast<StorageType*>(base); | 376 typename CallbackParamTraits<X$(UNBOUND_ARG)>::ForwardType x$(UNBOUND_ARG) |
211 return invoker->f_($for BOUND_ARG , [[Unwrap(invoker->p$(BOUND_ARG)_)]][[]] | 377 ]][[]] |
212 $$ Add comma if there are both boudn and unbound args. | 378 ) { |
| 379 StorageType* storage = static_cast<StorageType*>(base); |
| 380 |
| 381 // Local references to make debugger stepping easier. If in a debugger, |
| 382 // you really want to warp ahead and step through the |
| 383 // InvokeHelper<>::MakeItSo() call below. |
| 384 $for BOUND_ARG |
| 385 [[ |
| 386 |
| 387 typedef typename StorageType::Bound$(BOUND_ARG)UnwrapTraits Bound$(BOUND_ARG
)UnwrapTraits; |
| 388 ]] |
| 389 |
| 390 |
| 391 $for BOUND_ARG |
| 392 [[ |
| 393 |
| 394 typename Bound$(BOUND_ARG)UnwrapTraits::ForwardType x$(BOUND_ARG) = |
| 395 Bound$(BOUND_ARG)UnwrapTraits::Unwrap(storage->p$(BOUND_ARG)_); |
| 396 ]] |
| 397 |
| 398 return InvokeHelper<StorageType::IsWeakCall::value, R, |
| 399 typename StorageType::RunnableType, |
| 400 void( |
| 401 $for BOUND_ARG , [[ |
| 402 typename Bound$(BOUND_ARG)UnwrapTraits::ForwardType |
| 403 ]] |
| 404 |
213 $if UNBOUND > 0 [[$if BOUND > 0 [[, ]]]][[]] | 405 $if UNBOUND > 0 [[$if BOUND > 0 [[, ]]]][[]] |
214 $for UNBOUND_ARG , [[x$(UNBOUND_ARG)]]); | 406 |
215 } | 407 $for UNBOUND_ARG , [[ |
216 }; | 408 typename CallbackParamTraits<X$(UNBOUND_ARG)>::ForwardType x$(UNBOUND_ARG) |
217 | 409 ]] |
218 $if BOUND > 0 [[ | 410 )> |
219 | 411 ::MakeItSo(storage->runnable_ |
220 // Method: Arity $(M_ARITY) -> $(UNBOUND). | 412 $if ARITY > 0[[, ]] $for ARG , [[x$(ARG)]]); |
221 template <typename StorageType, typename R, typename T[[]] | 413 } |
222 $if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]> | 414 }; |
223 struct Invoker$(BOUND)<false, StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]])>
{ | 415 |
224 typedef R(*DoInvokeType)( | 416 ]] $$ for BOUND |
225 internal::InvokerStorageBase*[[]] | 417 ]] $$ for ARITY |
226 $if UNBOUND != 0 [[, ]] | 418 |
227 $for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::Forwar
dType]]); | 419 |
228 | 420 // BindState<> |
229 static R DoInvoke(InvokerStorageBase* base[[]] | 421 // |
230 $if UNBOUND > 0 [[, ]][[]] | 422 // This stores all the state passed into Bind() and is also where most |
231 $for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::Forwar
dType x$(M_UNBOUND_ARG)]]) { | 423 // of the template resolution magic occurs. |
232 StorageType* invoker = static_cast<StorageType*>(base); | 424 // |
233 return (Unwrap(invoker->p1_)->*invoker->f_)([[]] | 425 // Runnable is the functor we are binding arguments to. |
234 $for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]] | 426 // RunType is type of the Run() function that the Invoker<> should use. |
235 $if UNBOUND > 0 [[$if BOUND > 1 [[, ]]]][[]] | 427 // Normally, this is the same as the RunType of the Runnable, but it can |
236 $for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]); | 428 // be different if an adapter like IgnoreResult() has been used. |
237 } | 429 // |
238 }; | 430 // BoundArgsType contains the storage type for all the bound arguments by |
239 | 431 // (ab)using a function type. |
240 // WeakPtr Method: Arity $(M_ARITY) -> $(UNBOUND). | 432 template <typename Runnable, typename RunType, typename BoundArgsType> |
241 template <typename StorageType, typename T[[]] | 433 struct BindState; |
242 $if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]> | 434 |
243 struct Invoker$(BOUND)<true, StorageType, void(T::*)($for M_ARG , [[X$(M_ARG)]])
> { | 435 $for ARITY [[ |
244 typedef void(*DoInvokeType)( | 436 $range ARG 1..ARITY |
245 internal::InvokerStorageBase*[[]] | 437 |
246 $if UNBOUND != 0 [[, ]] | 438 template <typename Runnable, typename RunType[[]] |
247 $for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::Forwar
dType]]); | 439 $if ARITY > 0[[, ]] $for ARG , [[typename P$(ARG)]]> |
248 | 440 struct BindState<Runnable, RunType, void($for ARG , [[P$(ARG)]])> : public BindS
tateBase { |
249 static void DoInvoke(InvokerStorageBase* base[[]] | 441 typedef Runnable RunnableType; |
250 $if UNBOUND > 0 [[, ]][[]] | 442 |
251 $for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::Forwar
dType x$(M_UNBOUND_ARG)]]) { | 443 $if ARITY > 0 [[ |
252 StorageType* invoker = static_cast<StorageType*>(base); | 444 typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall; |
253 typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_; | |
254 if (!weak_ptr.get()) { | |
255 return; | |
256 } | |
257 (weak_ptr->*invoker->f_)([[]] | |
258 $for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]] | |
259 $if UNBOUND > 0 [[$if BOUND > 1 [[, ]]]][[]] | |
260 $for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]); | |
261 } | |
262 }; | |
263 | |
264 ]] $$ if BOUND | |
265 | |
266 ]] $$ if UNBOUND | |
267 ]] $$ for ARITY | |
268 ]] $$ for BOUND | |
269 | |
270 // BindMoreFuncN<> | |
271 // | |
272 // This set of functions help in fully binding the free parameters in a | |
273 // Callback<>. | |
274 $for BOUND [[ | |
275 $range BOUND_ARG 1..BOUND | |
276 $if BOUND != 0 [[ | |
277 | |
278 template <typename Sig, $for BOUND_ARG , [[typename P$(BOUND_ARG)]]> | |
279 void BindMoreFunc$(BOUND)(const base::Callback<Sig>& callback, [[]] | |
280 $for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]]) { | |
281 callback.Run($for BOUND_ARG , [[p$(BOUND_ARG)]]); | |
282 } | |
283 | |
284 ]] $$ if BOUND | |
285 ]] $$ for BOUND | |
286 | |
287 // InvokerStorageN<> | |
288 // | |
289 // These are the actual storage classes for the Invokers. | |
290 // | |
291 // Though these types are "classes", they are being used as structs with | |
292 // all member variable public. We cannot make it a struct because it inherits | |
293 // from a class which causes a compiler warning. We cannot add a "Run()" method | |
294 // that forwards the unbound arguments because that would require we unwrap the | |
295 // Sig type like in InvokerN above to know the return type, and the arity | |
296 // of Run(). | |
297 // | |
298 // An alternate solution would be to merge InvokerN and InvokerStorageN, | |
299 // but the generated code seemed harder to read. | |
300 | |
301 $for BOUND [[ | |
302 $range BOUND_ARG 1..BOUND | |
303 | |
304 template <typename Sig[[]] | |
305 $if BOUND > 0 [[, ]] | |
306 $for BOUND_ARG , [[typename P$(BOUND_ARG)]]> | |
307 class InvokerStorage$(BOUND) : public InvokerStorageBase { | |
308 public: | |
309 typedef InvokerStorage$(BOUND) StorageType; | |
310 typedef FunctionTraits<Sig> TargetTraits; | |
311 typedef typename TargetTraits::IsMethod IsMethod; | |
312 typedef Sig Signature; | |
313 | |
314 $for BOUND_ARG [[ | |
315 typedef ParamTraits<P$(BOUND_ARG)> P$(BOUND_ARG)Traits; | |
316 | |
317 ]] | |
318 | |
319 $if BOUND == 0 [[ | |
320 typedef Invoker$(BOUND)<false, StorageType, | |
321 typename TargetTraits::NormalizedSig> Invoker; | |
322 ]] $else [[ | 445 ]] $else [[ |
323 typedef Invoker$(BOUND)<IsWeakMethod<IsMethod::value, P1>::value, StorageType, | 446 typedef false_type IsWeakCall; |
324 typename TargetTraits::NormalizedSig> Invoker; | 447 ]] |
325 COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) || | 448 |
326 is_void<typename TargetTraits::Return>::value, | 449 typedef Invoker<$(ARITY), BindState, RunType> InvokerType; |
327 weak_ptrs_can_only_bind_to_methods_without_return_values); | 450 typedef typename InvokerType::UnboundRunType UnboundRunType; |
328 ]] | 451 |
329 | 452 $if ARITY > 0 [[ |
330 | 453 |
331 $for BOUND_ARG [[ | 454 // Convenience typedefs for bound argument types. |
332 $if BOUND_ARG == 1 [[ | 455 |
333 | 456 $for ARG [[ |
334 // For methods, we need to be careful for parameter 1. We skip the | 457 typedef UnwrapTraits<P$(ARG)> Bound$(ARG)UnwrapTraits; |
335 // scoped_refptr check because the binder itself takes care of this. We also | 458 |
336 // disallow binding of an array as the method's target object. | 459 ]] $$ for ARG |
337 COMPILE_ASSERT(IsMethod::value || | 460 |
338 internal::NeedsScopedRefptrButGetsRawPtr< | 461 |
339 typename ParamTraits<P$(BOUND_ARG)>::StorageType>::value ==
0, | 462 ]] $$ if ARITY > 0 |
340 p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr); | 463 |
341 COMPILE_ASSERT(!IsMethod::value || !is_array<P$(BOUND_ARG)>::value, | 464 $$ The extra [[ ]] is needed to massage spacing. Silly pump.py. |
342 first_bound_argument_to_method_cannot_be_array); | 465 [[ ]]$if ARITY == 0 [[explicit ]]BindState(const Runnable& runnable |
| 466 $if ARITY > 0 [[, ]] $for ARG , [[const P$(ARG)& p$(ARG)]]) |
| 467 : runnable_(runnable)[[]] |
| 468 $if ARITY == 0 [[ |
| 469 { |
| 470 |
343 ]] $else [[ | 471 ]] $else [[ |
344 | 472 , $for ARG , [[ |
345 COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< | 473 |
346 typename ParamTraits<P$(BOUND_ARG)>::StorageType>::value == 0, | 474 p$(ARG)_(p$(ARG)) |
347 p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr); | 475 ]] { |
348 ]] $$ $if BOUND_ARG | 476 MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_); |
349 ]] $$ $for BOUND_ARG | 477 |
350 | 478 ]] |
351 | 479 } |
352 $if BOUND > 0 [[ | 480 |
353 | 481 virtual ~BindState() { |
354 // Do not allow binding a non-const reference parameter. Non-const reference | 482 $if ARITY > 0 [[ |
355 // parameters are disallowed by the Google style guide. Also, binding a | 483 MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::Release(p1_); |
356 // non-const reference parameter can make for subtle bugs because the | 484 ]] |
357 // invoked function will receive a reference to the stored copy of the | 485 } |
358 // argument and not the original. | 486 |
359 COMPILE_ASSERT( | 487 RunnableType runnable_; |
360 !($for BOUND_ARG || [[ is_non_const_reference<typename TargetTraits::B$(BO
UND_ARG)>::value ]]), | 488 |
361 do_not_bind_functions_with_nonconst_ref); | 489 $for ARG [[ |
362 | 490 P$(ARG) p$(ARG)_; |
363 ]] | 491 |
364 | 492 ]] |
365 | 493 }; |
366 InvokerStorage$(BOUND)(Sig f | 494 |
367 $if BOUND > 0 [[, ]] | 495 ]] $$ for ARITY |
368 $for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]]) | |
369 : f_(f)[[]] | |
370 $if BOUND == 0 [[ | |
371 { | |
372 | |
373 ]] $else [[ | |
374 , $for BOUND_ARG , [[p$(BOUND_ARG)_(static_cast<typename ParamTraits<P$(BOUND_AR
G)>::StorageType>(p$(BOUND_ARG)))]] { | |
375 MaybeRefcount<IsMethod, P1>::AddRef(p1_); | |
376 | |
377 ]] | |
378 } | |
379 | |
380 virtual ~InvokerStorage$(BOUND)() { | |
381 $if BOUND > 0 [[ | |
382 | |
383 MaybeRefcount<IsMethod, P1>::Release(p1_); | |
384 | |
385 ]] | |
386 } | |
387 | |
388 Sig f_; | |
389 | |
390 $for BOUND_ARG [[ | |
391 typename ParamTraits<P$(BOUND_ARG)>::StorageType p$(BOUND_ARG)_; | |
392 | |
393 ]] | |
394 }; | |
395 | |
396 ]] $$ for BOUND | |
397 | 496 |
398 } // namespace internal | 497 } // namespace internal |
399 } // namespace base | 498 } // namespace base |
400 | 499 |
401 #endif // BASE_BIND_INTERNAL_H_ | 500 #endif // BASE_BIND_INTERNAL_H_ |
OLD | NEW |