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 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 // | 334 // |
335 // | 335 // |
336 // MISSING FUNCTIONALITY | 336 // MISSING FUNCTIONALITY |
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 | |
345 namespace base { | |
346 | |
347 // First, we forward declare the Callback class template. This informs the | |
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 // | 344 // |
355 // If you are thinking of forward declaring Callback in your own header file, | 345 // If you are thinking of forward declaring Callback in your own header file, |
356 // please include "base/callback_forward.h" instead. | 346 // please include "base/callback_forward.h" instead. |
357 | 347 |
| 348 namespace base { |
358 namespace internal { | 349 namespace internal { |
| 350 |
359 template <typename Runnable, typename RunType, typename... BoundArgsType> | 351 template <typename Runnable, typename RunType, typename... BoundArgsType> |
360 struct BindState; | 352 struct BindState; |
| 353 |
| 354 template <CopyMode copy_mode> |
| 355 using CallbackBase = typename std::conditional< |
| 356 copy_mode == CopyMode::MoveOnly, |
| 357 MoveOnlyCallbackBase, CopyableCallbackBase>::type; |
| 358 |
361 } // namespace internal | 359 } // namespace internal |
362 | 360 |
363 template <typename R, typename... Args> | 361 template <typename R, typename... Args, |
364 class Callback<R(Args...)> : public internal::CallbackBase { | 362 internal::CopyMode copy_mode> |
| 363 class Callback<R(Args...), copy_mode> |
| 364 : public internal::CallbackBase<copy_mode> { |
365 public: | 365 public: |
366 // MSVC 2013 doesn't support Type Alias of function types. | 366 // MSVC 2013 doesn't support Type Alias of function types. |
367 // Revisit this after we update it to newer version. | 367 // Revisit this after we update it to newer version. |
368 typedef R RunType(Args...); | 368 typedef R RunType(Args...); |
369 | 369 |
370 Callback() : CallbackBase(nullptr) { } | 370 Callback() {} |
371 | 371 |
372 template <typename Runnable, typename BindRunType, typename... BoundArgsType> | 372 template <typename Runnable, typename BindRunType, typename... BoundArgs> |
373 explicit Callback( | 373 explicit Callback( |
374 internal::BindState<Runnable, BindRunType, BoundArgsType...>* bind_state) | 374 internal::BindState<Runnable, BindRunType, BoundArgs...>* bind_state) { |
375 : CallbackBase(bind_state) { | 375 this->set_bind_state(bind_state); |
| 376 |
376 // Force the assignment to a local variable of PolymorphicInvoke | 377 // Force the assignment to a local variable of PolymorphicInvoke |
377 // so the compiler will typecheck that the passed in Run() method has | 378 // so the compiler will typecheck that the passed in Run() method has |
378 // the correct type. | 379 // the correct type. |
379 PolymorphicInvoke invoke_func = | 380 PolymorphicInvoke invoke_func = |
380 &internal::BindState<Runnable, BindRunType, BoundArgsType...> | 381 &internal::BindState<Runnable, BindRunType, BoundArgs...> |
381 ::InvokerType::Run; | 382 ::InvokerType::Run; |
382 polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func); | 383 using InvokeFuncStorage = |
| 384 typename internal::CallbackBase<copy_mode>::InvokeFuncStorage; |
| 385 this->polymorphic_invoke_ = |
| 386 reinterpret_cast<InvokeFuncStorage>(invoke_func); |
383 } | 387 } |
384 | 388 |
385 bool Equals(const Callback& other) const { | 389 bool Equals(const Callback& other) const { |
386 return CallbackBase::Equals(other); | 390 return this->EqualsInternal(other); |
387 } | 391 } |
388 | 392 |
389 R Run(typename internal::CallbackParamTraits<Args>::ForwardType... args) | 393 R Run(typename internal::CallbackParamTraits<Args>::ForwardType... args) |
390 const { | 394 const { |
391 PolymorphicInvoke f = | 395 PolymorphicInvoke f = |
392 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_); | 396 reinterpret_cast<PolymorphicInvoke>(this->polymorphic_invoke_); |
393 | 397 return f(this->bind_state_.get(), internal::CallbackForward(args)...); |
394 return f(bind_state_.get(), internal::CallbackForward(args)...); | |
395 } | 398 } |
396 | 399 |
397 private: | 400 private: |
398 using PolymorphicInvoke = | 401 using PolymorphicInvoke = |
399 R(*)(internal::BindStateBase*, | 402 R(*)(internal::BindStateBase*, |
400 typename internal::CallbackParamTraits<Args>::ForwardType...); | 403 typename internal::CallbackParamTraits<Args>::ForwardType...); |
401 }; | 404 }; |
402 | 405 |
403 } // namespace base | 406 } // namespace base |
404 | 407 |
405 #endif // BASE_CALLBACK_H_ | 408 #endif // BASE_CALLBACK_H_ |
OLD | NEW |