File indexing completed on 2025-07-02 08:06:45
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 constraint_t<
0068 is_completion_condition<CompletionCondition>::value
0069 >)
0070 {
0071 return detail::write(s, buffers,
0072 boost::asio::buffer_sequence_begin(buffers),
0073 static_cast<CompletionCondition&&>(completion_condition), ec);
0074 }
0075
0076 template <typename SyncWriteStream, typename ConstBufferSequence>
0077 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
0078 constraint_t<
0079 is_const_buffer_sequence<ConstBufferSequence>::value
0080 >)
0081 {
0082 boost::system::error_code ec;
0083 std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec);
0084 boost::asio::detail::throw_error(ec, "write");
0085 return bytes_transferred;
0086 }
0087
0088 template <typename SyncWriteStream, typename ConstBufferSequence>
0089 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
0090 boost::system::error_code& ec,
0091 constraint_t<
0092 is_const_buffer_sequence<ConstBufferSequence>::value
0093 >)
0094 {
0095 return write(s, buffers, transfer_all(), ec);
0096 }
0097
0098 template <typename SyncWriteStream, typename ConstBufferSequence,
0099 typename CompletionCondition>
0100 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
0101 CompletionCondition completion_condition,
0102 constraint_t<
0103 is_const_buffer_sequence<ConstBufferSequence>::value
0104 >,
0105 constraint_t<
0106 is_completion_condition<CompletionCondition>::value
0107 >)
0108 {
0109 boost::system::error_code ec;
0110 std::size_t bytes_transferred = write(s, buffers,
0111 static_cast<CompletionCondition&&>(completion_condition), ec);
0112 boost::asio::detail::throw_error(ec, "write");
0113 return bytes_transferred;
0114 }
0115
0116 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
0117
0118 template <typename SyncWriteStream, typename DynamicBuffer_v1,
0119 typename CompletionCondition>
0120 std::size_t write(SyncWriteStream& s,
0121 DynamicBuffer_v1&& buffers,
0122 CompletionCondition completion_condition, boost::system::error_code& ec,
0123 constraint_t<
0124 is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0125 >,
0126 constraint_t<
0127 !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0128 >,
0129 constraint_t<
0130 is_completion_condition<CompletionCondition>::value
0131 >)
0132 {
0133 decay_t<DynamicBuffer_v1> b(
0134 static_cast<DynamicBuffer_v1&&>(buffers));
0135
0136 std::size_t bytes_transferred = write(s, b.data(),
0137 static_cast<CompletionCondition&&>(completion_condition), ec);
0138 b.consume(bytes_transferred);
0139 return bytes_transferred;
0140 }
0141
0142 template <typename SyncWriteStream, typename DynamicBuffer_v1>
0143 inline std::size_t write(SyncWriteStream& s,
0144 DynamicBuffer_v1&& buffers,
0145 constraint_t<
0146 is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0147 >,
0148 constraint_t<
0149 !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0150 >)
0151 {
0152 boost::system::error_code ec;
0153 std::size_t bytes_transferred = write(s,
0154 static_cast<DynamicBuffer_v1&&>(buffers),
0155 transfer_all(), ec);
0156 boost::asio::detail::throw_error(ec, "write");
0157 return bytes_transferred;
0158 }
0159
0160 template <typename SyncWriteStream, typename DynamicBuffer_v1>
0161 inline std::size_t write(SyncWriteStream& s,
0162 DynamicBuffer_v1&& buffers,
0163 boost::system::error_code& ec,
0164 constraint_t<
0165 is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0166 >,
0167 constraint_t<
0168 !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0169 >)
0170 {
0171 return write(s, static_cast<DynamicBuffer_v1&&>(buffers),
0172 transfer_all(), ec);
0173 }
0174
0175 template <typename SyncWriteStream, typename DynamicBuffer_v1,
0176 typename CompletionCondition>
0177 inline std::size_t write(SyncWriteStream& s,
0178 DynamicBuffer_v1&& buffers,
0179 CompletionCondition completion_condition,
0180 constraint_t<
0181 is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value
0182 >,
0183 constraint_t<
0184 !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value
0185 >,
0186 constraint_t<
0187 is_completion_condition<CompletionCondition>::value
0188 >)
0189 {
0190 boost::system::error_code ec;
0191 std::size_t bytes_transferred = write(s,
0192 static_cast<DynamicBuffer_v1&&>(buffers),
0193 static_cast<CompletionCondition&&>(completion_condition), ec);
0194 boost::asio::detail::throw_error(ec, "write");
0195 return bytes_transferred;
0196 }
0197
0198 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
0199 #if !defined(BOOST_ASIO_NO_IOSTREAM)
0200
0201 template <typename SyncWriteStream, typename Allocator,
0202 typename CompletionCondition>
0203 inline std::size_t write(SyncWriteStream& s,
0204 boost::asio::basic_streambuf<Allocator>& b,
0205 CompletionCondition completion_condition, boost::system::error_code& ec,
0206 constraint_t<
0207 is_completion_condition<CompletionCondition>::value
0208 >)
0209 {
0210 return write(s, basic_streambuf_ref<Allocator>(b),
0211 static_cast<CompletionCondition&&>(completion_condition), ec);
0212 }
0213
0214 template <typename SyncWriteStream, typename Allocator>
0215 inline std::size_t write(SyncWriteStream& s,
0216 boost::asio::basic_streambuf<Allocator>& b)
0217 {
0218 return write(s, basic_streambuf_ref<Allocator>(b));
0219 }
0220
0221 template <typename SyncWriteStream, typename Allocator>
0222 inline std::size_t write(SyncWriteStream& s,
0223 boost::asio::basic_streambuf<Allocator>& b,
0224 boost::system::error_code& ec)
0225 {
0226 return write(s, basic_streambuf_ref<Allocator>(b), ec);
0227 }
0228
0229 template <typename SyncWriteStream, typename Allocator,
0230 typename CompletionCondition>
0231 inline std::size_t write(SyncWriteStream& s,
0232 boost::asio::basic_streambuf<Allocator>& b,
0233 CompletionCondition completion_condition,
0234 constraint_t<
0235 is_completion_condition<CompletionCondition>::value
0236 >)
0237 {
0238 return write(s, basic_streambuf_ref<Allocator>(b),
0239 static_cast<CompletionCondition&&>(completion_condition));
0240 }
0241
0242 #endif
0243 #endif
0244 #endif
0245
0246 template <typename SyncWriteStream, typename DynamicBuffer_v2,
0247 typename CompletionCondition>
0248 std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
0249 CompletionCondition completion_condition, boost::system::error_code& ec,
0250 constraint_t<
0251 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
0252 >,
0253 constraint_t<
0254 is_completion_condition<CompletionCondition>::value
0255 >)
0256 {
0257 std::size_t bytes_transferred = write(s, buffers.data(0, buffers.size()),
0258 static_cast<CompletionCondition&&>(completion_condition), ec);
0259 buffers.consume(bytes_transferred);
0260 return bytes_transferred;
0261 }
0262
0263 template <typename SyncWriteStream, typename DynamicBuffer_v2>
0264 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
0265 constraint_t<
0266 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
0267 >)
0268 {
0269 boost::system::error_code ec;
0270 std::size_t bytes_transferred = write(s,
0271 static_cast<DynamicBuffer_v2&&>(buffers),
0272 transfer_all(), ec);
0273 boost::asio::detail::throw_error(ec, "write");
0274 return bytes_transferred;
0275 }
0276
0277 template <typename SyncWriteStream, typename DynamicBuffer_v2>
0278 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
0279 boost::system::error_code& ec,
0280 constraint_t<
0281 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
0282 >)
0283 {
0284 return write(s, static_cast<DynamicBuffer_v2&&>(buffers),
0285 transfer_all(), ec);
0286 }
0287
0288 template <typename SyncWriteStream, typename DynamicBuffer_v2,
0289 typename CompletionCondition>
0290 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
0291 CompletionCondition completion_condition,
0292 constraint_t<
0293 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
0294 >,
0295 constraint_t<
0296 is_completion_condition<CompletionCondition>::value
0297 >)
0298 {
0299 boost::system::error_code ec;
0300 std::size_t bytes_transferred = write(s,
0301 static_cast<DynamicBuffer_v2&&>(buffers),
0302 static_cast<CompletionCondition&&>(completion_condition), ec);
0303 boost::asio::detail::throw_error(ec, "write");
0304 return bytes_transferred;
0305 }
0306
0307 namespace detail
0308 {
0309 template <typename AsyncWriteStream, typename ConstBufferSequence,
0310 typename ConstBufferIterator, typename CompletionCondition,
0311 typename WriteHandler>
0312 class write_op
0313 : public base_from_cancellation_state<WriteHandler>,
0314 base_from_completion_cond<CompletionCondition>
0315 {
0316 public:
0317 write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers,
0318 CompletionCondition& completion_condition, WriteHandler& handler)
0319 : base_from_cancellation_state<WriteHandler>(
0320 handler, enable_partial_cancellation()),
0321 base_from_completion_cond<CompletionCondition>(completion_condition),
0322 stream_(stream),
0323 buffers_(buffers),
0324 start_(0),
0325 handler_(static_cast<WriteHandler&&>(handler))
0326 {
0327 }
0328
0329 write_op(const write_op& other)
0330 : base_from_cancellation_state<WriteHandler>(other),
0331 base_from_completion_cond<CompletionCondition>(other),
0332 stream_(other.stream_),
0333 buffers_(other.buffers_),
0334 start_(other.start_),
0335 handler_(other.handler_)
0336 {
0337 }
0338
0339 write_op(write_op&& other)
0340 : base_from_cancellation_state<WriteHandler>(
0341 static_cast<base_from_cancellation_state<WriteHandler>&&>(other)),
0342 base_from_completion_cond<CompletionCondition>(
0343 static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),
0344 stream_(other.stream_),
0345 buffers_(static_cast<buffers_type&&>(other.buffers_)),
0346 start_(other.start_),
0347 handler_(static_cast<WriteHandler&&>(other.handler_))
0348 {
0349 }
0350
0351 void operator()(boost::system::error_code ec,
0352 std::size_t bytes_transferred, int start = 0)
0353 {
0354 std::size_t max_size;
0355 switch (start_ = start)
0356 {
0357 case 1:
0358 max_size = this->check_for_completion(ec, buffers_.total_consumed());
0359 for (;;)
0360 {
0361 {
0362 BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_write"));
0363 stream_.async_write_some(buffers_.prepare(max_size),
0364 static_cast<write_op&&>(*this));
0365 }
0366 return; default:
0367 buffers_.consume(bytes_transferred);
0368 if ((!ec && bytes_transferred == 0) || buffers_.empty())
0369 break;
0370 max_size = this->check_for_completion(ec, buffers_.total_consumed());
0371 if (max_size == 0)
0372 break;
0373 if (this->cancelled() != cancellation_type::none)
0374 {
0375 ec = error::operation_aborted;
0376 break;
0377 }
0378 }
0379
0380 static_cast<WriteHandler&&>(handler_)(
0381 static_cast<const boost::system::error_code&>(ec),
0382 static_cast<const std::size_t&>(buffers_.total_consumed()));
0383 }
0384 }
0385
0386
0387 typedef boost::asio::detail::consuming_buffers<const_buffer,
0388 ConstBufferSequence, ConstBufferIterator> buffers_type;
0389
0390 AsyncWriteStream& stream_;
0391 buffers_type buffers_;
0392 int start_;
0393 WriteHandler handler_;
0394 };
0395
0396 template <typename AsyncWriteStream, typename ConstBufferSequence,
0397 typename ConstBufferIterator, typename CompletionCondition,
0398 typename WriteHandler>
0399 inline bool asio_handler_is_continuation(
0400 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
0401 CompletionCondition, WriteHandler>* this_handler)
0402 {
0403 return this_handler->start_ == 0 ? true
0404 : boost_asio_handler_cont_helpers::is_continuation(
0405 this_handler->handler_);
0406 }
0407
0408 template <typename AsyncWriteStream, typename ConstBufferSequence,
0409 typename ConstBufferIterator, typename CompletionCondition,
0410 typename WriteHandler>
0411 inline void start_write_op(AsyncWriteStream& stream,
0412 const ConstBufferSequence& buffers, const ConstBufferIterator&,
0413 CompletionCondition& completion_condition, WriteHandler& handler)
0414 {
0415 detail::write_op<AsyncWriteStream, ConstBufferSequence,
0416 ConstBufferIterator, CompletionCondition, WriteHandler>(
0417 stream, buffers, completion_condition, handler)(
0418 boost::system::error_code(), 0, 1);
0419 }
0420
0421 template <typename AsyncWriteStream>
0422 class initiate_async_write
0423 {
0424 public:
0425 typedef typename AsyncWriteStream::executor_type executor_type;
0426
0427 explicit initiate_async_write(AsyncWriteStream& stream)
0428 : stream_(stream)
0429 {
0430 }
0431
0432 executor_type get_executor() const noexcept
0433 {
0434 return stream_.get_executor();
0435 }
0436
0437 template <typename WriteHandler, typename ConstBufferSequence,
0438 typename CompletionCondition>
0439 void operator()(WriteHandler&& handler,
0440 const ConstBufferSequence& buffers,
0441 CompletionCondition&& completion_cond) const
0442 {
0443
0444
0445 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
0446
0447 non_const_lvalue<WriteHandler> handler2(handler);
0448 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
0449 start_write_op(stream_, buffers,
0450 boost::asio::buffer_sequence_begin(buffers),
0451 completion_cond2.value, handler2.value);
0452 }
0453
0454 private:
0455 AsyncWriteStream& stream_;
0456 };
0457 }
0458
0459 #if !defined(GENERATING_DOCUMENTATION)
0460
0461 template <template <typename, typename> class Associator,
0462 typename AsyncWriteStream, typename ConstBufferSequence,
0463 typename ConstBufferIterator, typename CompletionCondition,
0464 typename WriteHandler, typename DefaultCandidate>
0465 struct associator<Associator,
0466 detail::write_op<AsyncWriteStream, ConstBufferSequence,
0467 ConstBufferIterator, CompletionCondition, WriteHandler>,
0468 DefaultCandidate>
0469 : Associator<WriteHandler, DefaultCandidate>
0470 {
0471 static typename Associator<WriteHandler, DefaultCandidate>::type get(
0472 const detail::write_op<AsyncWriteStream, ConstBufferSequence,
0473 ConstBufferIterator, CompletionCondition, WriteHandler>& h) noexcept
0474 {
0475 return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);
0476 }
0477
0478 static auto get(
0479 const detail::write_op<AsyncWriteStream, ConstBufferSequence,
0480 ConstBufferIterator, CompletionCondition, WriteHandler>& h,
0481 const DefaultCandidate& c) noexcept
0482 -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))
0483 {
0484 return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);
0485 }
0486 };
0487
0488 #endif
0489
0490 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
0491
0492 namespace detail
0493 {
0494 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
0495 typename CompletionCondition, typename WriteHandler>
0496 class write_dynbuf_v1_op
0497 {
0498 public:
0499 template <typename BufferSequence>
0500 write_dynbuf_v1_op(AsyncWriteStream& stream,
0501 BufferSequence&& buffers,
0502 CompletionCondition& completion_condition, WriteHandler& handler)
0503 : stream_(stream),
0504 buffers_(static_cast<BufferSequence&&>(buffers)),
0505 completion_condition_(
0506 static_cast<CompletionCondition&&>(completion_condition)),
0507 handler_(static_cast<WriteHandler&&>(handler))
0508 {
0509 }
0510
0511 write_dynbuf_v1_op(const write_dynbuf_v1_op& other)
0512 : stream_(other.stream_),
0513 buffers_(other.buffers_),
0514 completion_condition_(other.completion_condition_),
0515 handler_(other.handler_)
0516 {
0517 }
0518
0519 write_dynbuf_v1_op(write_dynbuf_v1_op&& other)
0520 : stream_(other.stream_),
0521 buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)),
0522 completion_condition_(
0523 static_cast<CompletionCondition&&>(
0524 other.completion_condition_)),
0525 handler_(static_cast<WriteHandler&&>(other.handler_))
0526 {
0527 }
0528
0529 void operator()(const boost::system::error_code& ec,
0530 std::size_t bytes_transferred, int start = 0)
0531 {
0532 switch (start)
0533 {
0534 case 1:
0535 async_write(stream_, buffers_.data(),
0536 static_cast<CompletionCondition&&>(completion_condition_),
0537 static_cast<write_dynbuf_v1_op&&>(*this));
0538 return; default:
0539 buffers_.consume(bytes_transferred);
0540 static_cast<WriteHandler&&>(handler_)(ec,
0541 static_cast<const std::size_t&>(bytes_transferred));
0542 }
0543 }
0544
0545
0546 AsyncWriteStream& stream_;
0547 DynamicBuffer_v1 buffers_;
0548 CompletionCondition completion_condition_;
0549 WriteHandler handler_;
0550 };
0551
0552 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
0553 typename CompletionCondition, typename WriteHandler>
0554 inline bool asio_handler_is_continuation(
0555 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
0556 CompletionCondition, WriteHandler>* this_handler)
0557 {
0558 return boost_asio_handler_cont_helpers::is_continuation(
0559 this_handler->handler_);
0560 }
0561
0562 template <typename AsyncWriteStream>
0563 class initiate_async_write_dynbuf_v1
0564 {
0565 public:
0566 typedef typename AsyncWriteStream::executor_type executor_type;
0567
0568 explicit initiate_async_write_dynbuf_v1(AsyncWriteStream& stream)
0569 : stream_(stream)
0570 {
0571 }
0572
0573 executor_type get_executor() const noexcept
0574 {
0575 return stream_.get_executor();
0576 }
0577
0578 template <typename WriteHandler, typename DynamicBuffer_v1,
0579 typename CompletionCondition>
0580 void operator()(WriteHandler&& handler,
0581 DynamicBuffer_v1&& buffers,
0582 CompletionCondition&& completion_cond) const
0583 {
0584
0585
0586 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
0587
0588 non_const_lvalue<WriteHandler> handler2(handler);
0589 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
0590 write_dynbuf_v1_op<AsyncWriteStream,
0591 decay_t<DynamicBuffer_v1>,
0592 CompletionCondition, decay_t<WriteHandler>>(
0593 stream_, static_cast<DynamicBuffer_v1&&>(buffers),
0594 completion_cond2.value, handler2.value)(
0595 boost::system::error_code(), 0, 1);
0596 }
0597
0598 private:
0599 AsyncWriteStream& stream_;
0600 };
0601 }
0602
0603 #if !defined(GENERATING_DOCUMENTATION)
0604
0605 template <template <typename, typename> class Associator,
0606 typename AsyncWriteStream, typename DynamicBuffer_v1,
0607 typename CompletionCondition, typename WriteHandler,
0608 typename DefaultCandidate>
0609 struct associator<Associator,
0610 detail::write_dynbuf_v1_op<AsyncWriteStream,
0611 DynamicBuffer_v1, CompletionCondition, WriteHandler>,
0612 DefaultCandidate>
0613 : Associator<WriteHandler, DefaultCandidate>
0614 {
0615 static typename Associator<WriteHandler, DefaultCandidate>::type get(
0616 const detail::write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
0617 CompletionCondition, WriteHandler>& h) noexcept
0618 {
0619 return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);
0620 }
0621
0622 static auto get(
0623 const detail::write_dynbuf_v1_op<AsyncWriteStream,
0624 DynamicBuffer_v1, CompletionCondition, WriteHandler>& h,
0625 const DefaultCandidate& c) noexcept
0626 -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))
0627 {
0628 return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);
0629 }
0630 };
0631
0632 #endif
0633
0634 #endif
0635
0636 namespace detail
0637 {
0638 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
0639 typename CompletionCondition, typename WriteHandler>
0640 class write_dynbuf_v2_op
0641 {
0642 public:
0643 template <typename BufferSequence>
0644 write_dynbuf_v2_op(AsyncWriteStream& stream,
0645 BufferSequence&& buffers,
0646 CompletionCondition& completion_condition, WriteHandler& handler)
0647 : stream_(stream),
0648 buffers_(static_cast<BufferSequence&&>(buffers)),
0649 completion_condition_(
0650 static_cast<CompletionCondition&&>(completion_condition)),
0651 handler_(static_cast<WriteHandler&&>(handler))
0652 {
0653 }
0654
0655 write_dynbuf_v2_op(const write_dynbuf_v2_op& other)
0656 : stream_(other.stream_),
0657 buffers_(other.buffers_),
0658 completion_condition_(other.completion_condition_),
0659 handler_(other.handler_)
0660 {
0661 }
0662
0663 write_dynbuf_v2_op(write_dynbuf_v2_op&& other)
0664 : stream_(other.stream_),
0665 buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)),
0666 completion_condition_(
0667 static_cast<CompletionCondition&&>(
0668 other.completion_condition_)),
0669 handler_(static_cast<WriteHandler&&>(other.handler_))
0670 {
0671 }
0672
0673 void operator()(const boost::system::error_code& ec,
0674 std::size_t bytes_transferred, int start = 0)
0675 {
0676 switch (start)
0677 {
0678 case 1:
0679 async_write(stream_, buffers_.data(0, buffers_.size()),
0680 static_cast<CompletionCondition&&>(completion_condition_),
0681 static_cast<write_dynbuf_v2_op&&>(*this));
0682 return; default:
0683 buffers_.consume(bytes_transferred);
0684 static_cast<WriteHandler&&>(handler_)(ec,
0685 static_cast<const std::size_t&>(bytes_transferred));
0686 }
0687 }
0688
0689
0690 AsyncWriteStream& stream_;
0691 DynamicBuffer_v2 buffers_;
0692 CompletionCondition completion_condition_;
0693 WriteHandler handler_;
0694 };
0695
0696 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
0697 typename CompletionCondition, typename WriteHandler>
0698 inline bool asio_handler_is_continuation(
0699 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
0700 CompletionCondition, WriteHandler>* this_handler)
0701 {
0702 return boost_asio_handler_cont_helpers::is_continuation(
0703 this_handler->handler_);
0704 }
0705
0706 template <typename AsyncWriteStream>
0707 class initiate_async_write_dynbuf_v2
0708 {
0709 public:
0710 typedef typename AsyncWriteStream::executor_type executor_type;
0711
0712 explicit initiate_async_write_dynbuf_v2(AsyncWriteStream& stream)
0713 : stream_(stream)
0714 {
0715 }
0716
0717 executor_type get_executor() const noexcept
0718 {
0719 return stream_.get_executor();
0720 }
0721
0722 template <typename WriteHandler, typename DynamicBuffer_v2,
0723 typename CompletionCondition>
0724 void operator()(WriteHandler&& handler,
0725 DynamicBuffer_v2&& buffers,
0726 CompletionCondition&& completion_cond) const
0727 {
0728
0729
0730 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
0731
0732 non_const_lvalue<WriteHandler> handler2(handler);
0733 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
0734 write_dynbuf_v2_op<AsyncWriteStream, decay_t<DynamicBuffer_v2>,
0735 CompletionCondition, decay_t<WriteHandler>>(
0736 stream_, static_cast<DynamicBuffer_v2&&>(buffers),
0737 completion_cond2.value, handler2.value)(
0738 boost::system::error_code(), 0, 1);
0739 }
0740
0741 private:
0742 AsyncWriteStream& stream_;
0743 };
0744 }
0745
0746 #if !defined(GENERATING_DOCUMENTATION)
0747
0748 template <template <typename, typename> class Associator,
0749 typename AsyncWriteStream, typename DynamicBuffer_v2,
0750 typename CompletionCondition, typename WriteHandler,
0751 typename DefaultCandidate>
0752 struct associator<Associator,
0753 detail::write_dynbuf_v2_op<AsyncWriteStream,
0754 DynamicBuffer_v2, CompletionCondition, WriteHandler>,
0755 DefaultCandidate>
0756 : Associator<WriteHandler, DefaultCandidate>
0757 {
0758 static typename Associator<WriteHandler, DefaultCandidate>::type get(
0759 const detail::write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
0760 CompletionCondition, WriteHandler>& h) noexcept
0761 {
0762 return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);
0763 }
0764
0765 static auto get(
0766 const detail::write_dynbuf_v2_op<AsyncWriteStream,
0767 DynamicBuffer_v2, CompletionCondition, WriteHandler>& h,
0768 const DefaultCandidate& c) noexcept
0769 -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))
0770 {
0771 return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);
0772 }
0773 };
0774
0775 #endif
0776
0777 }
0778 }
0779
0780 #include <boost/asio/detail/pop_options.hpp>
0781
0782 #endif