Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_CALLBACK_H_ | 5 #ifndef BASE_CALLBACK_H_ |
| 6 #define BASE_CALLBACK_H_ | 6 #define BASE_CALLBACK_H_ |
| 7 | 7 |
| 8 #include "base/callback_forward.h" | 8 #include "base/callback_forward.h" |
| 9 #include "base/callback_internal.h" | 9 #include "base/callback_internal.h" |
| 10 | 10 |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 338 // Example: | 338 // Example: |
| 339 // void Foo(const char* ptr); | 339 // void Foo(const char* ptr); |
| 340 // void Bar(char* ptr); | 340 // void Bar(char* ptr); |
| 341 // Bind(&Foo, "test"); | 341 // Bind(&Foo, "test"); |
| 342 // Bind(&Bar, "test"); // This fails because ptr is not const. | 342 // Bind(&Bar, "test"); // This fails because ptr is not const. |
| 343 // | 343 // |
| 344 // If you are thinking of forward declaring Callback in your own header file, | 344 // If you are thinking of forward declaring Callback in your own header file, |
| 345 // please include "base/callback_forward.h" instead. | 345 // please include "base/callback_forward.h" instead. |
| 346 | 346 |
| 347 namespace base { | 347 namespace base { |
| 348 namespace internal { | |
| 349 template <typename Runnable, typename RunType, typename... BoundArgsType> | |
| 350 struct BindState; | |
| 351 } // namespace internal | |
| 352 | 348 |
| 353 template <typename R, typename... Args, internal::CopyMode copy_mode> | 349 template <typename R, typename... Args, internal::CopyMode copy_mode> |
| 354 class Callback<R(Args...), copy_mode> | 350 class Callback<R(Args...), copy_mode> |
| 355 : public internal::CallbackBase<copy_mode> { | 351 : public internal::CallbackBase<copy_mode> { |
| 352 private: | |
| 353 using PolymorphicInvoke = R (*)(internal::BindStateBase*, Args&&...); | |
| 356 public: | 354 public: |
| 355 | |
| 357 // MSVC 2013 doesn't support Type Alias of function types. | 356 // MSVC 2013 doesn't support Type Alias of function types. |
| 358 // Revisit this after we update it to newer version. | 357 // Revisit this after we update it to newer version. |
|
Nico
2016/06/02 17:27:44
we could revisit this now
tzik
2016/06/03 13:29:52
Let me do it in a separate CL.
| |
| 359 typedef R RunType(Args...); | 358 typedef R RunType(Args...); |
| 360 | 359 |
| 361 Callback() : internal::CallbackBase<copy_mode>(nullptr) {} | 360 Callback() : internal::CallbackBase<copy_mode>(nullptr) {} |
| 362 | 361 |
| 363 template <typename Runnable, typename BindRunType, typename... BoundArgs> | 362 Callback(internal::BindStateBase* bind_state, |
| 364 explicit Callback( | 363 PolymorphicInvoke invoke_func) |
| 365 internal::BindState<Runnable, BindRunType, BoundArgs...>* bind_state) | |
| 366 : internal::CallbackBase<copy_mode>(bind_state) { | 364 : internal::CallbackBase<copy_mode>(bind_state) { |
| 367 // Force the assignment to a local variable of PolymorphicInvoke | |
| 368 // so the compiler will typecheck that the passed in Run() method has | |
| 369 // the correct type. | |
| 370 PolymorphicInvoke invoke_func = | |
| 371 &internal::BindState<Runnable, BindRunType, BoundArgs...> | |
| 372 ::InvokerType::Run; | |
| 373 using InvokeFuncStorage = | 365 using InvokeFuncStorage = |
| 374 typename internal::CallbackBase<copy_mode>::InvokeFuncStorage; | 366 typename internal::CallbackBase<copy_mode>::InvokeFuncStorage; |
| 375 this->polymorphic_invoke_ = | 367 this->polymorphic_invoke_ = |
| 376 reinterpret_cast<InvokeFuncStorage>(invoke_func); | 368 reinterpret_cast<InvokeFuncStorage>(invoke_func); |
| 377 } | 369 } |
| 378 | 370 |
| 379 bool Equals(const Callback& other) const { | 371 bool Equals(const Callback& other) const { |
| 380 return this->EqualsInternal(other); | 372 return this->EqualsInternal(other); |
| 381 } | 373 } |
| 382 | 374 |
| 383 // Run() makes an extra copy compared to directly calling the bound function | 375 // Run() makes an extra copy compared to directly calling the bound function |
| 384 // if an argument is passed-by-value and is copyable-but-not-movable: | 376 // if an argument is passed-by-value and is copyable-but-not-movable: |
| 385 // i.e. below copies CopyableNonMovableType twice. | 377 // i.e. below copies CopyableNonMovableType twice. |
| 386 // void F(CopyableNonMovableType) {} | 378 // void F(CopyableNonMovableType) {} |
| 387 // Bind(&F).Run(CopyableNonMovableType()); | 379 // Bind(&F).Run(CopyableNonMovableType()); |
| 388 // | 380 // |
| 389 // We can not fully apply Perfect Forwarding idiom to the callchain from | 381 // We can not fully apply Perfect Forwarding idiom to the callchain from |
| 390 // Callback::Run() to the target function. Perfect Forwarding requires | 382 // Callback::Run() to the target function. Perfect Forwarding requires |
| 391 // knowing how the caller will pass the arguments. However, the signature of | 383 // knowing how the caller will pass the arguments. However, the signature of |
| 392 // InvokerType::Run() needs to be fixed in the callback constructor, so Run() | 384 // InvokerType::Run() needs to be fixed in the callback constructor, so Run() |
| 393 // cannot template its arguments based on how it's called. | 385 // cannot template its arguments based on how it's called. |
| 394 R Run(Args... args) const { | 386 R Run(Args... args) const { |
| 395 PolymorphicInvoke f = | 387 PolymorphicInvoke f = |
| 396 reinterpret_cast<PolymorphicInvoke>(this->polymorphic_invoke_); | 388 reinterpret_cast<PolymorphicInvoke>(this->polymorphic_invoke_); |
| 397 return f(this->bind_state_.get(), std::forward<Args>(args)...); | 389 return f(this->bind_state_.get(), std::forward<Args>(args)...); |
| 398 } | 390 } |
| 399 | |
| 400 private: | |
| 401 using PolymorphicInvoke = R (*)(internal::BindStateBase*, Args&&...); | |
| 402 }; | 391 }; |
| 403 | 392 |
| 404 } // namespace base | 393 } // namespace base |
| 405 | 394 |
| 406 #endif // BASE_CALLBACK_H_ | 395 #endif // BASE_CALLBACK_H_ |
| OLD | NEW |