| 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 |