submit_receiver.hpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. //
  2. // execution/detail/submit_receiver.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_EXECUTION_DETAIL_SUBMIT_RECEIVER_HPP
  11. #define BOOST_ASIO_EXECUTION_DETAIL_SUBMIT_RECEIVER_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/config.hpp>
  16. #include <boost/asio/detail/type_traits.hpp>
  17. #include <boost/asio/detail/variadic_templates.hpp>
  18. #include <boost/asio/execution/connect.hpp>
  19. #include <boost/asio/execution/receiver.hpp>
  20. #include <boost/asio/execution/set_done.hpp>
  21. #include <boost/asio/execution/set_error.hpp>
  22. #include <boost/asio/execution/set_value.hpp>
  23. #include <boost/asio/traits/set_done_member.hpp>
  24. #include <boost/asio/traits/set_error_member.hpp>
  25. #include <boost/asio/traits/set_value_member.hpp>
  26. #include <boost/asio/detail/push_options.hpp>
  27. namespace boost {
  28. namespace asio {
  29. namespace execution {
  30. namespace detail {
  31. template <typename Sender, typename Receiver>
  32. struct submit_receiver;
  33. template <typename Sender, typename Receiver>
  34. struct submit_receiver_wrapper
  35. {
  36. submit_receiver<Sender, Receiver>* p_;
  37. explicit submit_receiver_wrapper(submit_receiver<Sender, Receiver>* p)
  38. : p_(p)
  39. {
  40. }
  41. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  42. template <typename... Args>
  43. typename enable_if<is_receiver_of<Receiver, Args...>::value>::type
  44. set_value(BOOST_ASIO_MOVE_ARG(Args)... args) BOOST_ASIO_RVALUE_REF_QUAL
  45. BOOST_ASIO_NOEXCEPT_IF((is_nothrow_receiver_of<Receiver, Args...>::value))
  46. {
  47. execution::set_value(
  48. BOOST_ASIO_MOVE_OR_LVALUE(
  49. typename remove_cvref<Receiver>::type)(p_->r_),
  50. BOOST_ASIO_MOVE_CAST(Args)(args)...);
  51. delete p_;
  52. }
  53. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  54. void set_value() BOOST_ASIO_RVALUE_REF_QUAL
  55. BOOST_ASIO_NOEXCEPT_IF((is_nothrow_receiver_of<Receiver>::value))
  56. {
  57. execution::set_value(
  58. BOOST_ASIO_MOVE_OR_LVALUE(
  59. typename remove_cvref<Receiver>::type)(p_->r_));
  60. delete p_;
  61. }
  62. #define BOOST_ASIO_PRIVATE_SUBMIT_RECEIVER_SET_VALUE_DEF(n) \
  63. template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  64. typename enable_if<is_receiver_of<Receiver, \
  65. BOOST_ASIO_VARIADIC_TARGS(n)>::value>::type \
  66. set_value(BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) BOOST_ASIO_RVALUE_REF_QUAL \
  67. BOOST_ASIO_NOEXCEPT_IF((is_nothrow_receiver_of< \
  68. Receiver, BOOST_ASIO_VARIADIC_TARGS(n)>::value)) \
  69. { \
  70. execution::set_value( \
  71. BOOST_ASIO_MOVE_OR_LVALUE( \
  72. typename remove_cvref<Receiver>::type)(p_->r_), \
  73. BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
  74. delete p_; \
  75. } \
  76. /**/
  77. BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_SUBMIT_RECEIVER_SET_VALUE_DEF)
  78. #undef BOOST_ASIO_PRIVATE_SUBMIT_RECEIVER_SET_VALUE_DEF
  79. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  80. template <typename E>
  81. void set_error(BOOST_ASIO_MOVE_ARG(E) e)
  82. BOOST_ASIO_RVALUE_REF_QUAL BOOST_ASIO_NOEXCEPT
  83. {
  84. execution::set_error(
  85. BOOST_ASIO_MOVE_OR_LVALUE(
  86. typename remove_cvref<Receiver>::type)(p_->r_),
  87. BOOST_ASIO_MOVE_CAST(E)(e));
  88. delete p_;
  89. }
  90. void set_done() BOOST_ASIO_RVALUE_REF_QUAL BOOST_ASIO_NOEXCEPT
  91. {
  92. execution::set_done(
  93. BOOST_ASIO_MOVE_OR_LVALUE(
  94. typename remove_cvref<Receiver>::type)(p_->r_));
  95. delete p_;
  96. }
  97. };
  98. template <typename Sender, typename Receiver>
  99. struct submit_receiver
  100. {
  101. typename remove_cvref<Receiver>::type r_;
  102. #if defined(BOOST_ASIO_HAS_MOVE)
  103. typename connect_result<Sender,
  104. submit_receiver_wrapper<Sender, Receiver> >::type state_;
  105. #else // defined(BOOST_ASIO_HAS_MOVE)
  106. typename connect_result<Sender,
  107. const submit_receiver_wrapper<Sender, Receiver>& >::type state_;
  108. #endif // defined(BOOST_ASIO_HAS_MOVE)
  109. #if defined(BOOST_ASIO_HAS_MOVE)
  110. template <typename S, typename R>
  111. explicit submit_receiver(BOOST_ASIO_MOVE_ARG(S) s, BOOST_ASIO_MOVE_ARG(R) r)
  112. : r_(BOOST_ASIO_MOVE_CAST(R)(r)),
  113. state_(execution::connect(BOOST_ASIO_MOVE_CAST(S)(s),
  114. submit_receiver_wrapper<Sender, Receiver>(this)))
  115. {
  116. }
  117. #else // defined(BOOST_ASIO_HAS_MOVE)
  118. explicit submit_receiver(Sender s, Receiver r)
  119. : r_(r),
  120. state_(execution::connect(s,
  121. submit_receiver_wrapper<Sender, Receiver>(this)))
  122. {
  123. }
  124. #endif // defined(BOOST_ASIO_HAS_MOVE)
  125. };
  126. } // namespace detail
  127. } // namespace execution
  128. namespace traits {
  129. #if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
  130. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  131. template <typename Sender, typename Receiver, typename... Args>
  132. struct set_value_member<
  133. boost::asio::execution::detail::submit_receiver_wrapper<
  134. Sender, Receiver>,
  135. void(Args...)>
  136. {
  137. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
  138. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
  139. (boost::asio::execution::is_nothrow_receiver_of<Receiver, Args...>::value));
  140. typedef void result_type;
  141. };
  142. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  143. template <typename Sender, typename Receiver>
  144. struct set_value_member<
  145. boost::asio::execution::detail::submit_receiver_wrapper<
  146. Sender, Receiver>,
  147. void()>
  148. {
  149. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
  150. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
  151. boost::asio::execution::is_nothrow_receiver_of<Receiver>::value);
  152. typedef void result_type;
  153. };
  154. #define BOOST_ASIO_PRIVATE_SUBMIT_RECEIVER_TRAIT_DEF(n) \
  155. template <typename Sender, typename Receiver, \
  156. BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  157. struct set_value_member< \
  158. boost::asio::execution::detail::submit_receiver_wrapper< \
  159. Sender, Receiver>, \
  160. void(BOOST_ASIO_VARIADIC_TARGS(n))> \
  161. { \
  162. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); \
  163. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = \
  164. (boost::asio::execution::is_nothrow_receiver_of<Receiver, \
  165. BOOST_ASIO_VARIADIC_TARGS(n)>::value)); \
  166. typedef void result_type; \
  167. }; \
  168. /**/
  169. BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_SUBMIT_RECEIVER_TRAIT_DEF)
  170. #undef BOOST_ASIO_PRIVATE_SUBMIT_RECEIVER_TRAIT_DEF
  171. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  172. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
  173. #if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
  174. template <typename Sender, typename Receiver, typename E>
  175. struct set_error_member<
  176. boost::asio::execution::detail::submit_receiver_wrapper<
  177. Sender, Receiver>, E>
  178. {
  179. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
  180. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
  181. typedef void result_type;
  182. };
  183. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
  184. #if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
  185. template <typename Sender, typename Receiver>
  186. struct set_done_member<
  187. boost::asio::execution::detail::submit_receiver_wrapper<
  188. Sender, Receiver> >
  189. {
  190. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
  191. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
  192. typedef void result_type;
  193. };
  194. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
  195. } // namespace traits
  196. } // namespace asio
  197. } // namespace boost
  198. #include <boost/asio/detail/pop_options.hpp>
  199. #endif // BOOST_ASIO_EXECUTION_DETAIL_SUBMIT_RECEIVER_HPP