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 |