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