File indexing completed on 2025-01-18 09:28:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_IMPL_WRITE_HPP
0012 #define BOOST_ASIO_IMPL_WRITE_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/associator.hpp>
0019 #include <boost/asio/buffer.hpp>
0020 #include <boost/asio/detail/array_fwd.hpp>
0021 #include <boost/asio/detail/base_from_cancellation_state.hpp>
0022 #include <boost/asio/detail/base_from_completion_cond.hpp>
0023 #include <boost/asio/detail/bind_handler.hpp>
0024 #include <boost/asio/detail/consuming_buffers.hpp>
0025 #include <boost/asio/detail/dependent_type.hpp>
0026 #include <boost/asio/detail/handler_cont_helpers.hpp>
0027 #include <boost/asio/detail/handler_tracking.hpp>
0028 #include <boost/asio/detail/handler_type_requirements.hpp>
0029 #include <boost/asio/detail/non_const_lvalue.hpp>
0030 #include <boost/asio/detail/throw_error.hpp>
0031
0032 #include <boost/asio/detail/push_options.hpp>
0033
0034 namespace boost {
0035 namespace asio {
0036
0037 namespace detail
0038 {
0039 template <typename SyncWriteStream, typename ConstBufferSequence,
0040 typename ConstBufferIterator, typename CompletionCondition>
0041 std::size_t write(SyncWriteStream& s,
0042 const ConstBufferSequence& buffers, const ConstBufferIterator&,
0043 CompletionCondition completion_condition, boost::system::error_code& ec)
0044 {
0045 ec = boost::system::error_code();
0046 boost::asio::detail::consuming_buffers<const_buffer,
0047 ConstBufferSequence, ConstBufferIterator> tmp(buffers);
0048 while (!tmp.empty())
0049 {
0050 if (std::size_t max_size = detail::adapt_completion_condition_result(
0051 completion_condition(ec, tmp.total_consumed())))
0052 tmp.consume(s.write_some(tmp.prepare(max_size), ec));
0053 else
0054 break;
0055 }
0056 return tmp.total_consumed();
0057 }
0058 }
0059
0060 template <typename SyncWriteStream, typename ConstBufferSequence,
0061 typename CompletionCondition>
0062 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
0063 CompletionCondition completion_condition, boost::system::error_code& ec,
0064 constraint_t<
0065 is_const_buffer_sequence<ConstBufferSequence>::value
0066 >)
0067 {
0068 return detail::write(s, buffers,
0069 boost::asio::buffer_sequence_begin(buffers),
0070 static_cast<CompletionCondition&&>(completion_condition), ec);
0071 }
0072
0073 template <typename SyncWriteStream, typename ConstBufferSequence>
0074 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
0075 constraint_t<
0076 is_const_buffer_sequence<ConstBufferSequence>::value
0077 >)
0078 {
0079 boost::system::error_code ec;
0080 std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec);
0081 boost::asio::detail::throw_error(ec, "write");
0082 return bytes_transferred;
0083 }
0084
0085 template <typename SyncWriteStream, typename ConstBufferSequence>
0086 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
0087 boost::system::error_code& ec,
0088 constraint_t<
0089 is_const_buffer_sequence<ConstBufferSequence>::value
0090 >)
0091 {
0092 return write(s, buffers, transfer_all(), ec);
0093 }
0094
0095 template <typename SyncWriteStream, typename ConstBufferSequence,
0096 typename CompletionCondition>
0097 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
0098 CompletionCondition completion_condition,
0099 constraint_t<
0100 is_const_buffer_sequence<ConstBufferSequence>::value
0101 >)
0102 {
0103 boost::system::error_code ec;
0104 std::size_t bytes_transferred = write(s, buffers,
0105 static_cast<CompletionCondition&&>(completion_condition), ec);
0106 boost::asio::detail::throw_error(ec, "write");
0107 return bytes_transferred;
0108 }
0109
0110 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
0111
0112 template <typename SyncWriteStream, typename DynamicBuffer_v1,
0113 typename CompletionCondition>
0114 std::size_t write(SyncWriteStream& s,
0115 DynamicBuffer_v1&& buffers,
0116 CompletionCondition completion_condition, boost::system::error_code& ec,
0117 constraint_t<
0118 is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0119 >,
0120 constraint_t<
0121 !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0122 >)
0123 {
0124 decay_t<DynamicBuffer_v1> b(
0125 static_cast<DynamicBuffer_v1&&>(buffers));
0126
0127 std::size_t bytes_transferred = write(s, b.data(),
0128 static_cast<CompletionCondition&&>(completion_condition), ec);
0129 b.consume(bytes_transferred);
0130 return bytes_transferred;
0131 }
0132
0133 template <typename SyncWriteStream, typename DynamicBuffer_v1>
0134 inline std::size_t write(SyncWriteStream& s,
0135 DynamicBuffer_v1&& buffers,
0136 constraint_t<
0137 is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0138 >,
0139 constraint_t<
0140 !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0141 >)
0142 {
0143 boost::system::error_code ec;
0144 std::size_t bytes_transferred = write(s,
0145 static_cast<DynamicBuffer_v1&&>(buffers),
0146 transfer_all(), ec);
0147 boost::asio::detail::throw_error(ec, "write");
0148 return bytes_transferred;
0149 }
0150
0151 template <typename SyncWriteStream, typename DynamicBuffer_v1>
0152 inline std::size_t write(SyncWriteStream& s,
0153 DynamicBuffer_v1&& buffers,
0154 boost::system::error_code& ec,
0155 constraint_t<
0156 is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0157 >,
0158 constraint_t<
0159 !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0160 >)
0161 {
0162 return write(s, static_cast<DynamicBuffer_v1&&>(buffers),
0163 transfer_all(), ec);
0164 }
0165
0166 template <typename SyncWriteStream, typename DynamicBuffer_v1,
0167 typename CompletionCondition>
0168 inline std::size_t write(SyncWriteStream& s,
0169 DynamicBuffer_v1&& buffers,
0170 CompletionCondition completion_condition,
0171 constraint_t<
0172 is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0173 >,
0174 constraint_t<
0175 !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0176 >)
0177 {
0178 boost::system::error_code ec;
0179 std::size_t bytes_transferred = write(s,
0180 static_cast<DynamicBuffer_v1&&>(buffers),
0181 static_cast<CompletionCondition&&>(completion_condition), ec);
0182 boost::asio::detail::throw_error(ec, "write");
0183 return bytes_transferred;
0184 }
0185
0186 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
0187 #if !defined(BOOST_ASIO_NO_IOSTREAM)
0188
0189 template <typename SyncWriteStream, typename Allocator,
0190 typename CompletionCondition>
0191 inline std::size_t write(SyncWriteStream& s,
0192 boost::asio::basic_streambuf<Allocator>& b,
0193 CompletionCondition completion_condition, boost::system::error_code& ec)
0194 {
0195 return write(s, basic_streambuf_ref<Allocator>(b),
0196 static_cast<CompletionCondition&&>(completion_condition), ec);
0197 }
0198
0199 template <typename SyncWriteStream, typename Allocator>
0200 inline std::size_t write(SyncWriteStream& s,
0201 boost::asio::basic_streambuf<Allocator>& b)
0202 {
0203 return write(s, basic_streambuf_ref<Allocator>(b));
0204 }
0205
0206 template <typename SyncWriteStream, typename Allocator>
0207 inline std::size_t write(SyncWriteStream& s,
0208 boost::asio::basic_streambuf<Allocator>& b,
0209 boost::system::error_code& ec)
0210 {
0211 return write(s, basic_streambuf_ref<Allocator>(b), ec);
0212 }
0213
0214 template <typename SyncWriteStream, typename Allocator,
0215 typename CompletionCondition>
0216 inline std::size_t write(SyncWriteStream& s,
0217 boost::asio::basic_streambuf<Allocator>& b,
0218 CompletionCondition completion_condition)
0219 {
0220 return write(s, basic_streambuf_ref<Allocator>(b),
0221 static_cast<CompletionCondition&&>(completion_condition));
0222 }
0223
0224 #endif
0225 #endif
0226 #endif
0227
0228 template <typename SyncWriteStream, typename DynamicBuffer_v2,
0229 typename CompletionCondition>
0230 std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
0231 CompletionCondition completion_condition, boost::system::error_code& ec,
0232 constraint_t<
0233 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
0234 >)
0235 {
0236 std::size_t bytes_transferred = write(s, buffers.data(0, buffers.size()),
0237 static_cast<CompletionCondition&&>(completion_condition), ec);
0238 buffers.consume(bytes_transferred);
0239 return bytes_transferred;
0240 }
0241
0242 template <typename SyncWriteStream, typename DynamicBuffer_v2>
0243 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
0244 constraint_t<
0245 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
0246 >)
0247 {
0248 boost::system::error_code ec;
0249 std::size_t bytes_transferred = write(s,
0250 static_cast<DynamicBuffer_v2&&>(buffers),
0251 transfer_all(), ec);
0252 boost::asio::detail::throw_error(ec, "write");
0253 return bytes_transferred;
0254 }
0255
0256 template <typename SyncWriteStream, typename DynamicBuffer_v2>
0257 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
0258 boost::system::error_code& ec,
0259 constraint_t<
0260 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
0261 >)
0262 {
0263 return write(s, static_cast<DynamicBuffer_v2&&>(buffers),
0264 transfer_all(), ec);
0265 }
0266
0267 template <typename SyncWriteStream, typename DynamicBuffer_v2,
0268 typename CompletionCondition>
0269 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
0270 CompletionCondition completion_condition,
0271 constraint_t<
0272 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
0273 >)
0274 {
0275 boost::system::error_code ec;
0276 std::size_t bytes_transferred = write(s,
0277 static_cast<DynamicBuffer_v2&&>(buffers),
0278 static_cast<CompletionCondition&&>(completion_condition), ec);
0279 boost::asio::detail::throw_error(ec, "write");
0280 return bytes_transferred;
0281 }
0282
0283 namespace detail
0284 {
0285 template <typename AsyncWriteStream, typename ConstBufferSequence,
0286 typename ConstBufferIterator, typename CompletionCondition,
0287 typename WriteHandler>
0288 class write_op
0289 : public base_from_cancellation_state<WriteHandler>,
0290 base_from_completion_cond<CompletionCondition>
0291 {
0292 public:
0293 write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers,
0294 CompletionCondition& completion_condition, WriteHandler& handler)
0295 : base_from_cancellation_state<WriteHandler>(
0296 handler, enable_partial_cancellation()),
0297 base_from_completion_cond<CompletionCondition>(completion_condition),
0298 stream_(stream),
0299 buffers_(buffers),
0300 start_(0),
0301 handler_(static_cast<WriteHandler&&>(handler))
0302 {
0303 }
0304
0305 write_op(const write_op& other)
0306 : base_from_cancellation_state<WriteHandler>(other),
0307 base_from_completion_cond<CompletionCondition>(other),
0308 stream_(other.stream_),
0309 buffers_(other.buffers_),
0310 start_(other.start_),
0311 handler_(other.handler_)
0312 {
0313 }
0314
0315 write_op(write_op&& other)
0316 : base_from_cancellation_state<WriteHandler>(
0317 static_cast<base_from_cancellation_state<WriteHandler>&&>(other)),
0318 base_from_completion_cond<CompletionCondition>(
0319 static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),
0320 stream_(other.stream_),
0321 buffers_(static_cast<buffers_type&&>(other.buffers_)),
0322 start_(other.start_),
0323 handler_(static_cast<WriteHandler&&>(other.handler_))
0324 {
0325 }
0326
0327 void operator()(boost::system::error_code ec,
0328 std::size_t bytes_transferred, int start = 0)
0329 {
0330 std::size_t max_size;
0331 switch (start_ = start)
0332 {
0333 case 1:
0334 max_size = this->check_for_completion(ec, buffers_.total_consumed());
0335 for (;;)
0336 {
0337 {
0338 BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_write"));
0339 stream_.async_write_some(buffers_.prepare(max_size),
0340 static_cast<write_op&&>(*this));
0341 }
0342 return; default:
0343 buffers_.consume(bytes_transferred);
0344 if ((!ec && bytes_transferred == 0) || buffers_.empty())
0345 break;
0346 max_size = this->check_for_completion(ec, buffers_.total_consumed());
0347 if (max_size == 0)
0348 break;
0349 if (this->cancelled() != cancellation_type::none)
0350 {
0351 ec = error::operation_aborted;
0352 break;
0353 }
0354 }
0355
0356 static_cast<WriteHandler&&>(handler_)(
0357 static_cast<const boost::system::error_code&>(ec),
0358 static_cast<const std::size_t&>(buffers_.total_consumed()));
0359 }
0360 }
0361
0362
0363 typedef boost::asio::detail::consuming_buffers<const_buffer,
0364 ConstBufferSequence, ConstBufferIterator> buffers_type;
0365
0366 AsyncWriteStream& stream_;
0367 buffers_type buffers_;
0368 int start_;
0369 WriteHandler handler_;
0370 };
0371
0372 template <typename AsyncWriteStream, typename ConstBufferSequence,
0373 typename ConstBufferIterator, typename CompletionCondition,
0374 typename WriteHandler>
0375 inline bool asio_handler_is_continuation(
0376 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
0377 CompletionCondition, WriteHandler>* this_handler)
0378 {
0379 return this_handler->start_ == 0 ? true
0380 : boost_asio_handler_cont_helpers::is_continuation(
0381 this_handler->handler_);
0382 }
0383
0384 template <typename AsyncWriteStream, typename ConstBufferSequence,
0385 typename ConstBufferIterator, typename CompletionCondition,
0386 typename WriteHandler>
0387 inline void start_write_op(AsyncWriteStream& stream,
0388 const ConstBufferSequence& buffers, const ConstBufferIterator&,
0389 CompletionCondition& completion_condition, WriteHandler& handler)
0390 {
0391 detail::write_op<AsyncWriteStream, ConstBufferSequence,
0392 ConstBufferIterator, CompletionCondition, WriteHandler>(
0393 stream, buffers, completion_condition, handler)(
0394 boost::system::error_code(), 0, 1);
0395 }
0396
0397 template <typename AsyncWriteStream>
0398 class initiate_async_write
0399 {
0400 public:
0401 typedef typename AsyncWriteStream::executor_type executor_type;
0402
0403 explicit initiate_async_write(AsyncWriteStream& stream)
0404 : stream_(stream)
0405 {
0406 }
0407
0408 executor_type get_executor() const noexcept
0409 {
0410 return stream_.get_executor();
0411 }
0412
0413 template <typename WriteHandler, typename ConstBufferSequence,
0414 typename CompletionCondition>
0415 void operator()(WriteHandler&& handler,
0416 const ConstBufferSequence& buffers,
0417 CompletionCondition&& completion_cond) const
0418 {
0419
0420
0421 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
0422
0423 non_const_lvalue<WriteHandler> handler2(handler);
0424 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
0425 start_write_op(stream_, buffers,
0426 boost::asio::buffer_sequence_begin(buffers),
0427 completion_cond2.value, handler2.value);
0428 }
0429
0430 private:
0431 AsyncWriteStream& stream_;
0432 };
0433 }
0434
0435 #if !defined(GENERATING_DOCUMENTATION)
0436
0437 template <template <typename, typename> class Associator,
0438 typename AsyncWriteStream, typename ConstBufferSequence,
0439 typename ConstBufferIterator, typename CompletionCondition,
0440 typename WriteHandler, typename DefaultCandidate>
0441 struct associator<Associator,
0442 detail::write_op<AsyncWriteStream, ConstBufferSequence,
0443 ConstBufferIterator, CompletionCondition, WriteHandler>,
0444 DefaultCandidate>
0445 : Associator<WriteHandler, DefaultCandidate>
0446 {
0447 static typename Associator<WriteHandler, DefaultCandidate>::type get(
0448 const detail::write_op<AsyncWriteStream, ConstBufferSequence,
0449 ConstBufferIterator, CompletionCondition, WriteHandler>& h) noexcept
0450 {
0451 return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);
0452 }
0453
0454 static auto get(
0455 const detail::write_op<AsyncWriteStream, ConstBufferSequence,
0456 ConstBufferIterator, CompletionCondition, WriteHandler>& h,
0457 const DefaultCandidate& c) noexcept
0458 -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))
0459 {
0460 return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);
0461 }
0462 };
0463
0464 #endif
0465
0466 template <typename AsyncWriteStream,
0467 typename ConstBufferSequence, typename CompletionCondition,
0468 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0469 std::size_t)) WriteToken>
0470 inline auto async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
0471 CompletionCondition completion_condition, WriteToken&& token,
0472 constraint_t<
0473 is_const_buffer_sequence<ConstBufferSequence>::value
0474 >)
0475 -> decltype(
0476 async_initiate<WriteToken,
0477 void (boost::system::error_code, std::size_t)>(
0478 declval<detail::initiate_async_write<AsyncWriteStream>>(),
0479 token, buffers,
0480 static_cast<CompletionCondition&&>(completion_condition)))
0481 {
0482 return async_initiate<WriteToken,
0483 void (boost::system::error_code, std::size_t)>(
0484 detail::initiate_async_write<AsyncWriteStream>(s),
0485 token, buffers,
0486 static_cast<CompletionCondition&&>(completion_condition));
0487 }
0488
0489 template <typename AsyncWriteStream, typename ConstBufferSequence,
0490 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0491 std::size_t)) WriteToken>
0492 inline auto async_write(AsyncWriteStream& s,
0493 const ConstBufferSequence& buffers, WriteToken&& token,
0494 constraint_t<
0495 is_const_buffer_sequence<ConstBufferSequence>::value
0496 >)
0497 -> decltype(
0498 async_initiate<WriteToken,
0499 void (boost::system::error_code, std::size_t)>(
0500 declval<detail::initiate_async_write<AsyncWriteStream>>(),
0501 token, buffers, transfer_all()))
0502 {
0503 return async_initiate<WriteToken,
0504 void (boost::system::error_code, std::size_t)>(
0505 detail::initiate_async_write<AsyncWriteStream>(s),
0506 token, buffers, transfer_all());
0507 }
0508
0509 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
0510
0511 namespace detail
0512 {
0513 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
0514 typename CompletionCondition, typename WriteHandler>
0515 class write_dynbuf_v1_op
0516 {
0517 public:
0518 template <typename BufferSequence>
0519 write_dynbuf_v1_op(AsyncWriteStream& stream,
0520 BufferSequence&& buffers,
0521 CompletionCondition& completion_condition, WriteHandler& handler)
0522 : stream_(stream),
0523 buffers_(static_cast<BufferSequence&&>(buffers)),
0524 completion_condition_(
0525 static_cast<CompletionCondition&&>(completion_condition)),
0526 handler_(static_cast<WriteHandler&&>(handler))
0527 {
0528 }
0529
0530 write_dynbuf_v1_op(const write_dynbuf_v1_op& other)
0531 : stream_(other.stream_),
0532 buffers_(other.buffers_),
0533 completion_condition_(other.completion_condition_),
0534 handler_(other.handler_)
0535 {
0536 }
0537
0538 write_dynbuf_v1_op(write_dynbuf_v1_op&& other)
0539 : stream_(other.stream_),
0540 buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)),
0541 completion_condition_(
0542 static_cast<CompletionCondition&&>(
0543 other.completion_condition_)),
0544 handler_(static_cast<WriteHandler&&>(other.handler_))
0545 {
0546 }
0547
0548 void operator()(const boost::system::error_code& ec,
0549 std::size_t bytes_transferred, int start = 0)
0550 {
0551 switch (start)
0552 {
0553 case 1:
0554 async_write(stream_, buffers_.data(),
0555 static_cast<CompletionCondition&&>(completion_condition_),
0556 static_cast<write_dynbuf_v1_op&&>(*this));
0557 return; default:
0558 buffers_.consume(bytes_transferred);
0559 static_cast<WriteHandler&&>(handler_)(ec,
0560 static_cast<const std::size_t&>(bytes_transferred));
0561 }
0562 }
0563
0564
0565 AsyncWriteStream& stream_;
0566 DynamicBuffer_v1 buffers_;
0567 CompletionCondition completion_condition_;
0568 WriteHandler handler_;
0569 };
0570
0571 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
0572 typename CompletionCondition, typename WriteHandler>
0573 inline bool asio_handler_is_continuation(
0574 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
0575 CompletionCondition, WriteHandler>* this_handler)
0576 {
0577 return boost_asio_handler_cont_helpers::is_continuation(
0578 this_handler->handler_);
0579 }
0580
0581 template <typename AsyncWriteStream>
0582 class initiate_async_write_dynbuf_v1
0583 {
0584 public:
0585 typedef typename AsyncWriteStream::executor_type executor_type;
0586
0587 explicit initiate_async_write_dynbuf_v1(AsyncWriteStream& stream)
0588 : stream_(stream)
0589 {
0590 }
0591
0592 executor_type get_executor() const noexcept
0593 {
0594 return stream_.get_executor();
0595 }
0596
0597 template <typename WriteHandler, typename DynamicBuffer_v1,
0598 typename CompletionCondition>
0599 void operator()(WriteHandler&& handler,
0600 DynamicBuffer_v1&& buffers,
0601 CompletionCondition&& completion_cond) const
0602 {
0603
0604
0605 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
0606
0607 non_const_lvalue<WriteHandler> handler2(handler);
0608 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
0609 write_dynbuf_v1_op<AsyncWriteStream,
0610 decay_t<DynamicBuffer_v1>,
0611 CompletionCondition, decay_t<WriteHandler>>(
0612 stream_, static_cast<DynamicBuffer_v1&&>(buffers),
0613 completion_cond2.value, handler2.value)(
0614 boost::system::error_code(), 0, 1);
0615 }
0616
0617 private:
0618 AsyncWriteStream& stream_;
0619 };
0620 }
0621
0622 #if !defined(GENERATING_DOCUMENTATION)
0623
0624 template <template <typename, typename> class Associator,
0625 typename AsyncWriteStream, typename DynamicBuffer_v1,
0626 typename CompletionCondition, typename WriteHandler,
0627 typename DefaultCandidate>
0628 struct associator<Associator,
0629 detail::write_dynbuf_v1_op<AsyncWriteStream,
0630 DynamicBuffer_v1, CompletionCondition, WriteHandler>,
0631 DefaultCandidate>
0632 : Associator<WriteHandler, DefaultCandidate>
0633 {
0634 static typename Associator<WriteHandler, DefaultCandidate>::type get(
0635 const detail::write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
0636 CompletionCondition, WriteHandler>& h) noexcept
0637 {
0638 return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);
0639 }
0640
0641 static auto get(
0642 const detail::write_dynbuf_v1_op<AsyncWriteStream,
0643 DynamicBuffer_v1, CompletionCondition, WriteHandler>& h,
0644 const DefaultCandidate& c) noexcept
0645 -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))
0646 {
0647 return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);
0648 }
0649 };
0650
0651 #endif
0652
0653 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
0654 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0655 std::size_t)) WriteToken>
0656 inline auto async_write(AsyncWriteStream& s,
0657 DynamicBuffer_v1&& buffers, WriteToken&& token,
0658 constraint_t<
0659 is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0660 >,
0661 constraint_t<
0662 !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0663 >)
0664 -> decltype(
0665 async_initiate<WriteToken,
0666 void (boost::system::error_code, std::size_t)>(
0667 declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>>(),
0668 token, static_cast<DynamicBuffer_v1&&>(buffers),
0669 transfer_all()))
0670 {
0671 return async_initiate<WriteToken,
0672 void (boost::system::error_code, std::size_t)>(
0673 detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),
0674 token, static_cast<DynamicBuffer_v1&&>(buffers),
0675 transfer_all());
0676 }
0677
0678 template <typename AsyncWriteStream,
0679 typename DynamicBuffer_v1, typename CompletionCondition,
0680 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0681 std::size_t)) WriteToken>
0682 inline auto async_write(AsyncWriteStream& s, DynamicBuffer_v1&& buffers,
0683 CompletionCondition completion_condition, WriteToken&& token,
0684 constraint_t<
0685 is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0686 >,
0687 constraint_t<
0688 !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0689 >)
0690 -> decltype(
0691 async_initiate<WriteToken,
0692 void (boost::system::error_code, std::size_t)>(
0693 declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>>(),
0694 token, static_cast<DynamicBuffer_v1&&>(buffers),
0695 static_cast<CompletionCondition&&>(completion_condition)))
0696 {
0697 return async_initiate<WriteToken,
0698 void (boost::system::error_code, std::size_t)>(
0699 detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),
0700 token, static_cast<DynamicBuffer_v1&&>(buffers),
0701 static_cast<CompletionCondition&&>(completion_condition));
0702 }
0703
0704 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
0705 #if !defined(BOOST_ASIO_NO_IOSTREAM)
0706
0707 template <typename AsyncWriteStream, typename Allocator,
0708 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0709 std::size_t)) WriteToken>
0710 inline auto async_write(AsyncWriteStream& s,
0711 boost::asio::basic_streambuf<Allocator>& b,
0712 WriteToken&& token)
0713 -> decltype(
0714 async_initiate<WriteToken,
0715 void (boost::system::error_code, std::size_t)>(
0716 declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>>(),
0717 token, basic_streambuf_ref<Allocator>(b), transfer_all()))
0718 {
0719 return async_initiate<WriteToken,
0720 void (boost::system::error_code, std::size_t)>(
0721 detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),
0722 token, basic_streambuf_ref<Allocator>(b), transfer_all());
0723 }
0724
0725 template <typename AsyncWriteStream,
0726 typename Allocator, typename CompletionCondition,
0727 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0728 std::size_t)) WriteToken>
0729 inline auto async_write(AsyncWriteStream& s,
0730 boost::asio::basic_streambuf<Allocator>& b,
0731 CompletionCondition completion_condition, WriteToken&& token)
0732 -> decltype(
0733 async_initiate<WriteToken,
0734 void (boost::system::error_code, std::size_t)>(
0735 declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>>(),
0736 token, basic_streambuf_ref<Allocator>(b),
0737 static_cast<CompletionCondition&&>(completion_condition)))
0738 {
0739 return async_initiate<WriteToken,
0740 void (boost::system::error_code, std::size_t)>(
0741 detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),
0742 token, basic_streambuf_ref<Allocator>(b),
0743 static_cast<CompletionCondition&&>(completion_condition));
0744 }
0745
0746 #endif
0747 #endif
0748 #endif
0749
0750 namespace detail
0751 {
0752 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
0753 typename CompletionCondition, typename WriteHandler>
0754 class write_dynbuf_v2_op
0755 {
0756 public:
0757 template <typename BufferSequence>
0758 write_dynbuf_v2_op(AsyncWriteStream& stream,
0759 BufferSequence&& buffers,
0760 CompletionCondition& completion_condition, WriteHandler& handler)
0761 : stream_(stream),
0762 buffers_(static_cast<BufferSequence&&>(buffers)),
0763 completion_condition_(
0764 static_cast<CompletionCondition&&>(completion_condition)),
0765 handler_(static_cast<WriteHandler&&>(handler))
0766 {
0767 }
0768
0769 write_dynbuf_v2_op(const write_dynbuf_v2_op& other)
0770 : stream_(other.stream_),
0771 buffers_(other.buffers_),
0772 completion_condition_(other.completion_condition_),
0773 handler_(other.handler_)
0774 {
0775 }
0776
0777 write_dynbuf_v2_op(write_dynbuf_v2_op&& other)
0778 : stream_(other.stream_),
0779 buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)),
0780 completion_condition_(
0781 static_cast<CompletionCondition&&>(
0782 other.completion_condition_)),
0783 handler_(static_cast<WriteHandler&&>(other.handler_))
0784 {
0785 }
0786
0787 void operator()(const boost::system::error_code& ec,
0788 std::size_t bytes_transferred, int start = 0)
0789 {
0790 switch (start)
0791 {
0792 case 1:
0793 async_write(stream_, buffers_.data(0, buffers_.size()),
0794 static_cast<CompletionCondition&&>(completion_condition_),
0795 static_cast<write_dynbuf_v2_op&&>(*this));
0796 return; default:
0797 buffers_.consume(bytes_transferred);
0798 static_cast<WriteHandler&&>(handler_)(ec,
0799 static_cast<const std::size_t&>(bytes_transferred));
0800 }
0801 }
0802
0803
0804 AsyncWriteStream& stream_;
0805 DynamicBuffer_v2 buffers_;
0806 CompletionCondition completion_condition_;
0807 WriteHandler handler_;
0808 };
0809
0810 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
0811 typename CompletionCondition, typename WriteHandler>
0812 inline bool asio_handler_is_continuation(
0813 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
0814 CompletionCondition, WriteHandler>* this_handler)
0815 {
0816 return boost_asio_handler_cont_helpers::is_continuation(
0817 this_handler->handler_);
0818 }
0819
0820 template <typename AsyncWriteStream>
0821 class initiate_async_write_dynbuf_v2
0822 {
0823 public:
0824 typedef typename AsyncWriteStream::executor_type executor_type;
0825
0826 explicit initiate_async_write_dynbuf_v2(AsyncWriteStream& stream)
0827 : stream_(stream)
0828 {
0829 }
0830
0831 executor_type get_executor() const noexcept
0832 {
0833 return stream_.get_executor();
0834 }
0835
0836 template <typename WriteHandler, typename DynamicBuffer_v2,
0837 typename CompletionCondition>
0838 void operator()(WriteHandler&& handler,
0839 DynamicBuffer_v2&& buffers,
0840 CompletionCondition&& completion_cond) const
0841 {
0842
0843
0844 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
0845
0846 non_const_lvalue<WriteHandler> handler2(handler);
0847 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
0848 write_dynbuf_v2_op<AsyncWriteStream, decay_t<DynamicBuffer_v2>,
0849 CompletionCondition, decay_t<WriteHandler>>(
0850 stream_, static_cast<DynamicBuffer_v2&&>(buffers),
0851 completion_cond2.value, handler2.value)(
0852 boost::system::error_code(), 0, 1);
0853 }
0854
0855 private:
0856 AsyncWriteStream& stream_;
0857 };
0858 }
0859
0860 #if !defined(GENERATING_DOCUMENTATION)
0861
0862 template <template <typename, typename> class Associator,
0863 typename AsyncWriteStream, typename DynamicBuffer_v2,
0864 typename CompletionCondition, typename WriteHandler,
0865 typename DefaultCandidate>
0866 struct associator<Associator,
0867 detail::write_dynbuf_v2_op<AsyncWriteStream,
0868 DynamicBuffer_v2, CompletionCondition, WriteHandler>,
0869 DefaultCandidate>
0870 : Associator<WriteHandler, DefaultCandidate>
0871 {
0872 static typename Associator<WriteHandler, DefaultCandidate>::type get(
0873 const detail::write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
0874 CompletionCondition, WriteHandler>& h) noexcept
0875 {
0876 return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);
0877 }
0878
0879 static auto get(
0880 const detail::write_dynbuf_v2_op<AsyncWriteStream,
0881 DynamicBuffer_v2, CompletionCondition, WriteHandler>& h,
0882 const DefaultCandidate& c) noexcept
0883 -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))
0884 {
0885 return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);
0886 }
0887 };
0888
0889 #endif
0890
0891 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
0892 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0893 std::size_t)) WriteToken>
0894 inline auto async_write(AsyncWriteStream& s,
0895 DynamicBuffer_v2 buffers, WriteToken&& token,
0896 constraint_t<
0897 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
0898 >)
0899 -> decltype(
0900 async_initiate<WriteToken,
0901 void (boost::system::error_code, std::size_t)>(
0902 declval<detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>>(),
0903 token, static_cast<DynamicBuffer_v2&&>(buffers),
0904 transfer_all()))
0905 {
0906 return async_initiate<WriteToken,
0907 void (boost::system::error_code, std::size_t)>(
0908 detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>(s),
0909 token, static_cast<DynamicBuffer_v2&&>(buffers),
0910 transfer_all());
0911 }
0912
0913 template <typename AsyncWriteStream,
0914 typename DynamicBuffer_v2, typename CompletionCondition,
0915 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0916 std::size_t)) WriteToken>
0917 inline auto async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
0918 CompletionCondition completion_condition, WriteToken&& token,
0919 constraint_t<
0920 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
0921 >)
0922 -> decltype(
0923 async_initiate<WriteToken,
0924 void (boost::system::error_code, std::size_t)>(
0925 declval<detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>>(),
0926 token, static_cast<DynamicBuffer_v2&&>(buffers),
0927 static_cast<CompletionCondition&&>(completion_condition)))
0928 {
0929 return async_initiate<WriteToken,
0930 void (boost::system::error_code, std::size_t)>(
0931 detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>(s),
0932 token, static_cast<DynamicBuffer_v2&&>(buffers),
0933 static_cast<CompletionCondition&&>(completion_condition));
0934 }
0935
0936 }
0937 }
0938
0939 #include <boost/asio/detail/pop_options.hpp>
0940
0941 #endif