co_spawn.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. //
  2. // experimental/co_spawn.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2021-2023 Klemens D. Morgenstern
  6. // (klemens dot morgenstern at gmx dot net)
  7. //
  8. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  9. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. #ifndef BOOST_ASIO_EXPERIMENTAL_CO_SPAWN_HPP
  12. #define BOOST_ASIO_EXPERIMENTAL_CO_SPAWN_HPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  16. #include <boost/asio/detail/config.hpp>
  17. #include <utility>
  18. #include <boost/asio/compose.hpp>
  19. #include <boost/asio/detail/type_traits.hpp>
  20. #include <boost/asio/experimental/coro.hpp>
  21. #include <boost/asio/experimental/deferred.hpp>
  22. #include <boost/asio/experimental/prepend.hpp>
  23. #include <boost/asio/redirect_error.hpp>
  24. #include <boost/asio/detail/push_options.hpp>
  25. namespace boost {
  26. namespace asio {
  27. namespace experimental {
  28. namespace detail {
  29. template <typename T, typename U, typename Executor>
  30. struct coro_spawn_op
  31. {
  32. coro<T, U, Executor> c;
  33. void operator()(auto& self)
  34. {
  35. auto op = c.async_resume(deferred);
  36. std::move(op)((prepend)(std::move(self), 0));
  37. }
  38. void operator()(auto& self, int, auto... res)
  39. {
  40. self.complete(std::move(res)...);
  41. }
  42. };
  43. } // namespace detail
  44. /// Spawn a resumable coroutine.
  45. /**
  46. * This function spawns the coroutine for execution on its executor. It binds
  47. * the lifetime of the coroutine to the executor.
  48. *
  49. * @param c The coroutine
  50. *
  51. * @param token The completion token
  52. *
  53. * @returns Implementation defined
  54. */
  55. template <typename T, typename Executor, typename CompletionToken>
  56. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
  57. CompletionToken, void(std::exception_ptr, T))
  58. co_spawn(coro<void, T, Executor> c, CompletionToken&& token)
  59. {
  60. auto exec = c.get_executor();
  61. return async_compose<CompletionToken, void(std::exception_ptr, T)>(
  62. detail::coro_spawn_op<void, T, Executor>{std::move(c)},
  63. token, exec);
  64. }
  65. /// Spawn a resumable coroutine.
  66. /**
  67. * This function spawns the coroutine for execution on its executor. It binds
  68. * the lifetime of the coroutine to the executor.
  69. *
  70. * @param c The coroutine
  71. *
  72. * @param token The completion token
  73. *
  74. * @returns Implementation defined
  75. */
  76. template <typename T, typename Executor, typename CompletionToken>
  77. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
  78. CompletionToken, void(std::exception_ptr, T))
  79. co_spawn(coro<void(), T, Executor> c, CompletionToken&& token)
  80. {
  81. auto exec = c.get_executor();
  82. return async_compose<CompletionToken, void(std::exception_ptr, T)>(
  83. detail::coro_spawn_op<void(), T, Executor>{std::move(c)},
  84. token, exec);
  85. }
  86. /// Spawn a resumable coroutine.
  87. /**
  88. * This function spawns the coroutine for execution on its executor. It binds
  89. * the lifetime of the coroutine to the executor.
  90. *
  91. * @param c The coroutine
  92. *
  93. * @param token The completion token
  94. *
  95. * @returns Implementation defined
  96. */
  97. template <typename T, typename Executor, typename CompletionToken>
  98. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(T))
  99. co_spawn(coro<void() noexcept, T, Executor> c, CompletionToken&& token)
  100. {
  101. auto exec = c.get_executor();
  102. return async_compose<CompletionToken, void(T)>(
  103. detail::coro_spawn_op<void() noexcept, T, Executor>{std::move(c)},
  104. token, exec);
  105. }
  106. /// Spawn a resumable coroutine.
  107. /**
  108. * This function spawns the coroutine for execution on its executor. It binds
  109. * the lifetime of the coroutine to the executor.
  110. *
  111. * @param c The coroutine
  112. *
  113. * @param token The completion token
  114. *
  115. * @returns Implementation defined
  116. */
  117. template <typename Executor, typename CompletionToken>
  118. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
  119. CompletionToken, void(std::exception_ptr))
  120. co_spawn(coro<void, void, Executor> c, CompletionToken&& token)
  121. {
  122. auto exec = c.get_executor();
  123. return async_compose<CompletionToken, void(std::exception_ptr)>(
  124. detail::coro_spawn_op<void, void, Executor>{std::move(c)},
  125. token, exec);
  126. }
  127. /// Spawn a resumable coroutine.
  128. /**
  129. * This function spawns the coroutine for execution on its executor. It binds
  130. * the lifetime of the coroutine to the executor.
  131. *
  132. * @param c The coroutine
  133. *
  134. * @param token The completion token
  135. *
  136. * @returns Implementation defined
  137. */
  138. template <typename Executor, typename CompletionToken>
  139. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
  140. CompletionToken, void(std::exception_ptr))
  141. co_spawn(coro<void(), void, Executor> c, CompletionToken&& token)
  142. {
  143. auto exec = c.get_executor();
  144. return async_compose<CompletionToken, void(std::exception_ptr)>(
  145. detail::coro_spawn_op<void(), void, Executor>{std::move(c)},
  146. token, exec);
  147. }
  148. /// Spawn a resumable coroutine.
  149. /**
  150. * This function spawns the coroutine for execution on its executor. It binds
  151. * the lifetime of the coroutine to the executor.
  152. *
  153. * @param c The coroutine
  154. *
  155. * @param token The completion token
  156. *
  157. * @returns Implementation defined
  158. */
  159. template <typename Executor, typename CompletionToken>
  160. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void())
  161. co_spawn(coro<void() noexcept, void, Executor> c, CompletionToken&& token)
  162. {
  163. auto exec = c.get_executor();
  164. return async_compose<CompletionToken, void()>(
  165. detail::coro_spawn_op<void() noexcept, void, Executor>{std::move(c)},
  166. token, exec);
  167. }
  168. } // namespace detail
  169. } // namespace asio
  170. } // namespace boost
  171. #include <boost/asio/detail/pop_options.hpp>
  172. #endif //BOOST_ASIO_EXPERIMENTAL_CO_SPAWN_HPP