bulk_sender.hpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. //
  2. // execution/detail/bulk_sender.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2022 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 ASIO_EXECUTION_DETAIL_BULK_SENDER_HPP
  11. #define ASIO_EXECUTION_DETAIL_BULK_SENDER_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include "asio/detail/type_traits.hpp"
  17. #include "asio/execution/connect.hpp"
  18. #include "asio/execution/executor.hpp"
  19. #include "asio/execution/set_done.hpp"
  20. #include "asio/execution/set_error.hpp"
  21. #include "asio/traits/connect_member.hpp"
  22. #include "asio/traits/set_done_member.hpp"
  23. #include "asio/traits/set_error_member.hpp"
  24. #include "asio/traits/set_value_member.hpp"
  25. #include "asio/detail/push_options.hpp"
  26. namespace asio {
  27. namespace execution {
  28. namespace detail {
  29. template <typename Receiver, typename Function, typename Number, typename Index>
  30. struct bulk_receiver
  31. {
  32. typename remove_cvref<Receiver>::type receiver_;
  33. typename decay<Function>::type f_;
  34. typename decay<Number>::type n_;
  35. template <typename R, typename F, typename N>
  36. explicit bulk_receiver(ASIO_MOVE_ARG(R) r,
  37. ASIO_MOVE_ARG(F) f, ASIO_MOVE_ARG(N) n)
  38. : receiver_(ASIO_MOVE_CAST(R)(r)),
  39. f_(ASIO_MOVE_CAST(F)(f)),
  40. n_(ASIO_MOVE_CAST(N)(n))
  41. {
  42. }
  43. void set_value()
  44. {
  45. for (Index i = 0; i < n_; ++i)
  46. f_(i);
  47. execution::set_value(
  48. ASIO_MOVE_OR_LVALUE(
  49. typename remove_cvref<Receiver>::type)(receiver_));
  50. }
  51. template <typename Error>
  52. void set_error(ASIO_MOVE_ARG(Error) e) ASIO_NOEXCEPT
  53. {
  54. execution::set_error(
  55. ASIO_MOVE_OR_LVALUE(
  56. typename remove_cvref<Receiver>::type)(receiver_),
  57. ASIO_MOVE_CAST(Error)(e));
  58. }
  59. void set_done() ASIO_NOEXCEPT
  60. {
  61. execution::set_done(
  62. ASIO_MOVE_OR_LVALUE(
  63. typename remove_cvref<Receiver>::type)(receiver_));
  64. }
  65. };
  66. template <typename Sender, typename Receiver,
  67. typename Function, typename Number>
  68. struct bulk_receiver_traits
  69. {
  70. typedef bulk_receiver<
  71. Receiver, Function, Number,
  72. typename execution::executor_index<
  73. typename remove_cvref<Sender>::type
  74. >::type
  75. > type;
  76. #if defined(ASIO_HAS_MOVE)
  77. typedef type arg_type;
  78. #else // defined(ASIO_HAS_MOVE)
  79. typedef const type& arg_type;
  80. #endif // defined(ASIO_HAS_MOVE)
  81. };
  82. template <typename Sender, typename Function, typename Number>
  83. struct bulk_sender : sender_base
  84. {
  85. typename remove_cvref<Sender>::type sender_;
  86. typename decay<Function>::type f_;
  87. typename decay<Number>::type n_;
  88. template <typename S, typename F, typename N>
  89. explicit bulk_sender(ASIO_MOVE_ARG(S) s,
  90. ASIO_MOVE_ARG(F) f, ASIO_MOVE_ARG(N) n)
  91. : sender_(ASIO_MOVE_CAST(S)(s)),
  92. f_(ASIO_MOVE_CAST(F)(f)),
  93. n_(ASIO_MOVE_CAST(N)(n))
  94. {
  95. }
  96. template <typename Receiver>
  97. typename connect_result<
  98. ASIO_MOVE_OR_LVALUE_TYPE(typename remove_cvref<Sender>::type),
  99. typename bulk_receiver_traits<
  100. Sender, Receiver, Function, Number
  101. >::arg_type
  102. >::type connect(ASIO_MOVE_ARG(Receiver) r,
  103. typename enable_if<
  104. can_connect<
  105. typename remove_cvref<Sender>::type,
  106. typename bulk_receiver_traits<
  107. Sender, Receiver, Function, Number
  108. >::arg_type
  109. >::value
  110. >::type* = 0) ASIO_RVALUE_REF_QUAL ASIO_NOEXCEPT
  111. {
  112. return execution::connect(
  113. ASIO_MOVE_OR_LVALUE(typename remove_cvref<Sender>::type)(sender_),
  114. typename bulk_receiver_traits<Sender, Receiver, Function, Number>::type(
  115. ASIO_MOVE_CAST(Receiver)(r),
  116. ASIO_MOVE_CAST(typename decay<Function>::type)(f_),
  117. ASIO_MOVE_CAST(typename decay<Number>::type)(n_)));
  118. }
  119. template <typename Receiver>
  120. typename connect_result<
  121. const typename remove_cvref<Sender>::type&,
  122. typename bulk_receiver_traits<
  123. Sender, Receiver, Function, Number
  124. >::arg_type
  125. >::type connect(ASIO_MOVE_ARG(Receiver) r,
  126. typename enable_if<
  127. can_connect<
  128. const typename remove_cvref<Sender>::type&,
  129. typename bulk_receiver_traits<
  130. Sender, Receiver, Function, Number
  131. >::arg_type
  132. >::value
  133. >::type* = 0) const ASIO_LVALUE_REF_QUAL ASIO_NOEXCEPT
  134. {
  135. return execution::connect(sender_,
  136. typename bulk_receiver_traits<Sender, Receiver, Function, Number>::type(
  137. ASIO_MOVE_CAST(Receiver)(r), f_, n_));
  138. }
  139. };
  140. } // namespace detail
  141. } // namespace execution
  142. namespace traits {
  143. #if !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
  144. template <typename Receiver, typename Function, typename Number, typename Index>
  145. struct set_value_member<
  146. execution::detail::bulk_receiver<Receiver, Function, Number, Index>,
  147. void()>
  148. {
  149. ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
  150. ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
  151. typedef void result_type;
  152. };
  153. #endif // !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
  154. #if !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
  155. template <typename Receiver, typename Function,
  156. typename Number, typename Index, typename Error>
  157. struct set_error_member<
  158. execution::detail::bulk_receiver<Receiver, Function, Number, Index>,
  159. Error>
  160. {
  161. ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
  162. ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
  163. typedef void result_type;
  164. };
  165. #endif // !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
  166. #if !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
  167. template <typename Receiver, typename Function, typename Number, typename Index>
  168. struct set_done_member<
  169. execution::detail::bulk_receiver<Receiver, Function, Number, Index> >
  170. {
  171. ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
  172. ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
  173. typedef void result_type;
  174. };
  175. #endif // !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
  176. #if !defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
  177. template <typename Sender, typename Function,
  178. typename Number, typename Receiver>
  179. struct connect_member<
  180. execution::detail::bulk_sender<Sender, Function, Number>,
  181. Receiver,
  182. typename enable_if<
  183. execution::can_connect<
  184. ASIO_MOVE_OR_LVALUE_TYPE(typename remove_cvref<Sender>::type),
  185. typename execution::detail::bulk_receiver_traits<
  186. Sender, Receiver, Function, Number
  187. >::arg_type
  188. >::value
  189. >::type>
  190. {
  191. ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
  192. ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
  193. typedef typename execution::connect_result<
  194. ASIO_MOVE_OR_LVALUE_TYPE(typename remove_cvref<Sender>::type),
  195. typename execution::detail::bulk_receiver_traits<
  196. Sender, Receiver, Function, Number
  197. >::arg_type
  198. >::type result_type;
  199. };
  200. template <typename Sender, typename Function,
  201. typename Number, typename Receiver>
  202. struct connect_member<
  203. const execution::detail::bulk_sender<Sender, Function, Number>,
  204. Receiver,
  205. typename enable_if<
  206. execution::can_connect<
  207. const typename remove_cvref<Sender>::type&,
  208. typename execution::detail::bulk_receiver_traits<
  209. Sender, Receiver, Function, Number
  210. >::arg_type
  211. >::value
  212. >::type>
  213. {
  214. ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
  215. ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
  216. typedef typename execution::connect_result<
  217. const typename remove_cvref<Sender>::type&,
  218. typename execution::detail::bulk_receiver_traits<
  219. Sender, Receiver, Function, Number
  220. >::arg_type
  221. >::type result_type;
  222. };
  223. #endif // !defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
  224. } // namespace traits
  225. } // namespace asio
  226. #include "asio/detail/pop_options.hpp"
  227. #endif // ASIO_EXECUTION_DETAIL_BULK_SENDER_HPP