use_coro.hpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. //
  2. // experimental/impl/use_coro.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_IMPL_USE_CORO_HPP
  12. #define BOOST_ASIO_EXPERIMENTAL_IMPL_USE_CORO_HPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  16. #include <boost/asio/deferred.hpp>
  17. #include <boost/asio/experimental/coro.hpp>
  18. #include <boost/asio/detail/push_options.hpp>
  19. namespace boost {
  20. namespace asio {
  21. #if !defined(GENERATING_DOCUMENTATION)
  22. template <typename Allocator, typename R>
  23. struct async_result<experimental::use_coro_t<Allocator>, R()>
  24. {
  25. template <typename Initiation, typename... InitArgs>
  26. static auto initiate_impl(Initiation initiation,
  27. std::allocator_arg_t, Allocator, InitArgs... args)
  28. -> experimental::coro<void() noexcept, void,
  29. boost::asio::associated_executor_t<Initiation>, Allocator>
  30. {
  31. co_await deferred_async_operation<R(), Initiation, InitArgs...>(
  32. deferred_init_tag{}, std::move(initiation), std::move(args)...);
  33. }
  34. template <typename... InitArgs>
  35. static auto initiate_impl(boost::asio::detail::initiation_archetype<R()>,
  36. std::allocator_arg_t, Allocator, InitArgs... args)
  37. -> experimental::coro<void(), void,
  38. boost::asio::any_io_executor, Allocator>;
  39. template <typename Initiation, typename... InitArgs>
  40. static auto initiate(Initiation initiation,
  41. experimental::use_coro_t<Allocator> tk, InitArgs&&... args)
  42. {
  43. return initiate_impl(std::move(initiation), std::allocator_arg,
  44. tk.get_allocator(), std::forward<InitArgs>(args)...);
  45. }
  46. };
  47. template <typename Allocator, typename R>
  48. struct async_result<
  49. experimental::use_coro_t<Allocator>, R(boost::system::error_code)>
  50. {
  51. template <typename Initiation, typename... InitArgs>
  52. static auto initiate_impl(Initiation initiation,
  53. std::allocator_arg_t, Allocator, InitArgs... args)
  54. -> experimental::coro<void() noexcept, void,
  55. boost::asio::associated_executor_t<Initiation>, Allocator>
  56. {
  57. co_await deferred_async_operation<
  58. R(boost::system::error_code), Initiation, InitArgs...>(
  59. deferred_init_tag{}, std::move(initiation), std::move(args)...);
  60. }
  61. template <typename... InitArgs>
  62. static auto initiate_impl(
  63. boost::asio::detail::initiation_archetype<R(boost::system::error_code)>,
  64. std::allocator_arg_t, Allocator, InitArgs... args)
  65. -> experimental::coro<void(), void,
  66. boost::asio::any_io_executor, Allocator>;
  67. template <typename Initiation, typename... InitArgs>
  68. static auto initiate(Initiation initiation,
  69. experimental::use_coro_t<Allocator> tk, InitArgs&&... args)
  70. {
  71. return initiate_impl(std::move(initiation), std::allocator_arg,
  72. tk.get_allocator(), std::forward<InitArgs>(args)...);
  73. }
  74. };
  75. template <typename Allocator, typename R>
  76. struct async_result<
  77. experimental::use_coro_t<Allocator>, R(std::exception_ptr)>
  78. {
  79. template <typename Initiation, typename... InitArgs>
  80. static auto initiate_impl(Initiation initiation,
  81. std::allocator_arg_t, Allocator, InitArgs... args)
  82. -> experimental::coro<void(), void,
  83. boost::asio::associated_executor_t<Initiation>, Allocator>
  84. {
  85. co_await deferred_async_operation<
  86. R(std::exception_ptr), Initiation, InitArgs...>(
  87. deferred_init_tag{}, std::move(initiation), std::move(args)...);
  88. }
  89. template <typename... InitArgs>
  90. static auto initiate_impl(
  91. boost::asio::detail::initiation_archetype<R(std::exception_ptr)>,
  92. std::allocator_arg_t, Allocator, InitArgs... args)
  93. -> experimental::coro<void(), void,
  94. boost::asio::any_io_executor, Allocator>;
  95. template <typename Initiation, typename... InitArgs>
  96. static auto initiate(Initiation initiation,
  97. experimental::use_coro_t<Allocator> tk, InitArgs&&... args)
  98. {
  99. return initiate_impl(std::move(initiation), std::allocator_arg,
  100. tk.get_allocator(), std::forward<InitArgs>(args)...);
  101. }
  102. };
  103. template <typename Allocator, typename R, typename T>
  104. struct async_result<experimental::use_coro_t<Allocator>, R(T)>
  105. {
  106. template <typename Initiation, typename... InitArgs>
  107. static auto initiate_impl(Initiation initiation,
  108. std::allocator_arg_t, Allocator, InitArgs... args)
  109. -> experimental::coro<void() noexcept, T,
  110. boost::asio::associated_executor_t<Initiation>, Allocator>
  111. {
  112. co_return co_await deferred_async_operation<R(T), Initiation, InitArgs...>(
  113. deferred_init_tag{}, std::move(initiation), std::move(args)...);
  114. }
  115. template <typename... InitArgs>
  116. static auto initiate_impl(boost::asio::detail::initiation_archetype<R(T)>,
  117. std::allocator_arg_t, Allocator, InitArgs... args)
  118. -> experimental::coro<void() noexcept, T,
  119. boost::asio::any_io_executor, Allocator>;
  120. template <typename Initiation, typename... InitArgs>
  121. static auto initiate(Initiation initiation,
  122. experimental::use_coro_t<Allocator> tk, InitArgs&&... args)
  123. {
  124. return initiate_impl(std::move(initiation), std::allocator_arg,
  125. tk.get_allocator(), std::forward<InitArgs>(args)...);
  126. }
  127. };
  128. template <typename Allocator, typename R, typename T>
  129. struct async_result<
  130. experimental::use_coro_t<Allocator>, R(boost::system::error_code, T)>
  131. {
  132. template <typename Initiation, typename... InitArgs>
  133. static auto initiate_impl(Initiation initiation,
  134. std::allocator_arg_t, Allocator, InitArgs... args)
  135. -> experimental::coro<void(), T,
  136. boost::asio::associated_executor_t<Initiation>, Allocator>
  137. {
  138. co_return co_await deferred_async_operation<
  139. R(boost::system::error_code, T), Initiation, InitArgs...>(
  140. deferred_init_tag{}, std::move(initiation), std::move(args)...);
  141. }
  142. template <typename... InitArgs>
  143. static auto initiate_impl(
  144. boost::asio::detail::initiation_archetype<
  145. R(boost::system::error_code, T)>,
  146. std::allocator_arg_t, Allocator, InitArgs... args)
  147. -> experimental::coro<void(), T, boost::asio::any_io_executor, Allocator>;
  148. template <typename Initiation, typename... InitArgs>
  149. static auto initiate(Initiation initiation,
  150. experimental::use_coro_t<Allocator> tk, InitArgs&&... args)
  151. {
  152. return initiate_impl(std::move(initiation), std::allocator_arg,
  153. tk.get_allocator(), std::forward<InitArgs>(args)...);
  154. }
  155. };
  156. template <typename Allocator, typename R, typename T>
  157. struct async_result<
  158. experimental::use_coro_t<Allocator>, R(std::exception_ptr, T)>
  159. {
  160. template <typename Initiation, typename... InitArgs>
  161. static auto initiate_impl(Initiation initiation,
  162. std::allocator_arg_t, Allocator, InitArgs... args)
  163. -> experimental::coro<void(), T,
  164. boost::asio::associated_executor_t<Initiation>, Allocator>
  165. {
  166. co_return co_await deferred_async_operation<
  167. R(std::exception_ptr, T), Initiation, InitArgs...>(
  168. deferred_init_tag{}, std::move(initiation), std::move(args)...);
  169. }
  170. template <typename... InitArgs>
  171. static auto initiate_impl(
  172. boost::asio::detail::initiation_archetype<R(std::exception_ptr, T)>,
  173. std::allocator_arg_t, Allocator, InitArgs... args)
  174. -> experimental::coro<void(), T, boost::asio::any_io_executor, Allocator>;
  175. template <typename Initiation, typename... InitArgs>
  176. static auto initiate(Initiation initiation,
  177. experimental::use_coro_t<Allocator> tk, InitArgs&&... args)
  178. {
  179. return initiate_impl(std::move(initiation), std::allocator_arg,
  180. tk.get_allocator(), std::forward<InitArgs>(args)...);
  181. }
  182. };
  183. #endif // !defined(GENERATING_DOCUMENTATION)
  184. } // namespace asio
  185. } // namespace boost
  186. #include <boost/asio/detail/pop_options.hpp>
  187. #endif // BOOST_ASIO_EXPERIMENTAL_IMPL_USE_CORO_HPP