基于C++ Coroutines提案 ‘Stackless Resumable Functions’编写的协程库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

asio_task_1.12.0.inl 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #include <memory>
  2. #include "asio/detail/push_options.hpp"
  3. namespace asio {
  4. /**
  5. * @brief 用于指示asio相关异步函数,返回librf::future_t<>的类型,从而变成支持 librf 的协程函数。
  6. */
  7. template <typename Executor = executor>
  8. struct rf_task_t
  9. {
  10. ASIO_CONSTEXPR rf_task_t() {}
  11. };
  12. /**
  13. * @brief 用于指示asio相关异步函数,返回librf::future_t<>的常量,从而变成支持 librf 的协程函数。
  14. */
  15. constexpr rf_task_t<> rf_task;
  16. namespace librf {
  17. template <typename Executor, typename T>
  18. struct promise_handler_base
  19. {
  20. public:
  21. typedef T result_type;
  22. typedef librf::state_t<result_type> state_type;
  23. promise_handler_base()
  24. : state_(librf::state_future_t::_Alloc_state<state_type>(true))
  25. {
  26. }
  27. librf::counted_ptr<state_type> state_;
  28. promise_handler_base(promise_handler_base &&) = default;
  29. promise_handler_base(const promise_handler_base &) = default;
  30. promise_handler_base & operator = (promise_handler_base &&) = default;
  31. promise_handler_base & operator = (const promise_handler_base &) = default;
  32. };
  33. template <typename, typename...>
  34. struct promise_handler;
  35. template <typename Executor>
  36. struct promise_handler<Executor, void> : public promise_handler_base<Executor, void>
  37. {
  38. using promise_handler_base<Executor, void>::promise_handler_base;
  39. void operator()() const
  40. {
  41. this->state_->set_value();
  42. }
  43. };
  44. template <typename Executor>
  45. struct promise_handler<Executor, asio::error_code> : public promise_handler_base<Executor, void>
  46. {
  47. using promise_handler_base<Executor, void>::promise_handler_base;
  48. void operator()(const asio::error_code& ec) const
  49. {
  50. if (!ec)
  51. this->state_->set_value();
  52. else
  53. this->state_->set_exception(std::make_exception_ptr(asio::system_error(ec)));
  54. }
  55. };
  56. template <typename Executor>
  57. struct promise_handler<Executor, std::exception_ptr> : public promise_handler_base<Executor, void>
  58. {
  59. using promise_handler_base<Executor, void>::promise_handler_base;
  60. void operator()(std::exception_ptr ex) const
  61. {
  62. if (!ex)
  63. this->state_->set_value();
  64. else
  65. this->state_->set_exception(ex);
  66. }
  67. };
  68. template <typename Executor, typename T>
  69. struct promise_handler<Executor, T> : public promise_handler_base<Executor, T>
  70. {
  71. using promise_handler_base<Executor, T>::promise_handler_base;
  72. template <typename Arg>
  73. void operator()(Arg&& arg) const
  74. {
  75. this->state_->set_value(std::forward<Arg>(arg));
  76. }
  77. };
  78. template <typename Executor, typename T>
  79. struct promise_handler<Executor, asio::error_code, T> : public promise_handler_base<Executor, T>
  80. {
  81. using promise_handler_base<Executor, T>::promise_handler_base;
  82. template <typename Arg>
  83. void operator()(const asio::error_code& ec, Arg&& arg) const
  84. {
  85. if (!ec)
  86. this->state_->set_value(std::forward<Arg>(arg));
  87. else
  88. this->state_->set_exception(std::make_exception_ptr(asio::system_error(ec)));
  89. }
  90. };
  91. template <typename Executor, typename T>
  92. struct promise_handler<Executor, std::exception_ptr, T> : public promise_handler_base<Executor, T>
  93. {
  94. using promise_handler_base<Executor, T>::promise_handler_base;
  95. template <typename Arg>
  96. void operator()(std::exception_ptr ex, Arg&& arg) const
  97. {
  98. if (!ex)
  99. this->state_->set_value(std::forward<Arg>(arg));
  100. else
  101. this->state_->set_exception(ex);
  102. }
  103. };
  104. template <typename Executor, typename... Ts>
  105. struct promise_handler : public promise_handler_base<Executor, std::tuple<Ts...>>
  106. {
  107. using promise_handler_base<Executor, std::tuple<Ts...>>::promise_handler_base;
  108. template <typename... Args>
  109. void operator()(Args&&... args) const
  110. {
  111. this->state_->set_value(std::make_tuple(std::forward<Args>(args)...));
  112. }
  113. };
  114. template <typename Executor, typename... Ts>
  115. struct promise_handler<Executor, asio::error_code, Ts...> : public promise_handler_base<Executor, std::tuple<Ts...>>
  116. {
  117. using promise_handler_base<Executor, std::tuple<Ts...>>::promise_handler_base;
  118. template <typename... Args>
  119. void operator()(const asio::error_code& ec, Args&&... args) const
  120. {
  121. if (!ec)
  122. this->state_->set_value(std::make_tuple(std::forward<Args>(args)...));
  123. else
  124. this->state_->set_exception(std::make_exception_ptr(asio::system_error(ec)));
  125. }
  126. };
  127. template <typename Executor, typename... Ts>
  128. struct promise_handler<Executor, std::exception_ptr, Ts...> : public promise_handler_base<Executor, std::tuple<Ts...>>
  129. {
  130. using promise_handler_base<Executor, std::tuple<Ts...>>::promise_handler_base;
  131. template <typename... Args>
  132. void operator()(std::exception_ptr ex, Args&&... args) const
  133. {
  134. if (!ex)
  135. this->state_->set_value(std::make_tuple(std::forward<Args>(args)...));
  136. else
  137. this->state_->set_exception(ex);
  138. }
  139. };
  140. } // namespace librf
  141. template <typename Executor, typename R, typename... Args>
  142. class async_result<rf_task_t<Executor>, R(Args...)>
  143. {
  144. public:
  145. typedef librf::promise_handler<Executor, Args...> handler_type;
  146. typedef typename handler_type::result_type result_type;
  147. typedef librf::future_t<result_type> return_type;
  148. template <typename Initiation, typename... InitArgs>
  149. static return_type initiate(ASIO_MOVE_ARG(Initiation) initiation,
  150. rf_task_t<Executor>, ASIO_MOVE_ARG(InitArgs)... args)
  151. {
  152. handler_type handler{};
  153. return_type future{ handler.state_ };
  154. std::move(initiation)(std::move(handler), std::move(args)...);
  155. return std::move(future);
  156. }
  157. };
  158. } // namespace asio
  159. #include "asio/detail/pop_options.hpp"