Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: base/callback.h

Issue 8483003: Callback API Change: Reimplement Bind(); support IgnoreResult, full currying, and use less types (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/bind_unittest.nc ('k') | base/callback.h.pump » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // This file was GENERATED by command: 1 // This file was GENERATED by command:
2 // pump.py callback.h.pump 2 // pump.py callback.h.pump
3 // DO NOT EDIT BY HAND!!! 3 // DO NOT EDIT BY HAND!!!
4 4
5 5
6 6
7 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 7 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
8 // Use of this source code is governed by a BSD-style license that can be 8 // Use of this source code is governed by a BSD-style license that can be
9 // found in the LICENSE file. 9 // found in the LICENSE file.
10 10
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 // HOW THE IMPLEMENTATION WORKS: 119 // HOW THE IMPLEMENTATION WORKS:
120 // 120 //
121 // There are three main components to the system: 121 // There are three main components to the system:
122 // 1) The Callback classes. 122 // 1) The Callback classes.
123 // 2) The Bind() functions. 123 // 2) The Bind() functions.
124 // 3) The arguments wrappers (eg., Unretained() and ConstRef()). 124 // 3) The arguments wrappers (eg., Unretained() and ConstRef()).
125 // 125 //
126 // The Callback classes represent a generic function pointer. Internally, 126 // The Callback classes represent a generic function pointer. Internally,
127 // it stores a refcounted piece of state that represents the target function 127 // it stores a refcounted piece of state that represents the target function
128 // and all its bound parameters. Each Callback specialization has a templated 128 // and all its bound parameters. Each Callback specialization has a templated
129 // constructor that takes an InvokerStorageHolder<> object. In the context of 129 // constructor that takes an BindStateHolder<> object. In the context of
130 // the constructor, the static type of this InvokerStorageHolder<> object 130 // the constructor, the static type of this BindStateHolder<> object
131 // uniquely identifies the function it is representing, all its bound 131 // uniquely identifies the function it is representing, all its bound
132 // parameters, and a DoInvoke() that is capable of invoking the target. 132 // parameters, and a DoInvoke() that is capable of invoking the target.
133 // 133 //
134 // Callback's constructor is takes the InvokerStorageHolder<> that has the 134 // Callback's constructor is takes the BindStateHolder<> that has the
135 // full static type and erases the target function type, and the bound 135 // full static type and erases the target function type, and the bound
136 // parameters. It does this by storing a pointer to the specific DoInvoke() 136 // parameters. It does this by storing a pointer to the specific DoInvoke()
137 // function, and upcasting the state of InvokerStorageHolder<> to a 137 // function, and upcasting the state of BindStateHolder<> to a
138 // InvokerStorageBase. This is safe as long as this InvokerStorageBase pointer 138 // BindStateBase. This is safe as long as this BindStateBase pointer
139 // is only used with the stored DoInvoke() pointer. 139 // is only used with the stored DoInvoke() pointer.
140 // 140 //
141 // To create InvokerStorageHolder<> objects, we use the Bind() functions. 141 // To create BindStateHolder<> objects, we use the Bind() functions.
142 // These functions, along with a set of internal templates, are reponsible for 142 // These functions, along with a set of internal templates, are reponsible for
143 // 143 //
144 // - Unwrapping the function signature into return type, and parameters 144 // - Unwrapping the function signature into return type, and parameters
145 // - Determining the number of parameters that are bound 145 // - Determining the number of parameters that are bound
146 // - Creating the storage for the bound parameters 146 // - Creating the storage for the bound parameters
147 // - Performing compile-time asserts to avoid error-prone behavior 147 // - Performing compile-time asserts to avoid error-prone behavior
148 // - Returning an InvokerStorageHolder<> with an DoInvoke() that has an arity 148 // - Returning an BindStateHolder<> with an DoInvoke() that has an arity
149 // matching the number of unbound parameters, and knows the correct 149 // matching the number of unbound parameters, and knows the correct
150 // refcounting semantics for the target object if we are binding a class 150 // refcounting semantics for the target object if we are binding a class
151 // method. 151 // method.
152 // 152 //
153 // The Bind functions do the above using type-inference, and template 153 // The Bind functions do the above using type-inference, and template
154 // specializations. 154 // specializations.
155 // 155 //
156 // By default Bind() will store copies of all bound parameters, and attempt 156 // By default Bind() will store copies of all bound parameters, and attempt
157 // to refcount a target object if the function being bound is a class method. 157 // to refcount a target object if the function being bound is a class method.
158 // 158 //
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 // 229 //
230 // After this, create template specializations for 0-6 parameters. Note that 230 // After this, create template specializations for 0-6 parameters. Note that
231 // even though the template typelist grows, the specialization still 231 // even though the template typelist grows, the specialization still
232 // only has one type: the function signature. 232 // only has one type: the function signature.
233 template <typename Sig> 233 template <typename Sig>
234 class Callback; 234 class Callback;
235 235
236 template <typename R> 236 template <typename R>
237 class Callback<R(void)> : public internal::CallbackBase { 237 class Callback<R(void)> : public internal::CallbackBase {
238 public: 238 public:
239 typedef R(*PolymorphicInvoke)( 239 typedef R(RunType)();
240 internal::InvokerStorageBase*);
241 240
242 Callback() : CallbackBase(NULL, NULL) { } 241 Callback() : CallbackBase(NULL, NULL) { }
243 242
244 // We pass InvokerStorageHolder by const ref to avoid incurring an 243 // We pass BindStateHolder by const ref to avoid incurring an
245 // unnecessary AddRef/Unref pair even though we will modify the object. 244 // unnecessary AddRef/Unref pair even though we will modify the object.
246 // We cannot use a normal reference because the compiler will warn 245 // We cannot use a normal reference because the compiler will warn
247 // since this is often used on a return value, which is a temporary. 246 // since this is often used on a return value, which is a temporary.
248 // 247 //
249 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT 248 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
250 // return the exact Callback<> type. See base/bind.h for details. 249 // return the exact Callback<> type. See base/bind.h for details.
251 template <typename T> 250 template <typename T>
252 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) 251 Callback(const internal::BindStateHolder<T>& bind_state_holder)
253 : CallbackBase( 252 : CallbackBase(NULL, &bind_state_holder.bind_state_) {
254 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke), 253 // Force the assignment to a location variable of PolymorphicInvoke
255 &invoker_holder.invoker_storage_) { 254 // so the compiler will typecheck that the passed in Run() method has
256 COMPILE_ASSERT((is_same<PolymorphicInvoke, 255 // the correct type.
257 typename T::Invoker::DoInvokeType>::value), 256 PolymorphicInvoke invoke_func = &T::InvokerType::Run;
258 callback_type_does_not_match_bind_result); 257 polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
259 } 258 }
260 259
261 bool Equals(const Callback& other) const { 260 bool Equals(const Callback& other) const {
262 return CallbackBase::Equals(other); 261 return CallbackBase::Equals(other);
263 } 262 }
264 263
265 R Run() const { 264 R Run() const {
266 PolymorphicInvoke f = 265 PolymorphicInvoke f =
267 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_); 266 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
268 267
269 return f(invoker_storage_.get()); 268 return f(bind_state_.get());
270 } 269 }
270
271 private:
272 typedef R(*PolymorphicInvoke)(
273 internal::BindStateBase*);
274
271 }; 275 };
272 276
273 template <typename R, typename A1> 277 template <typename R, typename A1>
274 class Callback<R(A1)> : public internal::CallbackBase { 278 class Callback<R(A1)> : public internal::CallbackBase {
275 public: 279 public:
276 typedef R(*PolymorphicInvoke)( 280 typedef R(RunType)(A1);
277 internal::InvokerStorageBase*,
278 typename internal::ParamTraits<A1>::ForwardType);
279 281
280 Callback() : CallbackBase(NULL, NULL) { } 282 Callback() : CallbackBase(NULL, NULL) { }
281 283
282 // We pass InvokerStorageHolder by const ref to avoid incurring an 284 // We pass BindStateHolder by const ref to avoid incurring an
283 // unnecessary AddRef/Unref pair even though we will modify the object. 285 // unnecessary AddRef/Unref pair even though we will modify the object.
284 // We cannot use a normal reference because the compiler will warn 286 // We cannot use a normal reference because the compiler will warn
285 // since this is often used on a return value, which is a temporary. 287 // since this is often used on a return value, which is a temporary.
286 // 288 //
287 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT 289 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
288 // return the exact Callback<> type. See base/bind.h for details. 290 // return the exact Callback<> type. See base/bind.h for details.
289 template <typename T> 291 template <typename T>
290 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) 292 Callback(const internal::BindStateHolder<T>& bind_state_holder)
291 : CallbackBase( 293 : CallbackBase(NULL, &bind_state_holder.bind_state_) {
292 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke), 294 // Force the assignment to a location variable of PolymorphicInvoke
293 &invoker_holder.invoker_storage_) { 295 // so the compiler will typecheck that the passed in Run() method has
294 COMPILE_ASSERT((is_same<PolymorphicInvoke, 296 // the correct type.
295 typename T::Invoker::DoInvokeType>::value), 297 PolymorphicInvoke invoke_func = &T::InvokerType::Run;
296 callback_type_does_not_match_bind_result); 298 polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
297 } 299 }
298 300
299 bool Equals(const Callback& other) const { 301 bool Equals(const Callback& other) const {
300 return CallbackBase::Equals(other); 302 return CallbackBase::Equals(other);
301 } 303 }
302 304
303 R Run(typename internal::ParamTraits<A1>::ForwardType a1) const { 305 R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1) const {
304 PolymorphicInvoke f = 306 PolymorphicInvoke f =
305 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_); 307 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
306 308
307 return f(invoker_storage_.get(), a1); 309 return f(bind_state_.get(), a1);
308 } 310 }
311
312 private:
313 typedef R(*PolymorphicInvoke)(
314 internal::BindStateBase*,
315 typename internal::CallbackParamTraits<A1>::ForwardType);
316
309 }; 317 };
310 318
311 template <typename R, typename A1, typename A2> 319 template <typename R, typename A1, typename A2>
312 class Callback<R(A1, A2)> : public internal::CallbackBase { 320 class Callback<R(A1, A2)> : public internal::CallbackBase {
313 public: 321 public:
314 typedef R(*PolymorphicInvoke)( 322 typedef R(RunType)(A1, A2);
315 internal::InvokerStorageBase*,
316 typename internal::ParamTraits<A1>::ForwardType,
317 typename internal::ParamTraits<A2>::ForwardType);
318 323
319 Callback() : CallbackBase(NULL, NULL) { } 324 Callback() : CallbackBase(NULL, NULL) { }
320 325
321 // We pass InvokerStorageHolder by const ref to avoid incurring an 326 // We pass BindStateHolder by const ref to avoid incurring an
322 // unnecessary AddRef/Unref pair even though we will modify the object. 327 // unnecessary AddRef/Unref pair even though we will modify the object.
323 // We cannot use a normal reference because the compiler will warn 328 // We cannot use a normal reference because the compiler will warn
324 // since this is often used on a return value, which is a temporary. 329 // since this is often used on a return value, which is a temporary.
325 // 330 //
326 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT 331 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
327 // return the exact Callback<> type. See base/bind.h for details. 332 // return the exact Callback<> type. See base/bind.h for details.
328 template <typename T> 333 template <typename T>
329 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) 334 Callback(const internal::BindStateHolder<T>& bind_state_holder)
330 : CallbackBase( 335 : CallbackBase(NULL, &bind_state_holder.bind_state_) {
331 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke), 336 // Force the assignment to a location variable of PolymorphicInvoke
332 &invoker_holder.invoker_storage_) { 337 // so the compiler will typecheck that the passed in Run() method has
333 COMPILE_ASSERT((is_same<PolymorphicInvoke, 338 // the correct type.
334 typename T::Invoker::DoInvokeType>::value), 339 PolymorphicInvoke invoke_func = &T::InvokerType::Run;
335 callback_type_does_not_match_bind_result); 340 polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
336 } 341 }
337 342
338 bool Equals(const Callback& other) const { 343 bool Equals(const Callback& other) const {
339 return CallbackBase::Equals(other); 344 return CallbackBase::Equals(other);
340 } 345 }
341 346
342 R Run(typename internal::ParamTraits<A1>::ForwardType a1, 347 R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
343 typename internal::ParamTraits<A2>::ForwardType a2) const { 348 typename internal::CallbackParamTraits<A2>::ForwardType a2) const {
344 PolymorphicInvoke f = 349 PolymorphicInvoke f =
345 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_); 350 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
346 351
347 return f(invoker_storage_.get(), a1, 352 return f(bind_state_.get(), a1,
348 a2); 353 a2);
349 } 354 }
355
356 private:
357 typedef R(*PolymorphicInvoke)(
358 internal::BindStateBase*,
359 typename internal::CallbackParamTraits<A1>::ForwardType,
360 typename internal::CallbackParamTraits<A2>::ForwardType);
361
350 }; 362 };
351 363
352 template <typename R, typename A1, typename A2, typename A3> 364 template <typename R, typename A1, typename A2, typename A3>
353 class Callback<R(A1, A2, A3)> : public internal::CallbackBase { 365 class Callback<R(A1, A2, A3)> : public internal::CallbackBase {
354 public: 366 public:
355 typedef R(*PolymorphicInvoke)( 367 typedef R(RunType)(A1, A2, A3);
356 internal::InvokerStorageBase*,
357 typename internal::ParamTraits<A1>::ForwardType,
358 typename internal::ParamTraits<A2>::ForwardType,
359 typename internal::ParamTraits<A3>::ForwardType);
360 368
361 Callback() : CallbackBase(NULL, NULL) { } 369 Callback() : CallbackBase(NULL, NULL) { }
362 370
363 // We pass InvokerStorageHolder by const ref to avoid incurring an 371 // We pass BindStateHolder by const ref to avoid incurring an
364 // unnecessary AddRef/Unref pair even though we will modify the object. 372 // unnecessary AddRef/Unref pair even though we will modify the object.
365 // We cannot use a normal reference because the compiler will warn 373 // We cannot use a normal reference because the compiler will warn
366 // since this is often used on a return value, which is a temporary. 374 // since this is often used on a return value, which is a temporary.
367 // 375 //
368 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT 376 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
369 // return the exact Callback<> type. See base/bind.h for details. 377 // return the exact Callback<> type. See base/bind.h for details.
370 template <typename T> 378 template <typename T>
371 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) 379 Callback(const internal::BindStateHolder<T>& bind_state_holder)
372 : CallbackBase( 380 : CallbackBase(NULL, &bind_state_holder.bind_state_) {
373 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke), 381 // Force the assignment to a location variable of PolymorphicInvoke
374 &invoker_holder.invoker_storage_) { 382 // so the compiler will typecheck that the passed in Run() method has
375 COMPILE_ASSERT((is_same<PolymorphicInvoke, 383 // the correct type.
376 typename T::Invoker::DoInvokeType>::value), 384 PolymorphicInvoke invoke_func = &T::InvokerType::Run;
377 callback_type_does_not_match_bind_result); 385 polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
378 } 386 }
379 387
380 bool Equals(const Callback& other) const { 388 bool Equals(const Callback& other) const {
381 return CallbackBase::Equals(other); 389 return CallbackBase::Equals(other);
382 } 390 }
383 391
384 R Run(typename internal::ParamTraits<A1>::ForwardType a1, 392 R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
385 typename internal::ParamTraits<A2>::ForwardType a2, 393 typename internal::CallbackParamTraits<A2>::ForwardType a2,
386 typename internal::ParamTraits<A3>::ForwardType a3) const { 394 typename internal::CallbackParamTraits<A3>::ForwardType a3) const {
387 PolymorphicInvoke f = 395 PolymorphicInvoke f =
388 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_); 396 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
389 397
390 return f(invoker_storage_.get(), a1, 398 return f(bind_state_.get(), a1,
391 a2, 399 a2,
392 a3); 400 a3);
393 } 401 }
402
403 private:
404 typedef R(*PolymorphicInvoke)(
405 internal::BindStateBase*,
406 typename internal::CallbackParamTraits<A1>::ForwardType,
407 typename internal::CallbackParamTraits<A2>::ForwardType,
408 typename internal::CallbackParamTraits<A3>::ForwardType);
409
394 }; 410 };
395 411
396 template <typename R, typename A1, typename A2, typename A3, typename A4> 412 template <typename R, typename A1, typename A2, typename A3, typename A4>
397 class Callback<R(A1, A2, A3, A4)> : public internal::CallbackBase { 413 class Callback<R(A1, A2, A3, A4)> : public internal::CallbackBase {
398 public: 414 public:
399 typedef R(*PolymorphicInvoke)( 415 typedef R(RunType)(A1, A2, A3, A4);
400 internal::InvokerStorageBase*,
401 typename internal::ParamTraits<A1>::ForwardType,
402 typename internal::ParamTraits<A2>::ForwardType,
403 typename internal::ParamTraits<A3>::ForwardType,
404 typename internal::ParamTraits<A4>::ForwardType);
405 416
406 Callback() : CallbackBase(NULL, NULL) { } 417 Callback() : CallbackBase(NULL, NULL) { }
407 418
408 // We pass InvokerStorageHolder by const ref to avoid incurring an 419 // We pass BindStateHolder by const ref to avoid incurring an
409 // unnecessary AddRef/Unref pair even though we will modify the object. 420 // unnecessary AddRef/Unref pair even though we will modify the object.
410 // We cannot use a normal reference because the compiler will warn 421 // We cannot use a normal reference because the compiler will warn
411 // since this is often used on a return value, which is a temporary. 422 // since this is often used on a return value, which is a temporary.
412 // 423 //
413 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT 424 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
414 // return the exact Callback<> type. See base/bind.h for details. 425 // return the exact Callback<> type. See base/bind.h for details.
415 template <typename T> 426 template <typename T>
416 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) 427 Callback(const internal::BindStateHolder<T>& bind_state_holder)
417 : CallbackBase( 428 : CallbackBase(NULL, &bind_state_holder.bind_state_) {
418 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke), 429 // Force the assignment to a location variable of PolymorphicInvoke
419 &invoker_holder.invoker_storage_) { 430 // so the compiler will typecheck that the passed in Run() method has
420 COMPILE_ASSERT((is_same<PolymorphicInvoke, 431 // the correct type.
421 typename T::Invoker::DoInvokeType>::value), 432 PolymorphicInvoke invoke_func = &T::InvokerType::Run;
422 callback_type_does_not_match_bind_result); 433 polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
423 } 434 }
424 435
425 bool Equals(const Callback& other) const { 436 bool Equals(const Callback& other) const {
426 return CallbackBase::Equals(other); 437 return CallbackBase::Equals(other);
427 } 438 }
428 439
429 R Run(typename internal::ParamTraits<A1>::ForwardType a1, 440 R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
430 typename internal::ParamTraits<A2>::ForwardType a2, 441 typename internal::CallbackParamTraits<A2>::ForwardType a2,
431 typename internal::ParamTraits<A3>::ForwardType a3, 442 typename internal::CallbackParamTraits<A3>::ForwardType a3,
432 typename internal::ParamTraits<A4>::ForwardType a4) const { 443 typename internal::CallbackParamTraits<A4>::ForwardType a4) const {
433 PolymorphicInvoke f = 444 PolymorphicInvoke f =
434 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_); 445 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
435 446
436 return f(invoker_storage_.get(), a1, 447 return f(bind_state_.get(), a1,
437 a2, 448 a2,
438 a3, 449 a3,
439 a4); 450 a4);
440 } 451 }
452
453 private:
454 typedef R(*PolymorphicInvoke)(
455 internal::BindStateBase*,
456 typename internal::CallbackParamTraits<A1>::ForwardType,
457 typename internal::CallbackParamTraits<A2>::ForwardType,
458 typename internal::CallbackParamTraits<A3>::ForwardType,
459 typename internal::CallbackParamTraits<A4>::ForwardType);
460
441 }; 461 };
442 462
443 template <typename R, typename A1, typename A2, typename A3, typename A4, 463 template <typename R, typename A1, typename A2, typename A3, typename A4,
444 typename A5> 464 typename A5>
445 class Callback<R(A1, A2, A3, A4, A5)> : public internal::CallbackBase { 465 class Callback<R(A1, A2, A3, A4, A5)> : public internal::CallbackBase {
446 public: 466 public:
447 typedef R(*PolymorphicInvoke)( 467 typedef R(RunType)(A1, A2, A3, A4, A5);
448 internal::InvokerStorageBase*,
449 typename internal::ParamTraits<A1>::ForwardType,
450 typename internal::ParamTraits<A2>::ForwardType,
451 typename internal::ParamTraits<A3>::ForwardType,
452 typename internal::ParamTraits<A4>::ForwardType,
453 typename internal::ParamTraits<A5>::ForwardType);
454 468
455 Callback() : CallbackBase(NULL, NULL) { } 469 Callback() : CallbackBase(NULL, NULL) { }
456 470
457 // We pass InvokerStorageHolder by const ref to avoid incurring an 471 // We pass BindStateHolder by const ref to avoid incurring an
458 // unnecessary AddRef/Unref pair even though we will modify the object. 472 // unnecessary AddRef/Unref pair even though we will modify the object.
459 // We cannot use a normal reference because the compiler will warn 473 // We cannot use a normal reference because the compiler will warn
460 // since this is often used on a return value, which is a temporary. 474 // since this is often used on a return value, which is a temporary.
461 // 475 //
462 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT 476 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
463 // return the exact Callback<> type. See base/bind.h for details. 477 // return the exact Callback<> type. See base/bind.h for details.
464 template <typename T> 478 template <typename T>
465 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) 479 Callback(const internal::BindStateHolder<T>& bind_state_holder)
466 : CallbackBase( 480 : CallbackBase(NULL, &bind_state_holder.bind_state_) {
467 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke), 481 // Force the assignment to a location variable of PolymorphicInvoke
468 &invoker_holder.invoker_storage_) { 482 // so the compiler will typecheck that the passed in Run() method has
469 COMPILE_ASSERT((is_same<PolymorphicInvoke, 483 // the correct type.
470 typename T::Invoker::DoInvokeType>::value), 484 PolymorphicInvoke invoke_func = &T::InvokerType::Run;
471 callback_type_does_not_match_bind_result); 485 polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
472 } 486 }
473 487
474 bool Equals(const Callback& other) const { 488 bool Equals(const Callback& other) const {
475 return CallbackBase::Equals(other); 489 return CallbackBase::Equals(other);
476 } 490 }
477 491
478 R Run(typename internal::ParamTraits<A1>::ForwardType a1, 492 R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
479 typename internal::ParamTraits<A2>::ForwardType a2, 493 typename internal::CallbackParamTraits<A2>::ForwardType a2,
480 typename internal::ParamTraits<A3>::ForwardType a3, 494 typename internal::CallbackParamTraits<A3>::ForwardType a3,
481 typename internal::ParamTraits<A4>::ForwardType a4, 495 typename internal::CallbackParamTraits<A4>::ForwardType a4,
482 typename internal::ParamTraits<A5>::ForwardType a5) const { 496 typename internal::CallbackParamTraits<A5>::ForwardType a5) const {
483 PolymorphicInvoke f = 497 PolymorphicInvoke f =
484 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_); 498 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
485 499
486 return f(invoker_storage_.get(), a1, 500 return f(bind_state_.get(), a1,
487 a2, 501 a2,
488 a3, 502 a3,
489 a4, 503 a4,
490 a5); 504 a5);
491 } 505 }
506
507 private:
508 typedef R(*PolymorphicInvoke)(
509 internal::BindStateBase*,
510 typename internal::CallbackParamTraits<A1>::ForwardType,
511 typename internal::CallbackParamTraits<A2>::ForwardType,
512 typename internal::CallbackParamTraits<A3>::ForwardType,
513 typename internal::CallbackParamTraits<A4>::ForwardType,
514 typename internal::CallbackParamTraits<A5>::ForwardType);
515
492 }; 516 };
493 517
494 template <typename R, typename A1, typename A2, typename A3, typename A4, 518 template <typename R, typename A1, typename A2, typename A3, typename A4,
495 typename A5, typename A6> 519 typename A5, typename A6>
496 class Callback<R(A1, A2, A3, A4, A5, A6)> : public internal::CallbackBase { 520 class Callback<R(A1, A2, A3, A4, A5, A6)> : public internal::CallbackBase {
497 public: 521 public:
498 typedef R(*PolymorphicInvoke)( 522 typedef R(RunType)(A1, A2, A3, A4, A5, A6);
499 internal::InvokerStorageBase*,
500 typename internal::ParamTraits<A1>::ForwardType,
501 typename internal::ParamTraits<A2>::ForwardType,
502 typename internal::ParamTraits<A3>::ForwardType,
503 typename internal::ParamTraits<A4>::ForwardType,
504 typename internal::ParamTraits<A5>::ForwardType,
505 typename internal::ParamTraits<A6>::ForwardType);
506 523
507 Callback() : CallbackBase(NULL, NULL) { } 524 Callback() : CallbackBase(NULL, NULL) { }
508 525
509 // We pass InvokerStorageHolder by const ref to avoid incurring an 526 // We pass BindStateHolder by const ref to avoid incurring an
510 // unnecessary AddRef/Unref pair even though we will modify the object. 527 // unnecessary AddRef/Unref pair even though we will modify the object.
511 // We cannot use a normal reference because the compiler will warn 528 // We cannot use a normal reference because the compiler will warn
512 // since this is often used on a return value, which is a temporary. 529 // since this is often used on a return value, which is a temporary.
513 // 530 //
514 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT 531 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
515 // return the exact Callback<> type. See base/bind.h for details. 532 // return the exact Callback<> type. See base/bind.h for details.
516 template <typename T> 533 template <typename T>
517 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) 534 Callback(const internal::BindStateHolder<T>& bind_state_holder)
518 : CallbackBase( 535 : CallbackBase(NULL, &bind_state_holder.bind_state_) {
519 reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke), 536 // Force the assignment to a location variable of PolymorphicInvoke
520 &invoker_holder.invoker_storage_) { 537 // so the compiler will typecheck that the passed in Run() method has
521 COMPILE_ASSERT((is_same<PolymorphicInvoke, 538 // the correct type.
522 typename T::Invoker::DoInvokeType>::value), 539 PolymorphicInvoke invoke_func = &T::InvokerType::Run;
523 callback_type_does_not_match_bind_result); 540 polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
524 } 541 }
525 542
526 bool Equals(const Callback& other) const { 543 bool Equals(const Callback& other) const {
527 return CallbackBase::Equals(other); 544 return CallbackBase::Equals(other);
528 } 545 }
529 546
530 R Run(typename internal::ParamTraits<A1>::ForwardType a1, 547 R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
531 typename internal::ParamTraits<A2>::ForwardType a2, 548 typename internal::CallbackParamTraits<A2>::ForwardType a2,
532 typename internal::ParamTraits<A3>::ForwardType a3, 549 typename internal::CallbackParamTraits<A3>::ForwardType a3,
533 typename internal::ParamTraits<A4>::ForwardType a4, 550 typename internal::CallbackParamTraits<A4>::ForwardType a4,
534 typename internal::ParamTraits<A5>::ForwardType a5, 551 typename internal::CallbackParamTraits<A5>::ForwardType a5,
535 typename internal::ParamTraits<A6>::ForwardType a6) const { 552 typename internal::CallbackParamTraits<A6>::ForwardType a6) const {
536 PolymorphicInvoke f = 553 PolymorphicInvoke f =
537 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_); 554 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
538 555
539 return f(invoker_storage_.get(), a1, 556 return f(bind_state_.get(), a1,
540 a2, 557 a2,
541 a3, 558 a3,
542 a4, 559 a4,
543 a5, 560 a5,
544 a6); 561 a6);
545 } 562 }
563
564 private:
565 typedef R(*PolymorphicInvoke)(
566 internal::BindStateBase*,
567 typename internal::CallbackParamTraits<A1>::ForwardType,
568 typename internal::CallbackParamTraits<A2>::ForwardType,
569 typename internal::CallbackParamTraits<A3>::ForwardType,
570 typename internal::CallbackParamTraits<A4>::ForwardType,
571 typename internal::CallbackParamTraits<A5>::ForwardType,
572 typename internal::CallbackParamTraits<A6>::ForwardType);
573
546 }; 574 };
547 575
548 576
549 // Syntactic sugar to make Callbacks<void(void)> easier to declare since it 577 // Syntactic sugar to make Callbacks<void(void)> easier to declare since it
550 // will be used in a lot of APIs with delayed execution. 578 // will be used in a lot of APIs with delayed execution.
551 typedef Callback<void(void)> Closure; 579 typedef Callback<void(void)> Closure;
552 580
553 } // namespace base 581 } // namespace base
554 582
555 #endif // BASE_CALLBACK_H 583 #endif // BASE_CALLBACK_H
OLDNEW
« no previous file with comments | « base/bind_unittest.nc ('k') | base/callback.h.pump » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698