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 |