co_spawn.hpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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 ASIO_EXPERIMENTAL_CO_SPAWN_HPP
  12. #define 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 "asio/detail/config.hpp"
  17. #include <utility>
  18. #include "asio/compose.hpp"
  19. #include "asio/detail/type_traits.hpp"
  20. #include "asio/experimental/coro.hpp"
  21. #include "asio/experimental/deferred.hpp"
  22. #include "asio/experimental/prepend.hpp"
  23. #include "asio/redirect_error.hpp"
  24. #include "asio/detail/push_options.hpp"
  25. namespace asio {
  26. namespace experimental {
  27. namespace detail {
  28. template <typename T, typename U, typename Executor>
  29. struct coro_spawn_op
  30. {
  31. coro<T, U, Executor> c;
  32. void operator()(auto& self)
  33. {
  34. auto op = c.async_resume(deferred);
  35. std::move(op)((prepend)(std::move(self), 0));
  36. }
  37. void operator()(auto& self, int, auto... res)
  38. {
  39. self.complete(std::move(res)...);
  40. }
  41. };
  42. } // namespace detail
  43. /// Spawn a resumable coroutine.
  44. /**
  45. * This function spawns the coroutine for execution on its executor. It binds
  46. * the lifetime of the coroutine to the executor.
  47. *
  48. * @param c The coroutine
  49. *
  50. * @param token The completion token
  51. *
  52. * @returns Implementation defined
  53. */
  54. template <typename T, typename Executor, typename CompletionToken>
  55. ASIO_INITFN_AUTO_RESULT_TYPE(
  56. CompletionToken, void(std::exception_ptr, T))
  57. co_spawn(coro<void, T, Executor> c, CompletionToken&& token)
  58. {
  59. auto exec = c.get_executor();
  60. return async_compose<CompletionToken, void(std::exception_ptr, T)>(
  61. detail::coro_spawn_op<void, T, Executor>{std::move(c)},
  62. token, exec);
  63. }
  64. /// Spawn a resumable coroutine.
  65. /**
  66. * This function spawns the coroutine for execution on its executor. It binds
  67. * the lifetime of the coroutine to the executor.
  68. *
  69. * @param c The coroutine
  70. *
  71. * @param token The completion token
  72. *
  73. * @returns Implementation defined
  74. */
  75. template <typename T, typename Executor, typename CompletionToken>
  76. ASIO_INITFN_AUTO_RESULT_TYPE(
  77. CompletionToken, void(std::exception_ptr, T))
  78. co_spawn(coro<void(), T, Executor> c, CompletionToken&& token)
  79. {
  80. auto exec = c.get_executor();
  81. return async_compose<CompletionToken, void(std::exception_ptr, T)>(
  82. detail::coro_spawn_op<void(), T, Executor>{std::move(c)},
  83. token, exec);
  84. }
  85. /// Spawn a resumable coroutine.
  86. /**
  87. * This function spawns the coroutine for execution on its executor. It binds
  88. * the lifetime of the coroutine to the executor.
  89. *
  90. * @param c The coroutine
  91. *
  92. * @param token The completion token
  93. *
  94. * @returns Implementation defined
  95. */
  96. template <typename T, typename Executor, typename CompletionToken>
  97. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(T))
  98. co_spawn(coro<void() noexcept, T, Executor> c, CompletionToken&& token)
  99. {
  100. auto exec = c.get_executor();
  101. return async_compose<CompletionToken, void(T)>(
  102. detail::coro_spawn_op<void() noexcept, T, Executor>{std::move(c)},
  103. token, exec);
  104. }
  105. /// Spawn a resumable coroutine.
  106. /**
  107. * This function spawns the coroutine for execution on its executor. It binds
  108. * the lifetime of the coroutine to the executor.
  109. *
  110. * @param c The coroutine
  111. *
  112. * @param token The completion token
  113. *
  114. * @returns Implementation defined
  115. */
  116. template <typename Executor, typename CompletionToken>
  117. ASIO_INITFN_AUTO_RESULT_TYPE(
  118. CompletionToken, void(std::exception_ptr))
  119. co_spawn(coro<void, void, Executor> c, CompletionToken&& token)
  120. {
  121. auto exec = c.get_executor();
  122. return async_compose<CompletionToken, void(std::exception_ptr)>(
  123. detail::coro_spawn_op<void, void, Executor>{std::move(c)},
  124. token, exec);
  125. }
  126. /// Spawn a resumable coroutine.
  127. /**
  128. * This function spawns the coroutine for execution on its executor. It binds
  129. * the lifetime of the coroutine to the executor.
  130. *
  131. * @param c The coroutine
  132. *
  133. * @param token The completion token
  134. *
  135. * @returns Implementation defined
  136. */
  137. template <typename Executor, typename CompletionToken>
  138. ASIO_INITFN_AUTO_RESULT_TYPE(
  139. CompletionToken, void(std::exception_ptr))
  140. co_spawn(coro<void(), void, Executor> c, CompletionToken&& token)
  141. {
  142. auto exec = c.get_executor();
  143. return async_compose<CompletionToken, void(std::exception_ptr)>(
  144. detail::coro_spawn_op<void(), void, Executor>{std::move(c)},
  145. token, exec);
  146. }
  147. /// Spawn a resumable coroutine.
  148. /**
  149. * This function spawns the coroutine for execution on its executor. It binds
  150. * the lifetime of the coroutine to the executor.
  151. *
  152. * @param c The coroutine
  153. *
  154. * @param token The completion token
  155. *
  156. * @returns Implementation defined
  157. */
  158. template <typename Executor, typename CompletionToken>
  159. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void())
  160. co_spawn(coro<void() noexcept, void, Executor> c, CompletionToken&& token)
  161. {
  162. auto exec = c.get_executor();
  163. return async_compose<CompletionToken, void()>(
  164. detail::coro_spawn_op<void() noexcept, void, Executor>{std::move(c)},
  165. token, exec);
  166. }
  167. } // namespace detail
  168. } // namespace asio
  169. #include "asio/detail/pop_options.hpp"
  170. #endif //ASIO_EXPERIMENTAL_CO_SPAWN_HPP