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 inline void MakeItSo(Runnable&& runnable, |
320 BoundWeakPtr weak_ptr, | 320 BoundWeakPtr weak_ptr, |
321 RunArgs&&... args) { | 321 RunArgs&&... args) { |
322 if (!weak_ptr.get()) { | 322 if (!weak_ptr.get()) { |
323 return; | 323 return; |
324 } | 324 } |
325 std::forward<Runnable>(runnable).Run( | 325 std::forward<Runnable>(runnable).Run( |
326 weak_ptr.get(), std::forward<RunArgs>(args)...); | 326 weak_ptr.get(), std::forward<RunArgs>(args)...); |
327 } | 327 } |
328 }; | 328 }; |
329 | 329 |
330 #if !defined(_MSC_VER) | 330 #if !defined(_MSC_VER) |
331 | 331 |
332 template <typename ReturnType> | 332 template <typename ReturnType> |
333 struct InvokeHelper<true, ReturnType> { | 333 struct InvokeHelper<true, ReturnType> { |
334 // WeakCalls are only supported for functions with a void return type. | 334 // WeakCalls are only supported for functions with a void return type. |
335 // Otherwise, the function result would be undefined if the the WeakPtr<> | 335 // Otherwise, the function result would be undefined if the the WeakPtr<> |
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 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 StorageType* storage = static_cast<StorageType*>(base); | |
356 constexpr size_t num_bound_args = | |
Yuta Kitamura
2016/06/23 07:22:45
nit: Add "static" since constexpr doesn't imply st
tzik
2016/06/23 08:16:10
Hmm, I think that does not make any diff in this c
| |
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 constexpr bool is_method = | |
370 HasIsMethodTag<typename std::decay<Runnable>::type>::value; | |
371 constexpr bool is_weak_call = | |
372 IsWeakMethod<is_method, | |
373 typename std::decay<BoundArgsTuple>::type>::value; | |
374 | |
364 return InvokeHelper<is_weak_call, R>::MakeItSo( | 375 return InvokeHelper<is_weak_call, R>::MakeItSo( |
365 storage->runnable_, | 376 std::forward<Runnable>(runnable), |
366 Unwrap(std::get<bound_indices>(storage->bound_args_))..., | 377 Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))..., |
367 std::forward<UnboundArgs>(unbound_args)...); | 378 std::forward<UnboundArgs>(unbound_args)...); |
368 } | 379 } |
369 }; | 380 }; |
370 | 381 |
371 // Used to implement MakeArgsStorage. | 382 // Used to implement MakeArgsStorage. |
372 template <bool is_method, typename... BoundArgs> | 383 template <bool is_method, typename... BoundArgs> |
373 struct MakeArgsStorageImpl { | 384 struct MakeArgsStorageImpl { |
374 using Type = std::tuple<BoundArgs...>; | 385 using Type = std::tuple<BoundArgs...>; |
375 }; | 386 }; |
376 | 387 |
377 template <typename Obj, typename... BoundArgs> | 388 template <typename Obj, typename... BoundArgs> |
378 struct MakeArgsStorageImpl<true, Obj*, BoundArgs...> { | 389 struct MakeArgsStorageImpl<true, Obj*, BoundArgs...> { |
379 using Type = std::tuple<scoped_refptr<Obj>, BoundArgs...>; | 390 using Type = std::tuple<scoped_refptr<Obj>, BoundArgs...>; |
380 }; | 391 }; |
381 | 392 |
382 // Constructs a tuple type to store BoundArgs into BindState. | 393 // 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 | 394 // This wraps the first argument into a scoped_refptr if |is_method| is true and |
384 // the first argument is a raw pointer. | 395 // the first argument is a raw pointer. |
385 // Other arguments are adjusted for store and packed into a tuple. | 396 // Other arguments are adjusted for store and packed into a tuple. |
386 template <bool is_method, typename... BoundArgs> | 397 template <bool is_method, typename... BoundArgs> |
387 using MakeArgsStorage = typename MakeArgsStorageImpl< | 398 using MakeArgsStorage = typename MakeArgsStorageImpl< |
388 is_method, typename std::decay<BoundArgs>::type...>::Type; | 399 is_method, typename std::decay<BoundArgs>::type...>::Type; |
389 | 400 |
401 // Used to implement MakeUnboundRunType. | |
402 template <typename Functor, typename... BoundArgs> | |
403 struct MakeUnboundRunTypeImpl { | |
404 using RunType = typename FunctorTraits<Functor>::RunType; | |
405 using ReturnType = ExtractReturnType<RunType>; | |
406 using Args = ExtractArgs<RunType>; | |
407 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), Args>; | |
408 using Type = MakeFunctionType<ReturnType, UnboundArgs>; | |
409 }; | |
410 | |
411 // Returns a RunType of bound functor. | |
412 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C). | |
413 template <typename Functor, typename... BoundArgs> | |
414 using MakeUnboundRunType = | |
415 typename MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type; | |
416 | |
390 // BindState<> | 417 // BindState<> |
391 // | 418 // |
392 // This stores all the state passed into Bind() and is also where most | 419 // This stores all the state passed into Bind() and is also where most |
393 // of the template resolution magic occurs. | 420 // of the template resolution magic occurs. |
394 // | 421 // |
395 // Runnable is the functor we are binding arguments to. | 422 // 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 // | 423 // |
400 // BoundArgs contains the storage type for all the bound arguments. | 424 // BoundArgs contains the storage type for all the bound arguments. |
401 template <typename Runnable, typename RunType, typename... BoundArgs> | 425 template <typename Runnable, typename... BoundArgs> |
402 struct BindState; | 426 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: | 427 private: |
411 using StorageType = BindState<Runnable, R(Args...), BoundArgs...>; | |
412 using RunnableType = typename std::decay<Runnable>::type; | 428 using RunnableType = typename std::decay<Runnable>::type; |
413 | 429 |
414 enum { is_method = HasIsMethodTag<RunnableType>::value }; | 430 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 | 431 |
421 public: | 432 public: |
422 using UnboundRunType = MakeFunctionType<R, UnboundArgs>; | |
423 using InvokerType = | |
424 Invoker<BoundIndices, StorageType, is_weak_call, UnboundRunType>; | |
425 | |
426 template <typename... ForwardArgs> | 433 template <typename... ForwardArgs> |
427 BindState(RunnableType runnable, ForwardArgs&&... bound_args) | 434 explicit BindState(RunnableType runnable, ForwardArgs&&... bound_args) |
428 : BindStateBase(&Destroy), | 435 : BindStateBase(&Destroy), |
429 runnable_(std::move(runnable)), | 436 runnable_(std::move(runnable)), |
430 bound_args_(std::forward<ForwardArgs>(bound_args)...) {} | 437 bound_args_(std::forward<ForwardArgs>(bound_args)...) {} |
431 | 438 |
432 RunnableType runnable_; | 439 RunnableType runnable_; |
433 MakeArgsStorage<is_method, BoundArgs...> bound_args_; | 440 MakeArgsStorage<is_method, BoundArgs...> bound_args_; |
434 | 441 |
435 private: | 442 private: |
436 ~BindState() {} | 443 ~BindState() {} |
437 | 444 |
438 static void Destroy(BindStateBase* self) { | 445 static void Destroy(BindStateBase* self) { |
439 delete static_cast<BindState*>(self); | 446 delete static_cast<BindState*>(self); |
440 } | 447 } |
441 }; | 448 }; |
442 | 449 |
443 } // namespace internal | 450 } // namespace internal |
444 } // namespace base | 451 } // namespace base |
445 | 452 |
446 #endif // BASE_BIND_INTERNAL_H_ | 453 #endif // BASE_BIND_INTERNAL_H_ |
OLD | NEW |