1 // 2 // execution/detail/bulk_sender.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 11 #ifndef BOOST_ASIO_EXECUTION_DETAIL_BULK_SENDER_HPP 12 #define BOOST_ASIO_EXECUTION_DETAIL_BULK_SENDER_HPP 13 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 # pragma once 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 18 #include <boost/asio/detail/config.hpp> 19 #include <boost/asio/detail/type_traits.hpp> 20 #include <boost/asio/execution/connect.hpp> 21 #include <boost/asio/execution/executor.hpp> 22 #include <boost/asio/execution/set_done.hpp> 23 #include <boost/asio/execution/set_error.hpp> 24 #include <boost/asio/traits/connect_member.hpp> 25 #include <boost/asio/traits/set_done_member.hpp> 26 #include <boost/asio/traits/set_error_member.hpp> 27 #include <boost/asio/traits/set_value_member.hpp> 28 29 #include <boost/asio/detail/push_options.hpp> 30 31 namespace boost { 32 namespace asio { 33 namespace execution { 34 namespace detail { 35 36 template <typename Receiver, typename Function, typename Number, typename Index> 37 struct bulk_receiver 38 { 39 typename remove_cvref<Receiver>::type receiver_; 40 typename decay<Function>::type f_; 41 typename decay<Number>::type n_; 42 43 template <typename R, typename F, typename N> bulk_receiverboost::asio::execution::detail::bulk_receiver44 explicit bulk_receiver(BOOST_ASIO_MOVE_ARG(R) r, 45 BOOST_ASIO_MOVE_ARG(F) f, BOOST_ASIO_MOVE_ARG(N) n) 46 : receiver_(BOOST_ASIO_MOVE_CAST(R)(r)), 47 f_(BOOST_ASIO_MOVE_CAST(F)(f)), 48 n_(BOOST_ASIO_MOVE_CAST(N)(n)) 49 { 50 } 51 set_valueboost::asio::execution::detail::bulk_receiver52 void set_value() 53 { 54 for (Index i = 0; i < n_; ++i) 55 f_(i); 56 57 execution::set_value( 58 BOOST_ASIO_MOVE_OR_LVALUE( 59 typename remove_cvref<Receiver>::type)(receiver_)); 60 } 61 62 template <typename Error> set_errorboost::asio::execution::detail::bulk_receiver63 void set_error(BOOST_ASIO_MOVE_ARG(Error) e) BOOST_ASIO_NOEXCEPT 64 { 65 execution::set_error( 66 BOOST_ASIO_MOVE_OR_LVALUE( 67 typename remove_cvref<Receiver>::type)(receiver_), 68 BOOST_ASIO_MOVE_CAST(Error)(e)); 69 } 70 set_doneboost::asio::execution::detail::bulk_receiver71 void set_done() BOOST_ASIO_NOEXCEPT 72 { 73 execution::set_done( 74 BOOST_ASIO_MOVE_OR_LVALUE( 75 typename remove_cvref<Receiver>::type)(receiver_)); 76 } 77 }; 78 79 template <typename Sender, typename Receiver, 80 typename Function, typename Number> 81 struct bulk_receiver_traits 82 { 83 typedef bulk_receiver< 84 Receiver, Function, Number, 85 typename execution::executor_index< 86 typename remove_cvref<Sender>::type 87 >::type 88 > type; 89 90 #if defined(BOOST_ASIO_HAS_MOVE) 91 typedef type arg_type; 92 #else // defined(BOOST_ASIO_HAS_MOVE) 93 typedef const type& arg_type; 94 #endif // defined(BOOST_ASIO_HAS_MOVE) 95 }; 96 97 template <typename Sender, typename Function, typename Number> 98 struct bulk_sender : sender_base 99 { 100 typename remove_cvref<Sender>::type sender_; 101 typename decay<Function>::type f_; 102 typename decay<Number>::type n_; 103 104 template <typename S, typename F, typename N> bulk_senderboost::asio::execution::detail::bulk_sender105 explicit bulk_sender(BOOST_ASIO_MOVE_ARG(S) s, 106 BOOST_ASIO_MOVE_ARG(F) f, BOOST_ASIO_MOVE_ARG(N) n) 107 : sender_(BOOST_ASIO_MOVE_CAST(S)(s)), 108 f_(BOOST_ASIO_MOVE_CAST(F)(f)), 109 n_(BOOST_ASIO_MOVE_CAST(N)(n)) 110 { 111 } 112 113 template <typename Receiver> 114 typename connect_result< 115 BOOST_ASIO_MOVE_OR_LVALUE_TYPE(typename remove_cvref<Sender>::type), 116 typename bulk_receiver_traits< 117 Sender, Receiver, Function, Number 118 >::arg_type connectboost::asio::execution::detail::bulk_sender119 >::type connect(BOOST_ASIO_MOVE_ARG(Receiver) r, 120 typename enable_if< 121 can_connect< 122 typename remove_cvref<Sender>::type, 123 typename bulk_receiver_traits< 124 Sender, Receiver, Function, Number 125 >::arg_type 126 >::value 127 >::type* = 0) BOOST_ASIO_RVALUE_REF_QUAL BOOST_ASIO_NOEXCEPT 128 { 129 return execution::connect( 130 BOOST_ASIO_MOVE_OR_LVALUE(typename remove_cvref<Sender>::type)(sender_), 131 typename bulk_receiver_traits<Sender, Receiver, Function, Number>::type( 132 BOOST_ASIO_MOVE_CAST(Receiver)(r), 133 BOOST_ASIO_MOVE_CAST(typename decay<Function>::type)(f_), 134 BOOST_ASIO_MOVE_CAST(typename decay<Number>::type)(n_))); 135 } 136 137 template <typename Receiver> 138 typename connect_result< 139 const typename remove_cvref<Sender>::type&, 140 typename bulk_receiver_traits< 141 Sender, Receiver, Function, Number 142 >::arg_type connectboost::asio::execution::detail::bulk_sender143 >::type connect(BOOST_ASIO_MOVE_ARG(Receiver) r, 144 typename enable_if< 145 can_connect< 146 const typename remove_cvref<Sender>::type&, 147 typename bulk_receiver_traits< 148 Sender, Receiver, Function, Number 149 >::arg_type 150 >::value 151 >::type* = 0) const BOOST_ASIO_LVALUE_REF_QUAL BOOST_ASIO_NOEXCEPT 152 { 153 return execution::connect(sender_, 154 typename bulk_receiver_traits<Sender, Receiver, Function, Number>::type( 155 BOOST_ASIO_MOVE_CAST(Receiver)(r), f_, n_)); 156 } 157 }; 158 159 } // namespace detail 160 } // namespace execution 161 namespace traits { 162 163 #if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT) 164 165 template <typename Receiver, typename Function, typename Number, typename Index> 166 struct set_value_member< 167 execution::detail::bulk_receiver<Receiver, Function, Number, Index>, 168 void()> 169 { 170 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 171 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); 172 typedef void result_type; 173 }; 174 175 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT) 176 177 #if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT) 178 179 template <typename Receiver, typename Function, 180 typename Number, typename Index, typename Error> 181 struct set_error_member< 182 execution::detail::bulk_receiver<Receiver, Function, Number, Index>, 183 Error> 184 { 185 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 186 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); 187 typedef void result_type; 188 }; 189 190 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT) 191 192 #if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT) 193 194 template <typename Receiver, typename Function, typename Number, typename Index> 195 struct set_done_member< 196 execution::detail::bulk_receiver<Receiver, Function, Number, Index> > 197 { 198 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 199 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); 200 typedef void result_type; 201 }; 202 203 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT) 204 205 #if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT) 206 207 template <typename Sender, typename Function, 208 typename Number, typename Receiver> 209 struct connect_member< 210 execution::detail::bulk_sender<Sender, Function, Number>, 211 Receiver, 212 typename enable_if< 213 execution::can_connect< 214 BOOST_ASIO_MOVE_OR_LVALUE_TYPE(typename remove_cvref<Sender>::type), 215 typename execution::detail::bulk_receiver_traits< 216 Sender, Receiver, Function, Number 217 >::arg_type 218 >::value 219 >::type> 220 { 221 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 222 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); 223 typedef typename execution::connect_result< 224 BOOST_ASIO_MOVE_OR_LVALUE_TYPE(typename remove_cvref<Sender>::type), 225 typename execution::detail::bulk_receiver_traits< 226 Sender, Receiver, Function, Number 227 >::arg_type 228 >::type result_type; 229 }; 230 231 template <typename Sender, typename Function, 232 typename Number, typename Receiver> 233 struct connect_member< 234 const execution::detail::bulk_sender<Sender, Function, Number>, 235 Receiver, 236 typename enable_if< 237 execution::can_connect< 238 const typename remove_cvref<Sender>::type&, 239 typename execution::detail::bulk_receiver_traits< 240 Sender, Receiver, Function, Number 241 >::arg_type 242 >::value 243 >::type> 244 { 245 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 246 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); 247 typedef typename execution::connect_result< 248 const typename remove_cvref<Sender>::type&, 249 typename execution::detail::bulk_receiver_traits< 250 Sender, Receiver, Function, Number 251 >::arg_type 252 >::type result_type; 253 }; 254 255 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT) 256 257 } // namespace traits 258 } // namespace asio 259 } // namespace boost 260 261 #include <boost/asio/detail/pop_options.hpp> 262 263 #endif // BOOST_ASIO_EXECUTION_DETAIL_BULK_SENDER_HPP 264