async.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright Oliver Kowalke 2013.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_FIBERS_ASYNC_HPP
  6. #define BOOST_FIBERS_ASYNC_HPP
  7. #include <algorithm>
  8. #include <memory>
  9. #include <type_traits>
  10. #include <utility>
  11. #include <boost/config.hpp>
  12. #include <boost/fiber/future/future.hpp>
  13. #include <boost/fiber/future/packaged_task.hpp>
  14. #include <boost/fiber/policy.hpp>
  15. namespace boost {
  16. namespace fibers {
  17. #if defined(BOOST_MSVC) && (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)
  18. template <typename>
  19. struct result_of;
  20. template <typename F, typename... Args>
  21. struct result_of<F(Args...)> : std::invoke_result<F, Args...> {};
  22. #else
  23. using std::result_of;
  24. #endif
  25. template< typename Fn, typename ... Args >
  26. future<
  27. typename result_of<
  28. typename std::enable_if<
  29. ! detail::is_launch_policy< typename std::decay< Fn >::type >::value,
  30. typename std::decay< Fn >::type
  31. >::type( typename std::decay< Args >::type ... )
  32. >::type
  33. >
  34. async( Fn && fn, Args ... args) {
  35. typedef typename result_of<
  36. typename std::decay< Fn >::type( typename std::decay< Args >::type ... )
  37. >::type result_type;
  38. packaged_task< result_type( typename std::decay< Args >::type ... ) > pt{
  39. std::forward< Fn >( fn) };
  40. future< result_type > f{ pt.get_future() };
  41. fiber{ std::move( pt), std::forward< Args >( args) ... }.detach();
  42. return f;
  43. }
  44. template< typename Policy, typename Fn, typename ... Args >
  45. future<
  46. typename result_of<
  47. typename std::enable_if<
  48. detail::is_launch_policy< Policy >::value,
  49. typename std::decay< Fn >::type
  50. >::type( typename std::decay< Args >::type ...)
  51. >::type
  52. >
  53. async( Policy policy, Fn && fn, Args ... args) {
  54. typedef typename result_of<
  55. typename std::decay< Fn >::type( typename std::decay< Args >::type ... )
  56. >::type result_type;
  57. packaged_task< result_type( typename std::decay< Args >::type ... ) > pt{
  58. std::forward< Fn >( fn) };
  59. future< result_type > f{ pt.get_future() };
  60. fiber{ policy, std::move( pt), std::forward< Args >( args) ... }.detach();
  61. return f;
  62. }
  63. template< typename Policy, typename StackAllocator, typename Fn, typename ... Args >
  64. future<
  65. typename result_of<
  66. typename std::enable_if<
  67. detail::is_launch_policy< Policy >::value,
  68. typename std::decay< Fn >::type
  69. >::type( typename std::decay< Args >::type ... )
  70. >::type
  71. >
  72. async( Policy policy, std::allocator_arg_t, StackAllocator salloc, Fn && fn, Args ... args) {
  73. typedef typename result_of<
  74. typename std::decay< Fn >::type( typename std::decay< Args >::type ... )
  75. >::type result_type;
  76. packaged_task< result_type( typename std::decay< Args >::type ... ) > pt{
  77. std::forward< Fn >( fn) };
  78. future< result_type > f{ pt.get_future() };
  79. fiber{ policy, std::allocator_arg, salloc,
  80. std::move( pt), std::forward< Args >( args) ... }.detach();
  81. return f;
  82. }
  83. template< typename Policy, typename StackAllocator, typename Allocator, typename Fn, typename ... Args >
  84. future<
  85. typename result_of<
  86. typename std::enable_if<
  87. detail::is_launch_policy< Policy >::value,
  88. typename std::decay< Fn >::type
  89. >::type( typename std::decay< Args >::type ... )
  90. >::type
  91. >
  92. async( Policy policy, std::allocator_arg_t, StackAllocator salloc, Allocator alloc, Fn && fn, Args ... args) {
  93. typedef typename result_of<
  94. typename std::decay< Fn >::type( typename std::decay< Args >::type ... )
  95. >::type result_type;
  96. packaged_task< result_type( typename std::decay< Args >::type ... ) > pt{
  97. std::allocator_arg, alloc, std::forward< Fn >( fn) };
  98. future< result_type > f{ pt.get_future() };
  99. fiber{ policy, std::allocator_arg, salloc,
  100. std::move( pt), std::forward< Args >( args) ... }.detach();
  101. return f;
  102. }
  103. }}
  104. #endif // BOOST_FIBERS_ASYNC_HPP