| 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 $var MAX_ARITY = 6 | 8 $var MAX_ARITY = 6 |
| 9 | 9 |
| 10 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 10 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 // - Invoking the return of Bind. Bind(&foo).Run() does not work; | 209 // - Invoking the return of Bind. Bind(&foo).Run() does not work; |
| 210 // - Binding arrays to functions that take a non-const pointer. | 210 // - Binding arrays to functions that take a non-const pointer. |
| 211 // Example: | 211 // Example: |
| 212 // void Foo(const char* ptr); | 212 // void Foo(const char* ptr); |
| 213 // void Bar(char* ptr); | 213 // void Bar(char* ptr); |
| 214 // Bind(&Foo, "test"); | 214 // Bind(&Foo, "test"); |
| 215 // Bind(&Bar, "test"); // This fails because ptr is not const. | 215 // Bind(&Bar, "test"); // This fails because ptr is not const. |
| 216 | 216 |
| 217 namespace base { | 217 namespace base { |
| 218 | 218 |
| 219 namespace internal { |
| 220 |
| 221 // Holds the methods that don't require specialization to reduce template bloat. |
| 222 class CallbackBase { |
| 223 public: |
| 224 // Returns true if Callback is null (doesn't refer to anything). |
| 225 bool is_null() const { |
| 226 return invoker_storage_.get() == NULL; |
| 227 } |
| 228 |
| 229 // Returns the Callback into an uninitalized state. |
| 230 void Reset() { |
| 231 invoker_storage_ = NULL; |
| 232 polymorphic_invoke_ = NULL; |
| 233 } |
| 234 |
| 235 bool Equals(const CallbackBase& other) const { |
| 236 return invoker_storage_.get() == other.invoker_storage_.get() && |
| 237 polymorphic_invoke_ == other.polymorphic_invoke_; |
| 238 } |
| 239 |
| 240 protected: |
| 241 // In C++, it is safe to cast function pointers to function pointers of |
| 242 // another type. It is not okay to use void*. We create a InvokeFuncStorage |
| 243 // that that can store our function pointer, and then cast it back to |
| 244 // the original type on usage. |
| 245 typedef void(*InvokeFuncStorage)(void); |
| 246 |
| 247 CallbackBase(InvokeFuncStorage polymorphic_invoke, |
| 248 scoped_refptr<InvokerStorageBase>* invoker_storage) |
| 249 : polymorphic_invoke_(polymorphic_invoke) { |
| 250 if (invoker_storage) { |
| 251 invoker_storage_.swap(*invoker_storage); |
| 252 } |
| 253 } |
| 254 |
| 255 scoped_refptr<InvokerStorageBase> invoker_storage_; |
| 256 InvokeFuncStorage polymorphic_invoke_; |
| 257 }; |
| 258 |
| 259 } // namespace internal |
| 260 |
| 261 |
| 219 // First, we forward declare the Callback class template. This informs the | 262 // First, we forward declare the Callback class template. This informs the |
| 220 // compiler that the template only has 1 type parameter which is the function | 263 // compiler that the template only has 1 type parameter which is the function |
| 221 // signature that the Callback is representing. | 264 // signature that the Callback is representing. |
| 222 // | 265 // |
| 223 // After this, create template specializations for 0-$(MAX_ARITY) parameters. No
te that | 266 // After this, create template specializations for 0-$(MAX_ARITY) parameters. No
te that |
| 224 // even though the template typelist grows, the specialization still | 267 // even though the template typelist grows, the specialization still |
| 225 // only has one type: the function signature. | 268 // only has one type: the function signature. |
| 226 template <typename Sig> | 269 template <typename Sig> |
| 227 class Callback; | 270 class Callback; |
| 228 | 271 |
| 229 | |
| 230 $range ARITY 0..MAX_ARITY | 272 $range ARITY 0..MAX_ARITY |
| 231 $for ARITY [[ | 273 $for ARITY [[ |
| 232 $range ARG 1..ARITY | 274 $range ARG 1..ARITY |
| 233 | 275 |
| 234 $if ARITY == 0 [[ | 276 $if ARITY == 0 [[ |
| 235 template <typename R> | 277 template <typename R> |
| 236 class Callback<R(void)> { | 278 class Callback<R(void)> : public internal::CallbackBase { |
| 237 ]] $else [[ | 279 ]] $else [[ |
| 238 template <typename R, $for ARG , [[typename A$(ARG)]]> | 280 template <typename R, $for ARG , [[typename A$(ARG)]]> |
| 239 class Callback<R($for ARG , [[A$(ARG)]])> { | 281 class Callback<R($for ARG , [[A$(ARG)]])> : public internal::CallbackBase { |
| 240 ]] | 282 ]] |
| 241 | 283 |
| 242 public: | 284 public: |
| 243 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*[[]] | 285 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*[[]] |
| 244 $if ARITY != 0 [[, ]] | 286 $if ARITY != 0 [[, ]] |
| 245 $for ARG , | 287 $for ARG , |
| 246 [[const A$(ARG)&]]); | 288 [[const A$(ARG)&]]); |
| 247 | 289 |
| 248 Callback() : polymorphic_invoke_(NULL) { } | 290 Callback() : CallbackBase(NULL, NULL) { } |
| 249 | 291 |
| 250 // We pass InvokerStorageHolder by const ref to avoid incurring an | 292 // We pass InvokerStorageHolder by const ref to avoid incurring an |
| 251 // unnecessary AddRef/Unref pair even though we will modify the object. | 293 // unnecessary AddRef/Unref pair even though we will modify the object. |
| 252 // We cannot use a normal reference because the compiler will warn | 294 // We cannot use a normal reference because the compiler will warn |
| 253 // since this is often used on a return value, which is a temporary. | 295 // since this is often used on a return value, which is a temporary. |
| 254 // | 296 // |
| 255 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT | 297 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT |
| 256 // return the exact Callback<> type. See base/bind.h for details. | 298 // return the exact Callback<> type. See base/bind.h for details. |
| 257 template <typename T> | 299 template <typename T> |
| 258 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) | 300 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) |
| 259 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) { | 301 : CallbackBase( |
| 260 invoker_storage_.swap(invoker_holder.invoker_storage_); | 302 reinterpret_cast<InvokeFuncStorage>(&T::FunctionTraits::DoInvoke), |
| 303 &invoker_holder.invoker_storage_) { |
| 261 } | 304 } |
| 262 | 305 |
| 263 | |
| 264 $if ARITY == 0 [[ | |
| 265 R Run(void) const { | |
| 266 ]] $else [[ | |
| 267 R Run($for ARG , | 306 R Run($for ARG , |
| 268 [[const A$(ARG)& a$(ARG)]]) const { | 307 [[const A$(ARG)& a$(ARG)]]) const { |
| 269 ]] | 308 PolymorphicInvoke f = |
| 309 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_); |
| 270 | 310 |
| 271 return polymorphic_invoke_(invoker_storage_.get()[[]] | 311 return f(invoker_storage_.get()[[]] |
| 272 $if ARITY != 0 [[, ]] | 312 $if ARITY != 0 [[, ]] |
| 273 $for ARG , | 313 $for ARG , |
| 274 [[a$(ARG)]]); | 314 [[a$(ARG)]]); |
| 275 } | 315 } |
| 276 | |
| 277 private: | |
| 278 scoped_refptr<internal::InvokerStorageBase> invoker_storage_; | |
| 279 PolymorphicInvoke polymorphic_invoke_; | |
| 280 }; | 316 }; |
| 281 | 317 |
| 282 | 318 |
| 283 ]] $$ for ARITY | 319 ]] $$ for ARITY |
| 284 | 320 |
| 285 // Syntactic sugar to make Callbacks<void(void)> easier to declare since it | 321 // Syntactic sugar to make Callbacks<void(void)> easier to declare since it |
| 286 // will be used in a lot of APIs with delayed execution. | 322 // will be used in a lot of APIs with delayed execution. |
| 287 typedef Callback<void(void)> Closure; | 323 typedef Callback<void(void)> Closure; |
| 288 | 324 |
| 289 } // namespace base | 325 } // namespace base |
| 290 | 326 |
| 291 #endif // BASE_CALLBACK_H | 327 #endif // BASE_CALLBACK_H |
| OLD | NEW |