| 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 <tuple> | 10 #include <tuple> |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 // from the invocation call. | 293 // from the invocation call. |
| 294 // | 294 // |
| 295 // WeakCalls similarly need special syntax that is applied to the first | 295 // WeakCalls similarly need special syntax that is applied to the first |
| 296 // argument to check if they should no-op themselves. | 296 // argument to check if they should no-op themselves. |
| 297 template <bool is_weak_call, typename ReturnType> | 297 template <bool is_weak_call, typename ReturnType> |
| 298 struct InvokeHelper; | 298 struct InvokeHelper; |
| 299 | 299 |
| 300 template <typename ReturnType> | 300 template <typename ReturnType> |
| 301 struct InvokeHelper<false, ReturnType> { | 301 struct InvokeHelper<false, ReturnType> { |
| 302 template <typename Runnable, typename... RunArgs> | 302 template <typename Runnable, typename... RunArgs> |
| 303 static ReturnType MakeItSo(Runnable&& runnable, RunArgs&&... args) { | 303 static inline ReturnType MakeItSo(Runnable&& runnable, RunArgs&&... args) { |
| 304 return std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...); | 304 return std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...); |
| 305 } | 305 } |
| 306 }; | 306 }; |
| 307 | 307 |
| 308 template <> | 308 template <> |
| 309 struct InvokeHelper<false, void> { | 309 struct InvokeHelper<false, void> { |
| 310 template <typename Runnable, typename... RunArgs> | 310 template <typename Runnable, typename... RunArgs> |
| 311 static void MakeItSo(Runnable&& runnable, RunArgs&&... args) { | 311 static inline void MakeItSo(Runnable&& runnable, RunArgs&&... args) { |
| 312 std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...); | 312 std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...); |
| 313 } | 313 } |
| 314 }; | 314 }; |
| 315 | 315 |
| 316 template <> | 316 template <> |
| 317 struct InvokeHelper<true, void> { | 317 struct InvokeHelper<true, void> { |
| 318 template <typename Runnable, typename BoundWeakPtr, typename... RunArgs> | 318 template <typename Runnable, typename BoundWeakPtr, typename... RunArgs> |
| 319 static void MakeItSo(Runnable&& runnable, | 319 static void MakeItSo(Runnable&& runnable, |
| 320 BoundWeakPtr&& weak_ptr, | 320 BoundWeakPtr&& weak_ptr, |
| 321 RunArgs&&... args) { | 321 RunArgs&&... args) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 336 // is invalidated. | 336 // is invalidated. |
| 337 static_assert(std::is_void<ReturnType>::value, | 337 static_assert(std::is_void<ReturnType>::value, |
| 338 "weak_ptrs can only bind to methods without return values"); | 338 "weak_ptrs can only bind to methods without return values"); |
| 339 }; | 339 }; |
| 340 | 340 |
| 341 #endif | 341 #endif |
| 342 | 342 |
| 343 // Invoker<> | 343 // Invoker<> |
| 344 // | 344 // |
| 345 // See description at the top of the file. | 345 // See description at the top of the file. |
| 346 template <typename BoundIndices, typename StorageType, | 346 template <typename StorageType, typename UnboundRunType> |
| 347 bool is_weak_call, typename UnboundForwardRunType> | |
| 348 struct Invoker; | 347 struct Invoker; |
| 349 | 348 |
| 350 template <size_t... bound_indices, | 349 template <typename StorageType, typename R, typename... UnboundArgs> |
| 351 typename StorageType, | 350 struct Invoker<StorageType, R(UnboundArgs...)> { |
| 352 bool is_weak_call, | |
| 353 typename R, | |
| 354 typename... UnboundArgs> | |
| 355 struct Invoker<IndexSequence<bound_indices...>, | |
| 356 StorageType, | |
| 357 is_weak_call, | |
| 358 R(UnboundArgs...)> { | |
| 359 static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) { | 351 static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) { |
| 360 const StorageType* storage = static_cast<StorageType*>(base); | |
| 361 // Local references to make debugger stepping easier. If in a debugger, | 352 // Local references to make debugger stepping easier. If in a debugger, |
| 362 // you really want to warp ahead and step through the | 353 // you really want to warp ahead and step through the |
| 363 // InvokeHelper<>::MakeItSo() call below. | 354 // InvokeHelper<>::MakeItSo() call below. |
| 355 const StorageType* storage = static_cast<StorageType*>(base); |
| 356 static constexpr size_t num_bound_args = |
| 357 std::tuple_size<decltype(storage->bound_args_)>::value; |
| 358 return RunImpl(storage->runnable_, |
| 359 storage->bound_args_, |
| 360 MakeIndexSequence<num_bound_args>(), |
| 361 std::forward<UnboundArgs>(unbound_args)...); |
| 362 } |
| 363 |
| 364 template <typename Runnable, typename BoundArgsTuple, size_t... indices> |
| 365 static inline R RunImpl(Runnable&& runnable, |
| 366 BoundArgsTuple&& bound, |
| 367 IndexSequence<indices...>, |
| 368 UnboundArgs&&... unbound_args) { |
| 369 static constexpr bool is_method = |
| 370 HasIsMethodTag<typename std::decay<Runnable>::type>::value; |
| 371 |
| 372 using DecayedArgsTuple = typename std::decay<BoundArgsTuple>::type; |
| 373 static constexpr bool is_weak_call = |
| 374 IsWeakMethod<is_method, |
| 375 typename std::tuple_element< |
| 376 indices, |
| 377 DecayedArgsTuple>::type...>::value; |
| 378 |
| 364 return InvokeHelper<is_weak_call, R>::MakeItSo( | 379 return InvokeHelper<is_weak_call, R>::MakeItSo( |
| 365 storage->runnable_, | 380 std::forward<Runnable>(runnable), |
| 366 Unwrap(std::get<bound_indices>(storage->bound_args_))..., | 381 Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))..., |
| 367 std::forward<UnboundArgs>(unbound_args)...); | 382 std::forward<UnboundArgs>(unbound_args)...); |
| 368 } | 383 } |
| 369 }; | 384 }; |
| 370 | 385 |
| 371 // Used to implement MakeArgsStorage. | 386 // Used to implement MakeArgsStorage. |
| 372 template <bool is_method, typename... BoundArgs> | 387 template <bool is_method, typename... BoundArgs> |
| 373 struct MakeArgsStorageImpl { | 388 struct MakeArgsStorageImpl { |
| 374 using Type = std::tuple<BoundArgs...>; | 389 using Type = std::tuple<BoundArgs...>; |
| 375 }; | 390 }; |
| 376 | 391 |
| 377 template <typename Obj, typename... BoundArgs> | 392 template <typename Obj, typename... BoundArgs> |
| 378 struct MakeArgsStorageImpl<true, Obj*, BoundArgs...> { | 393 struct MakeArgsStorageImpl<true, Obj*, BoundArgs...> { |
| 379 using Type = std::tuple<scoped_refptr<Obj>, BoundArgs...>; | 394 using Type = std::tuple<scoped_refptr<Obj>, BoundArgs...>; |
| 380 }; | 395 }; |
| 381 | 396 |
| 382 // Constructs a tuple type to store BoundArgs into BindState. | 397 // Constructs a tuple type to store BoundArgs into BindState. |
| 383 // This wraps the first argument into a scoped_refptr if |is_method| is true and | 398 // This wraps the first argument into a scoped_refptr if |is_method| is true and |
| 384 // the first argument is a raw pointer. | 399 // the first argument is a raw pointer. |
| 385 // Other arguments are adjusted for store and packed into a tuple. | 400 // Other arguments are adjusted for store and packed into a tuple. |
| 386 template <bool is_method, typename... BoundArgs> | 401 template <bool is_method, typename... BoundArgs> |
| 387 using MakeArgsStorage = typename MakeArgsStorageImpl< | 402 using MakeArgsStorage = typename MakeArgsStorageImpl< |
| 388 is_method, typename std::decay<BoundArgs>::type...>::Type; | 403 is_method, typename std::decay<BoundArgs>::type...>::Type; |
| 389 | 404 |
| 405 // Used to implement MakeUnboundRunType. |
| 406 template <typename Functor, typename... BoundArgs> |
| 407 struct MakeUnboundRunTypeImpl { |
| 408 using RunType = typename FunctorTraits<Functor>::RunType; |
| 409 using ReturnType = ExtractReturnType<RunType>; |
| 410 using Args = ExtractArgs<RunType>; |
| 411 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), Args>; |
| 412 using Type = MakeFunctionType<ReturnType, UnboundArgs>; |
| 413 }; |
| 414 |
| 390 // BindState<> | 415 // BindState<> |
| 391 // | 416 // |
| 392 // This stores all the state passed into Bind() and is also where most | 417 // This stores all the state passed into Bind() and is also where most |
| 393 // of the template resolution magic occurs. | 418 // of the template resolution magic occurs. |
| 394 // | 419 // |
| 395 // Runnable is the functor we are binding arguments to. | 420 // Runnable is the functor we are binding arguments to. |
| 396 // RunType is type of the Run() function that the Invoker<> should use. | |
| 397 // Normally, this is the same as the RunType of the Runnable, but it can | |
| 398 // be different if an adapter like IgnoreResult() has been used. | |
| 399 // | 421 // |
| 400 // BoundArgs contains the storage type for all the bound arguments. | 422 // BoundArgs contains the storage type for all the bound arguments. |
| 401 template <typename Runnable, typename RunType, typename... BoundArgs> | 423 template <typename Runnable, typename... BoundArgs> |
| 402 struct BindState; | 424 struct BindState final : public BindStateBase { |
| 403 | |
| 404 template <typename Runnable, | |
| 405 typename R, | |
| 406 typename... Args, | |
| 407 typename... BoundArgs> | |
| 408 struct BindState<Runnable, R(Args...), BoundArgs...> final | |
| 409 : public BindStateBase { | |
| 410 private: | 425 private: |
| 411 using StorageType = BindState<Runnable, R(Args...), BoundArgs...>; | |
| 412 using RunnableType = typename std::decay<Runnable>::type; | 426 using RunnableType = typename std::decay<Runnable>::type; |
| 413 | 427 |
| 414 enum { is_method = HasIsMethodTag<RunnableType>::value }; | 428 static constexpr bool is_method = HasIsMethodTag<RunnableType>::value; |
| 415 enum { is_weak_call = IsWeakMethod< | |
| 416 is_method, typename std::decay<BoundArgs>::type...>::value}; | |
| 417 | |
| 418 using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>; | |
| 419 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>; | |
| 420 | 429 |
| 421 public: | 430 public: |
| 422 using UnboundRunType = MakeFunctionType<R, UnboundArgs>; | |
| 423 using InvokerType = | |
| 424 Invoker<BoundIndices, StorageType, is_weak_call, UnboundRunType>; | |
| 425 | |
| 426 template <typename... ForwardArgs> | 431 template <typename... ForwardArgs> |
| 427 BindState(RunnableType runnable, ForwardArgs&&... bound_args) | 432 explicit BindState(RunnableType runnable, ForwardArgs&&... bound_args) |
| 428 : BindStateBase(&Destroy), | 433 : BindStateBase(&Destroy), |
| 429 runnable_(std::move(runnable)), | 434 runnable_(std::move(runnable)), |
| 430 bound_args_(std::forward<ForwardArgs>(bound_args)...) {} | 435 bound_args_(std::forward<ForwardArgs>(bound_args)...) {} |
| 431 | 436 |
| 432 RunnableType runnable_; | 437 RunnableType runnable_; |
| 433 MakeArgsStorage<is_method, BoundArgs...> bound_args_; | 438 MakeArgsStorage<is_method, BoundArgs...> bound_args_; |
| 434 | 439 |
| 435 private: | 440 private: |
| 436 ~BindState() {} | 441 ~BindState() {} |
| 437 | 442 |
| 438 static void Destroy(BindStateBase* self) { | 443 static void Destroy(BindStateBase* self) { |
| 439 delete static_cast<BindState*>(self); | 444 delete static_cast<BindState*>(self); |
| 440 } | 445 } |
| 441 }; | 446 }; |
| 442 | 447 |
| 443 } // namespace internal | 448 } // namespace internal |
| 449 |
| 450 // Returns a RunType of bound functor. |
| 451 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C). |
| 452 template <typename Functor, typename... BoundArgs> |
| 453 using MakeUnboundRunType = |
| 454 typename internal::MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type; |
| 455 |
| 444 } // namespace base | 456 } // namespace base |
| 445 | 457 |
| 446 #endif // BASE_BIND_INTERNAL_H_ | 458 #endif // BASE_BIND_INTERNAL_H_ |
| OLD | NEW |