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 #include "base/template_util.h" | 10 #include "base/template_util.h" |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 337 // - Invoking the return of Bind. Bind(&foo).Run() does not work; | 337 // - Invoking the return of Bind. Bind(&foo).Run() does not work; |
| 338 // - Binding arrays to functions that take a non-const pointer. | 338 // - Binding arrays to functions that take a non-const pointer. |
| 339 // Example: | 339 // Example: |
| 340 // void Foo(const char* ptr); | 340 // void Foo(const char* ptr); |
| 341 // void Bar(char* ptr); | 341 // void Bar(char* ptr); |
| 342 // Bind(&Foo, "test"); | 342 // Bind(&Foo, "test"); |
| 343 // Bind(&Bar, "test"); // This fails because ptr is not const. | 343 // Bind(&Bar, "test"); // This fails because ptr is not const. |
| 344 | 344 |
| 345 namespace base { | 345 namespace base { |
| 346 | 346 |
| 347 // First, we forward declare the Callback class template. This informs the | 347 namespace internal { |
| 348 // compiler that the template only has 1 type parameter which is the function | |
| 349 // signature that the Callback is representing. | |
| 350 // | |
| 351 // After this, create template specializations for 0-7 parameters. Note that | |
| 352 // even though the template typelist grows, the specialization still | |
| 353 // only has one type: the function signature. | |
| 354 // | |
| 355 // If you are thinking of forward declaring Callback in your own header file, | |
| 356 // please include "base/callback_forward.h" instead. | |
|
Nico
2016/02/15 21:47:57
This paragraph could maybe stay?
tzik
2016/02/16 09:33:32
Done.
| |
| 357 | 348 |
| 358 namespace internal { | |
| 359 template <typename Runnable, typename RunType, typename... BoundArgsType> | 349 template <typename Runnable, typename RunType, typename... BoundArgsType> |
| 360 struct BindState; | 350 struct BindState; |
| 351 | |
| 352 template <CopyMode copy_mode> | |
| 353 using CallbackBase = typename std::conditional< | |
| 354 copy_mode == CopyMode::MoveOnly, | |
| 355 MoveOnlyCallbackBase, CopyableCallbackBase>::type; | |
| 356 | |
| 361 } // namespace internal | 357 } // namespace internal |
| 362 | 358 |
| 363 template <typename R, typename... Args> | 359 template <typename R, typename... Args, |
| 364 class Callback<R(Args...)> : public internal::CallbackBase { | 360 internal::CopyMode copy_mode> |
| 361 class Callback<R(Args...), copy_mode> | |
| 362 : public internal::CallbackBase<copy_mode> { | |
| 365 public: | 363 public: |
| 366 // MSVC 2013 doesn't support Type Alias of function types. | 364 // MSVC 2013 doesn't support Type Alias of function types. |
| 367 // Revisit this after we update it to newer version. | 365 // Revisit this after we update it to newer version. |
| 368 typedef R RunType(Args...); | 366 typedef R RunType(Args...); |
| 369 | 367 |
| 370 Callback() : CallbackBase(nullptr) { } | 368 Callback() {} |
| 371 | 369 |
| 372 template <typename Runnable, typename BindRunType, typename... BoundArgsType> | 370 template <typename Runnable, typename BindRunType, typename... BoundArgs> |
| 373 explicit Callback( | 371 explicit Callback( |
| 374 internal::BindState<Runnable, BindRunType, BoundArgsType...>* bind_state) | 372 internal::BindState<Runnable, BindRunType, BoundArgs...>* bind_state) { |
| 375 : CallbackBase(bind_state) { | 373 this->set_bind_state(bind_state); |
|
Nico
2016/02/15 21:47:57
i'm a bit surpised the this-> wasn't necessary bef
| |
| 374 | |
| 376 // Force the assignment to a local variable of PolymorphicInvoke | 375 // Force the assignment to a local variable of PolymorphicInvoke |
| 377 // so the compiler will typecheck that the passed in Run() method has | 376 // so the compiler will typecheck that the passed in Run() method has |
| 378 // the correct type. | 377 // the correct type. |
| 379 PolymorphicInvoke invoke_func = | 378 PolymorphicInvoke invoke_func = |
| 380 &internal::BindState<Runnable, BindRunType, BoundArgsType...> | 379 &internal::BindState<Runnable, BindRunType, BoundArgs...> |
| 381 ::InvokerType::Run; | 380 ::InvokerType::Run; |
| 382 polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func); | 381 using InvokeFuncStorage = |
| 382 typename internal::CallbackBase<copy_mode>::InvokeFuncStorage; | |
| 383 this->polymorphic_invoke_ = | |
| 384 reinterpret_cast<InvokeFuncStorage>(invoke_func); | |
| 383 } | 385 } |
| 384 | 386 |
| 385 bool Equals(const Callback& other) const { | 387 bool Equals(const Callback& other) const { |
| 386 return CallbackBase::Equals(other); | 388 return this->EqualsInternal(other); |
| 387 } | 389 } |
| 388 | 390 |
| 389 R Run(typename internal::CallbackParamTraits<Args>::ForwardType... args) | 391 R Run(typename internal::CallbackParamTraits<Args>::ForwardType... args) |
| 390 const { | 392 const { |
| 391 PolymorphicInvoke f = | 393 PolymorphicInvoke f = |
| 392 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_); | 394 reinterpret_cast<PolymorphicInvoke>(this->polymorphic_invoke_); |
| 393 | 395 return f(this->bind_state_.get(), internal::CallbackForward(args)...); |
| 394 return f(bind_state_.get(), internal::CallbackForward(args)...); | |
| 395 } | 396 } |
| 396 | 397 |
| 397 private: | 398 private: |
| 398 using PolymorphicInvoke = | 399 using PolymorphicInvoke = |
| 399 R(*)(internal::BindStateBase*, | 400 R(*)(internal::BindStateBase*, |
| 400 typename internal::CallbackParamTraits<Args>::ForwardType...); | 401 typename internal::CallbackParamTraits<Args>::ForwardType...); |
| 401 }; | 402 }; |
| 402 | 403 |
| 403 } // namespace base | 404 } // namespace base |
| 404 | 405 |
| 405 #endif // BASE_CALLBACK_H_ | 406 #endif // BASE_CALLBACK_H_ |
| OLD | NEW |