| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_BIND_INTERNAL_H_ | 5 #ifndef BASE_BIND_INTERNAL_H_ |
| 6 #define BASE_BIND_INTERNAL_H_ | 6 #define BASE_BIND_INTERNAL_H_ |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include <type_traits> | 10 #include <type_traits> |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 // We need a InvokeHelper to handle void return types in order to support | 286 // We need a InvokeHelper to handle void return types in order to support |
| 287 // IgnoreResult(). Normally, if the Runnable's RunType had a void return, | 287 // IgnoreResult(). Normally, if the Runnable's RunType had a void return, |
| 288 // the template system would just accept "return functor.Run()" ignoring | 288 // the template system would just accept "return functor.Run()" ignoring |
| 289 // the fact that a void function is being used with return. This piece of | 289 // the fact that a void function is being used with return. This piece of |
| 290 // sugar breaks though when the Runnable's RunType is not void. Thus, we | 290 // sugar breaks though when the Runnable's RunType is not void. Thus, we |
| 291 // need a partial specialization to change the syntax to drop the "return" | 291 // need a partial specialization to change the syntax to drop the "return" |
| 292 // from the invocation call. | 292 // from the invocation call. |
| 293 // | 293 // |
| 294 // WeakCalls similarly need special syntax that is applied to the first | 294 // WeakCalls similarly need special syntax that is applied to the first |
| 295 // argument to check if they should no-op themselves. | 295 // argument to check if they should no-op themselves. |
| 296 template <bool IsWeakCall, typename ReturnType, typename Runnable> | 296 template <bool is_weak_call, typename ReturnType> |
| 297 struct InvokeHelper; | 297 struct InvokeHelper; |
| 298 | 298 |
| 299 template <typename ReturnType, typename Runnable> | 299 template <typename ReturnType> |
| 300 struct InvokeHelper<false, ReturnType, Runnable> { | 300 struct InvokeHelper<false, ReturnType> { |
| 301 template <typename... RunArgs> | 301 template <typename Runnable, typename... RunArgs> |
| 302 static ReturnType MakeItSo(Runnable runnable, RunArgs&&... args) { | 302 static ReturnType MakeItSo(Runnable&& runnable, RunArgs&&... args) { |
| 303 return runnable.Run(std::forward<RunArgs>(args)...); | 303 return std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...); |
| 304 } | 304 } |
| 305 }; | 305 }; |
| 306 | 306 |
| 307 template <typename Runnable> | 307 template <> |
| 308 struct InvokeHelper<false, void, Runnable> { | 308 struct InvokeHelper<false, void> { |
| 309 template <typename... RunArgs> | 309 template <typename Runnable, typename... RunArgs> |
| 310 static void MakeItSo(Runnable runnable, RunArgs&&... args) { | 310 static void MakeItSo(Runnable&& runnable, RunArgs&&... args) { |
| 311 runnable.Run(std::forward<RunArgs>(args)...); | 311 std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...); |
| 312 } | 312 } |
| 313 }; | 313 }; |
| 314 | 314 |
| 315 template <typename Runnable> | 315 template <> |
| 316 struct InvokeHelper<true, void, Runnable> { | 316 struct InvokeHelper<true, void> { |
| 317 template <typename BoundWeakPtr, typename... RunArgs> | 317 template <typename Runnable, typename BoundWeakPtr, typename... RunArgs> |
| 318 static void MakeItSo(Runnable runnable, | 318 static void MakeItSo(Runnable&& runnable, |
| 319 BoundWeakPtr weak_ptr, | 319 BoundWeakPtr weak_ptr, |
| 320 RunArgs&&... args) { | 320 RunArgs&&... args) { |
| 321 if (!weak_ptr.get()) { | 321 if (!weak_ptr.get()) { |
| 322 return; | 322 return; |
| 323 } | 323 } |
| 324 runnable.Run(weak_ptr.get(), std::forward<RunArgs>(args)...); | 324 std::forward<Runnable>(runnable).Run( |
| 325 weak_ptr.get(), std::forward<RunArgs>(args)...); |
| 325 } | 326 } |
| 326 }; | 327 }; |
| 327 | 328 |
| 328 #if !defined(_MSC_VER) | 329 #if !defined(_MSC_VER) |
| 329 | 330 |
| 330 template <typename ReturnType, typename Runnable> | 331 template <typename ReturnType> |
| 331 struct InvokeHelper<true, ReturnType, Runnable> { | 332 struct InvokeHelper<true, ReturnType> { |
| 332 // WeakCalls are only supported for functions with a void return type. | 333 // WeakCalls are only supported for functions with a void return type. |
| 333 // Otherwise, the function result would be undefined if the the WeakPtr<> | 334 // Otherwise, the function result would be undefined if the the WeakPtr<> |
| 334 // is invalidated. | 335 // is invalidated. |
| 335 static_assert(std::is_void<ReturnType>::value, | 336 static_assert(std::is_void<ReturnType>::value, |
| 336 "weak_ptrs can only bind to methods without return values"); | 337 "weak_ptrs can only bind to methods without return values"); |
| 337 }; | 338 }; |
| 338 | 339 |
| 339 #endif | 340 #endif |
| 340 | 341 |
| 341 // Invoker<> | 342 // Invoker<> |
| 342 // | 343 // |
| 343 // See description at the top of the file. | 344 // See description at the top of the file. |
| 344 template <typename BoundIndices, typename StorageType, | 345 template <typename BoundIndices, typename StorageType, |
| 345 typename InvokeHelperType, typename UnboundForwardRunType> | 346 bool is_weak_call, typename UnboundForwardRunType> |
| 346 struct Invoker; | 347 struct Invoker; |
| 347 | 348 |
| 348 template <size_t... bound_indices, | 349 template <size_t... bound_indices, |
| 349 typename StorageType, | 350 typename StorageType, |
| 350 typename InvokeHelperType, | 351 bool is_weak_call, |
| 351 typename R, | 352 typename R, |
| 352 typename... UnboundArgs> | 353 typename... UnboundArgs> |
| 353 struct Invoker<IndexSequence<bound_indices...>, | 354 struct Invoker<IndexSequence<bound_indices...>, |
| 354 StorageType, | 355 StorageType, |
| 355 InvokeHelperType, | 356 is_weak_call, |
| 356 R(UnboundArgs...)> { | 357 R(UnboundArgs...)> { |
| 357 static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) { | 358 static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) { |
| 358 StorageType* storage = static_cast<StorageType*>(base); | 359 StorageType* storage = static_cast<StorageType*>(base); |
| 359 // Local references to make debugger stepping easier. If in a debugger, | 360 // Local references to make debugger stepping easier. If in a debugger, |
| 360 // you really want to warp ahead and step through the | 361 // you really want to warp ahead and step through the |
| 361 // InvokeHelper<>::MakeItSo() call below. | 362 // InvokeHelper<>::MakeItSo() call below. |
| 362 return InvokeHelperType::MakeItSo( | 363 return InvokeHelper<is_weak_call, R>::MakeItSo( |
| 363 storage->runnable_, Unwrap(get<bound_indices>(storage->bound_args_))..., | 364 storage->runnable_, Unwrap(get<bound_indices>(storage->bound_args_))..., |
| 364 std::forward<UnboundArgs>(unbound_args)...); | 365 std::forward<UnboundArgs>(unbound_args)...); |
| 365 } | 366 } |
| 366 }; | 367 }; |
| 367 | 368 |
| 368 // Used to implement MakeArgsStorage. | 369 // Used to implement MakeArgsStorage. |
| 369 template <bool is_method, typename... BoundArgs> | 370 template <bool is_method, typename... BoundArgs> |
| 370 struct MakeArgsStorageImpl { | 371 struct MakeArgsStorageImpl { |
| 371 using Type = std::tuple<BoundArgs...>; | 372 using Type = std::tuple<BoundArgs...>; |
| 372 }; | 373 }; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 399 struct BindState; | 400 struct BindState; |
| 400 | 401 |
| 401 template <typename Runnable, | 402 template <typename Runnable, |
| 402 typename R, | 403 typename R, |
| 403 typename... Args, | 404 typename... Args, |
| 404 typename... BoundArgs> | 405 typename... BoundArgs> |
| 405 struct BindState<Runnable, R(Args...), BoundArgs...> final | 406 struct BindState<Runnable, R(Args...), BoundArgs...> final |
| 406 : public BindStateBase { | 407 : public BindStateBase { |
| 407 private: | 408 private: |
| 408 using StorageType = BindState<Runnable, R(Args...), BoundArgs...>; | 409 using StorageType = BindState<Runnable, R(Args...), BoundArgs...>; |
| 409 using RunnableType = Runnable; | 410 using RunnableType = typename std::decay<Runnable>::type; |
| 410 | 411 |
| 411 enum { is_method = HasIsMethodTag<Runnable>::value }; | 412 enum { is_method = HasIsMethodTag<RunnableType>::value }; |
| 412 | 413 enum { is_weak_call = IsWeakMethod< |
| 413 // true_type if Runnable is a method invocation and the first bound argument | 414 is_method, typename std::decay<BoundArgs>::type...>::value}; |
| 414 // is a WeakPtr. | |
| 415 using IsWeakCall = | |
| 416 IsWeakMethod<is_method, typename std::decay<BoundArgs>::type...>; | |
| 417 | 415 |
| 418 using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>; | 416 using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>; |
| 419 using InvokeHelperType = InvokeHelper<IsWeakCall::value, R, Runnable>; | |
| 420 | |
| 421 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>; | 417 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>; |
| 422 | 418 |
| 423 public: | 419 public: |
| 424 using UnboundRunType = MakeFunctionType<R, UnboundArgs>; | 420 using UnboundRunType = MakeFunctionType<R, UnboundArgs>; |
| 425 using InvokerType = | 421 using InvokerType = |
| 426 Invoker<BoundIndices, StorageType, InvokeHelperType, UnboundRunType>; | 422 Invoker<BoundIndices, StorageType, is_weak_call, UnboundRunType>; |
| 427 | 423 |
| 428 template <typename... ForwardArgs> | 424 template <typename... ForwardArgs> |
| 429 BindState(const Runnable& runnable, ForwardArgs&&... bound_args) | 425 BindState(RunnableType runnable, ForwardArgs&&... bound_args) |
| 430 : BindStateBase(&Destroy), | 426 : BindStateBase(&Destroy), |
| 431 runnable_(runnable), | 427 runnable_(std::move(runnable)), |
| 432 bound_args_(std::forward<ForwardArgs>(bound_args)...) {} | 428 bound_args_(std::forward<ForwardArgs>(bound_args)...) {} |
| 433 | 429 |
| 434 RunnableType runnable_; | 430 RunnableType runnable_; |
| 435 MakeArgsStorage<is_method, BoundArgs...> bound_args_; | 431 MakeArgsStorage<is_method, BoundArgs...> bound_args_; |
| 436 | 432 |
| 437 private: | 433 private: |
| 438 ~BindState() {} | 434 ~BindState() {} |
| 439 | 435 |
| 440 static void Destroy(BindStateBase* self) { | 436 static void Destroy(BindStateBase* self) { |
| 441 delete static_cast<BindState*>(self); | 437 delete static_cast<BindState*>(self); |
| 442 } | 438 } |
| 443 }; | 439 }; |
| 444 | 440 |
| 445 } // namespace internal | 441 } // namespace internal |
| 446 } // namespace base | 442 } // namespace base |
| 447 | 443 |
| 448 #endif // BASE_BIND_INTERNAL_H_ | 444 #endif // BASE_BIND_INTERNAL_H_ |
| OLD | NEW |