5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_IMPL_WRITE_HPP
12 #define BOOST_ASIO_IMPL_WRITE_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/associated_allocator.hpp>
19 #include <boost/asio/associated_executor.hpp>
20 #include <boost/asio/buffer.hpp>
21 #include <boost/asio/completion_condition.hpp>
22 #include <boost/asio/detail/array_fwd.hpp>
23 #include <boost/asio/detail/base_from_completion_cond.hpp>
24 #include <boost/asio/detail/bind_handler.hpp>
25 #include <boost/asio/detail/consuming_buffers.hpp>
26 #include <boost/asio/detail/dependent_type.hpp>
27 #include <boost/asio/detail/handler_alloc_helpers.hpp>
28 #include <boost/asio/detail/handler_cont_helpers.hpp>
29 #include <boost/asio/detail/handler_invoke_helpers.hpp>
30 #include <boost/asio/detail/handler_type_requirements.hpp>
31 #include <boost/asio/detail/non_const_lvalue.hpp>
32 #include <boost/asio/detail/throw_error.hpp>
34 #include <boost/asio/detail/push_options.hpp>
41 template <typename SyncWriteStream, typename ConstBufferSequence,
42 typename ConstBufferIterator, typename CompletionCondition>
43 std::size_t write_buffer_sequence(SyncWriteStream& s,
44 const ConstBufferSequence& buffers, const ConstBufferIterator&,
45 CompletionCondition completion_condition, boost::system::error_code& ec)
47 ec = boost::system::error_code();
48 boost::asio::detail::consuming_buffers<const_buffer,
49 ConstBufferSequence, ConstBufferIterator> tmp(buffers);
52 if (std::size_t max_size = detail::adapt_completion_condition_result(
53 completion_condition(ec, tmp.total_consumed())))
54 tmp.consume(s.write_some(tmp.prepare(max_size), ec));
58 return tmp.total_consumed();;
62 template <typename SyncWriteStream, typename ConstBufferSequence,
63 typename CompletionCondition>
64 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
65 CompletionCondition completion_condition, boost::system::error_code& ec,
67 is_const_buffer_sequence<ConstBufferSequence>::value
70 return detail::write_buffer_sequence(s, buffers,
71 boost::asio::buffer_sequence_begin(buffers),
72 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
75 template <typename SyncWriteStream, typename ConstBufferSequence>
76 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
78 is_const_buffer_sequence<ConstBufferSequence>::value
81 boost::system::error_code ec;
82 std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec);
83 boost::asio::detail::throw_error(ec, "write");
84 return bytes_transferred;
87 template <typename SyncWriteStream, typename ConstBufferSequence>
88 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
89 boost::system::error_code& ec,
91 is_const_buffer_sequence<ConstBufferSequence>::value
94 return write(s, buffers, transfer_all(), ec);
97 template <typename SyncWriteStream, typename ConstBufferSequence,
98 typename CompletionCondition>
99 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
100 CompletionCondition completion_condition,
102 is_const_buffer_sequence<ConstBufferSequence>::value
105 boost::system::error_code ec;
106 std::size_t bytes_transferred = write(s, buffers,
107 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
108 boost::asio::detail::throw_error(ec, "write");
109 return bytes_transferred;
112 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
114 template <typename SyncWriteStream, typename DynamicBuffer_v1,
115 typename CompletionCondition>
116 std::size_t write(SyncWriteStream& s,
117 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
118 CompletionCondition completion_condition, boost::system::error_code& ec,
120 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
121 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
124 typename decay<DynamicBuffer_v1>::type b(
125 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));
127 std::size_t bytes_transferred = write(s, b.data(),
128 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
129 b.consume(bytes_transferred);
130 return bytes_transferred;
133 template <typename SyncWriteStream, typename DynamicBuffer_v1>
134 inline std::size_t write(SyncWriteStream& s,
135 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
137 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
138 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
141 boost::system::error_code ec;
142 std::size_t bytes_transferred = write(s,
143 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
145 boost::asio::detail::throw_error(ec, "write");
146 return bytes_transferred;
149 template <typename SyncWriteStream, typename DynamicBuffer_v1>
150 inline std::size_t write(SyncWriteStream& s,
151 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
152 boost::system::error_code& ec,
154 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
155 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
158 return write(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
162 template <typename SyncWriteStream, typename DynamicBuffer_v1,
163 typename CompletionCondition>
164 inline std::size_t write(SyncWriteStream& s,
165 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
166 CompletionCondition completion_condition,
168 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
169 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
172 boost::system::error_code ec;
173 std::size_t bytes_transferred = write(s,
174 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
175 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
176 boost::asio::detail::throw_error(ec, "write");
177 return bytes_transferred;
180 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
181 #if !defined(BOOST_ASIO_NO_IOSTREAM)
183 template <typename SyncWriteStream, typename Allocator,
184 typename CompletionCondition>
185 inline std::size_t write(SyncWriteStream& s,
186 boost::asio::basic_streambuf<Allocator>& b,
187 CompletionCondition completion_condition, boost::system::error_code& ec)
189 return write(s, basic_streambuf_ref<Allocator>(b),
190 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
193 template <typename SyncWriteStream, typename Allocator>
194 inline std::size_t write(SyncWriteStream& s,
195 boost::asio::basic_streambuf<Allocator>& b)
197 return write(s, basic_streambuf_ref<Allocator>(b));
200 template <typename SyncWriteStream, typename Allocator>
201 inline std::size_t write(SyncWriteStream& s,
202 boost::asio::basic_streambuf<Allocator>& b,
203 boost::system::error_code& ec)
205 return write(s, basic_streambuf_ref<Allocator>(b), ec);
208 template <typename SyncWriteStream, typename Allocator,
209 typename CompletionCondition>
210 inline std::size_t write(SyncWriteStream& s,
211 boost::asio::basic_streambuf<Allocator>& b,
212 CompletionCondition completion_condition)
214 return write(s, basic_streambuf_ref<Allocator>(b),
215 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
218 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
219 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
220 #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
222 template <typename SyncWriteStream, typename DynamicBuffer_v2,
223 typename CompletionCondition>
224 std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
225 CompletionCondition completion_condition, boost::system::error_code& ec,
227 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
230 std::size_t bytes_transferred = write(s, buffers.data(0, buffers.size()),
231 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
232 buffers.consume(bytes_transferred);
233 return bytes_transferred;
236 template <typename SyncWriteStream, typename DynamicBuffer_v2>
237 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
239 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
242 boost::system::error_code ec;
243 std::size_t bytes_transferred = write(s,
244 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
246 boost::asio::detail::throw_error(ec, "write");
247 return bytes_transferred;
250 template <typename SyncWriteStream, typename DynamicBuffer_v2>
251 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
252 boost::system::error_code& ec,
254 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
257 return write(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
261 template <typename SyncWriteStream, typename DynamicBuffer_v2,
262 typename CompletionCondition>
263 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
264 CompletionCondition completion_condition,
266 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
269 boost::system::error_code ec;
270 std::size_t bytes_transferred = write(s,
271 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
272 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
273 boost::asio::detail::throw_error(ec, "write");
274 return bytes_transferred;
279 template <typename AsyncWriteStream, typename ConstBufferSequence,
280 typename ConstBufferIterator, typename CompletionCondition,
281 typename WriteHandler>
283 : detail::base_from_completion_cond<CompletionCondition>
286 write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers,
287 CompletionCondition& completion_condition, WriteHandler& handler)
288 : detail::base_from_completion_cond<
289 CompletionCondition>(completion_condition),
293 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
297 #if defined(BOOST_ASIO_HAS_MOVE)
298 write_op(const write_op& other)
299 : detail::base_from_completion_cond<CompletionCondition>(other),
300 stream_(other.stream_),
301 buffers_(other.buffers_),
302 start_(other.start_),
303 handler_(other.handler_)
307 write_op(write_op&& other)
308 : detail::base_from_completion_cond<CompletionCondition>(
309 BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
310 CompletionCondition>)(other)),
311 stream_(other.stream_),
312 buffers_(BOOST_ASIO_MOVE_CAST(buffers_type)(other.buffers_)),
313 start_(other.start_),
314 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
317 #endif // defined(BOOST_ASIO_HAS_MOVE)
319 void operator()(const boost::system::error_code& ec,
320 std::size_t bytes_transferred, int start = 0)
322 std::size_t max_size;
323 switch (start_ = start)
326 max_size = this->check_for_completion(ec, buffers_.total_consumed());
329 stream_.async_write_some(buffers_.prepare(max_size),
330 BOOST_ASIO_MOVE_CAST(write_op)(*this));
332 buffers_.consume(bytes_transferred);
333 if ((!ec && bytes_transferred == 0) || buffers_.empty())
335 max_size = this->check_for_completion(ec, buffers_.total_consumed());
336 } while (max_size > 0);
338 handler_(ec, buffers_.total_consumed());
343 typedef boost::asio::detail::consuming_buffers<const_buffer,
344 ConstBufferSequence, ConstBufferIterator> buffers_type;
346 AsyncWriteStream& stream_;
347 buffers_type buffers_;
349 WriteHandler handler_;
352 template <typename AsyncWriteStream, typename ConstBufferSequence,
353 typename ConstBufferIterator, typename CompletionCondition,
354 typename WriteHandler>
355 inline void* asio_handler_allocate(std::size_t size,
356 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
357 CompletionCondition, WriteHandler>* this_handler)
359 return boost_asio_handler_alloc_helpers::allocate(
360 size, this_handler->handler_);
363 template <typename AsyncWriteStream, typename ConstBufferSequence,
364 typename ConstBufferIterator, typename CompletionCondition,
365 typename WriteHandler>
366 inline void asio_handler_deallocate(void* pointer, std::size_t size,
367 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
368 CompletionCondition, WriteHandler>* this_handler)
370 boost_asio_handler_alloc_helpers::deallocate(
371 pointer, size, this_handler->handler_);
374 template <typename AsyncWriteStream, typename ConstBufferSequence,
375 typename ConstBufferIterator, typename CompletionCondition,
376 typename WriteHandler>
377 inline bool asio_handler_is_continuation(
378 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
379 CompletionCondition, WriteHandler>* this_handler)
381 return this_handler->start_ == 0 ? true
382 : boost_asio_handler_cont_helpers::is_continuation(
383 this_handler->handler_);
386 template <typename Function, typename AsyncWriteStream,
387 typename ConstBufferSequence, typename ConstBufferIterator,
388 typename CompletionCondition, typename WriteHandler>
389 inline void asio_handler_invoke(Function& function,
390 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
391 CompletionCondition, WriteHandler>* this_handler)
393 boost_asio_handler_invoke_helpers::invoke(
394 function, this_handler->handler_);
397 template <typename Function, typename AsyncWriteStream,
398 typename ConstBufferSequence, typename ConstBufferIterator,
399 typename CompletionCondition, typename WriteHandler>
400 inline void asio_handler_invoke(const Function& function,
401 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
402 CompletionCondition, WriteHandler>* this_handler)
404 boost_asio_handler_invoke_helpers::invoke(
405 function, this_handler->handler_);
408 template <typename AsyncWriteStream, typename ConstBufferSequence,
409 typename ConstBufferIterator, typename CompletionCondition,
410 typename WriteHandler>
411 inline void start_write_buffer_sequence_op(AsyncWriteStream& stream,
412 const ConstBufferSequence& buffers, const ConstBufferIterator&,
413 CompletionCondition& completion_condition, WriteHandler& handler)
415 detail::write_op<AsyncWriteStream, ConstBufferSequence,
416 ConstBufferIterator, CompletionCondition, WriteHandler>(
417 stream, buffers, completion_condition, handler)(
418 boost::system::error_code(), 0, 1);
421 template <typename AsyncWriteStream>
422 class initiate_async_write_buffer_sequence
425 typedef typename AsyncWriteStream::executor_type executor_type;
427 explicit initiate_async_write_buffer_sequence(AsyncWriteStream& stream)
432 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
434 return stream_.get_executor();
437 template <typename WriteHandler, typename ConstBufferSequence,
438 typename CompletionCondition>
439 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
440 const ConstBufferSequence& buffers,
441 BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
443 // If you get an error on the following line it means that your handler
444 // does not meet the documented type requirements for a WriteHandler.
445 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
447 non_const_lvalue<WriteHandler> handler2(handler);
448 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
449 start_write_buffer_sequence_op(stream_, buffers,
450 boost::asio::buffer_sequence_begin(buffers),
451 completion_cond2.value, handler2.value);
455 AsyncWriteStream& stream_;
457 } // namespace detail
459 #if !defined(GENERATING_DOCUMENTATION)
461 template <typename AsyncWriteStream, typename ConstBufferSequence,
462 typename ConstBufferIterator, typename CompletionCondition,
463 typename WriteHandler, typename Allocator>
464 struct associated_allocator<
465 detail::write_op<AsyncWriteStream, ConstBufferSequence,
466 ConstBufferIterator, CompletionCondition, WriteHandler>,
469 typedef typename associated_allocator<WriteHandler, Allocator>::type type;
472 const detail::write_op<AsyncWriteStream, ConstBufferSequence,
473 ConstBufferIterator, CompletionCondition, WriteHandler>& h,
474 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
476 return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
480 template <typename AsyncWriteStream, typename ConstBufferSequence,
481 typename ConstBufferIterator, typename CompletionCondition,
482 typename WriteHandler, typename Executor>
483 struct associated_executor<
484 detail::write_op<AsyncWriteStream, ConstBufferSequence,
485 ConstBufferIterator, CompletionCondition, WriteHandler>,
488 typedef typename associated_executor<WriteHandler, Executor>::type type;
491 const detail::write_op<AsyncWriteStream, ConstBufferSequence,
492 ConstBufferIterator, CompletionCondition, WriteHandler>& h,
493 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
495 return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
499 #endif // !defined(GENERATING_DOCUMENTATION)
501 template <typename AsyncWriteStream,
502 typename ConstBufferSequence, typename CompletionCondition,
503 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
504 std::size_t)) WriteHandler>
505 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
506 void (boost::system::error_code, std::size_t))
507 async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
508 CompletionCondition completion_condition,
509 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
511 is_const_buffer_sequence<ConstBufferSequence>::value
514 return async_initiate<WriteHandler,
515 void (boost::system::error_code, std::size_t)>(
516 detail::initiate_async_write_buffer_sequence<AsyncWriteStream>(s),
518 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
521 template <typename AsyncWriteStream, typename ConstBufferSequence,
522 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
523 std::size_t)) WriteHandler>
524 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
525 void (boost::system::error_code, std::size_t))
526 async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
527 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
529 is_const_buffer_sequence<ConstBufferSequence>::value
532 return async_initiate<WriteHandler,
533 void (boost::system::error_code, std::size_t)>(
534 detail::initiate_async_write_buffer_sequence<AsyncWriteStream>(s),
535 handler, buffers, transfer_all());
538 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
542 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
543 typename CompletionCondition, typename WriteHandler>
544 class write_dynbuf_v1_op
547 template <typename BufferSequence>
548 write_dynbuf_v1_op(AsyncWriteStream& stream,
549 BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
550 CompletionCondition& completion_condition, WriteHandler& handler)
552 buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
553 completion_condition_(
554 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)),
555 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
559 #if defined(BOOST_ASIO_HAS_MOVE)
560 write_dynbuf_v1_op(const write_dynbuf_v1_op& other)
561 : stream_(other.stream_),
562 buffers_(other.buffers_),
563 completion_condition_(other.completion_condition_),
564 handler_(other.handler_)
568 write_dynbuf_v1_op(write_dynbuf_v1_op&& other)
569 : stream_(other.stream_),
570 buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),
571 completion_condition_(
572 BOOST_ASIO_MOVE_CAST(CompletionCondition)(
573 other.completion_condition_)),
574 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
577 #endif // defined(BOOST_ASIO_HAS_MOVE)
579 void operator()(const boost::system::error_code& ec,
580 std::size_t bytes_transferred, int start = 0)
585 async_write(stream_, buffers_.data(),
586 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),
587 BOOST_ASIO_MOVE_CAST(write_dynbuf_v1_op)(*this));
589 buffers_.consume(bytes_transferred);
590 handler_(ec, static_cast<const std::size_t&>(bytes_transferred));
595 AsyncWriteStream& stream_;
596 DynamicBuffer_v1 buffers_;
597 CompletionCondition completion_condition_;
598 WriteHandler handler_;
601 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
602 typename CompletionCondition, typename WriteHandler>
603 inline void* asio_handler_allocate(std::size_t size,
604 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
605 CompletionCondition, WriteHandler>* this_handler)
607 return boost_asio_handler_alloc_helpers::allocate(
608 size, this_handler->handler_);
611 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
612 typename CompletionCondition, typename WriteHandler>
613 inline void asio_handler_deallocate(void* pointer, std::size_t size,
614 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
615 CompletionCondition, WriteHandler>* this_handler)
617 boost_asio_handler_alloc_helpers::deallocate(
618 pointer, size, this_handler->handler_);
621 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
622 typename CompletionCondition, typename WriteHandler>
623 inline bool asio_handler_is_continuation(
624 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
625 CompletionCondition, WriteHandler>* this_handler)
627 return boost_asio_handler_cont_helpers::is_continuation(
628 this_handler->handler_);
631 template <typename Function, typename AsyncWriteStream,
632 typename DynamicBuffer_v1, typename CompletionCondition,
633 typename WriteHandler>
634 inline void asio_handler_invoke(Function& function,
635 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
636 CompletionCondition, WriteHandler>* this_handler)
638 boost_asio_handler_invoke_helpers::invoke(
639 function, this_handler->handler_);
642 template <typename Function, typename AsyncWriteStream,
643 typename DynamicBuffer_v1, typename CompletionCondition,
644 typename WriteHandler>
645 inline void asio_handler_invoke(const Function& function,
646 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
647 CompletionCondition, WriteHandler>* this_handler)
649 boost_asio_handler_invoke_helpers::invoke(
650 function, this_handler->handler_);
653 template <typename AsyncWriteStream>
654 class initiate_async_write_dynbuf_v1
657 typedef typename AsyncWriteStream::executor_type executor_type;
659 explicit initiate_async_write_dynbuf_v1(AsyncWriteStream& stream)
664 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
666 return stream_.get_executor();
669 template <typename WriteHandler, typename DynamicBuffer_v1,
670 typename CompletionCondition>
671 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
672 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
673 BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
675 // If you get an error on the following line it means that your handler
676 // does not meet the documented type requirements for a WriteHandler.
677 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
679 non_const_lvalue<WriteHandler> handler2(handler);
680 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
681 write_dynbuf_v1_op<AsyncWriteStream,
682 typename decay<DynamicBuffer_v1>::type,
683 CompletionCondition, typename decay<WriteHandler>::type>(
684 stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
685 completion_cond2.value, handler2.value)(
686 boost::system::error_code(), 0, 1);
690 AsyncWriteStream& stream_;
692 } // namespace detail
694 #if !defined(GENERATING_DOCUMENTATION)
696 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
697 typename CompletionCondition, typename WriteHandler, typename Allocator>
698 struct associated_allocator<
699 detail::write_dynbuf_v1_op<AsyncWriteStream,
700 DynamicBuffer_v1, CompletionCondition, WriteHandler>,
703 typedef typename associated_allocator<WriteHandler, Allocator>::type type;
706 const detail::write_dynbuf_v1_op<AsyncWriteStream,
707 DynamicBuffer_v1, CompletionCondition, WriteHandler>& h,
708 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
710 return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
714 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
715 typename CompletionCondition, typename WriteHandler, typename Executor>
716 struct associated_executor<
717 detail::write_dynbuf_v1_op<AsyncWriteStream,
718 DynamicBuffer_v1, CompletionCondition, WriteHandler>,
721 typedef typename associated_executor<WriteHandler, Executor>::type type;
724 const detail::write_dynbuf_v1_op<AsyncWriteStream,
725 DynamicBuffer_v1, CompletionCondition, WriteHandler>& h,
726 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
728 return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
732 #endif // !defined(GENERATING_DOCUMENTATION)
734 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
735 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
736 std::size_t)) WriteHandler>
737 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
738 void (boost::system::error_code, std::size_t))
739 async_write(AsyncWriteStream& s,
740 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
741 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
743 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
744 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
747 return async_write(s,
748 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
749 transfer_all(), BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
752 template <typename AsyncWriteStream,
753 typename DynamicBuffer_v1, typename CompletionCondition,
754 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
755 std::size_t)) WriteHandler>
756 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
757 void (boost::system::error_code, std::size_t))
758 async_write(AsyncWriteStream& s,
759 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
760 CompletionCondition completion_condition,
761 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
763 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
764 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
767 return async_initiate<WriteHandler,
768 void (boost::system::error_code, std::size_t)>(
769 detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),
770 handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
771 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
774 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
775 #if !defined(BOOST_ASIO_NO_IOSTREAM)
777 template <typename AsyncWriteStream, typename Allocator,
778 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
779 std::size_t)) WriteHandler>
780 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
781 void (boost::system::error_code, std::size_t))
782 async_write(AsyncWriteStream& s,
783 boost::asio::basic_streambuf<Allocator>& b,
784 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
786 return async_write(s, basic_streambuf_ref<Allocator>(b),
787 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
790 template <typename AsyncWriteStream,
791 typename Allocator, typename CompletionCondition,
792 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
793 std::size_t)) WriteHandler>
794 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
795 void (boost::system::error_code, std::size_t))
796 async_write(AsyncWriteStream& s,
797 boost::asio::basic_streambuf<Allocator>& b,
798 CompletionCondition completion_condition,
799 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
801 return async_write(s, basic_streambuf_ref<Allocator>(b),
802 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition),
803 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
806 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
807 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
808 #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
812 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
813 typename CompletionCondition, typename WriteHandler>
814 class write_dynbuf_v2_op
817 template <typename BufferSequence>
818 write_dynbuf_v2_op(AsyncWriteStream& stream,
819 BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
820 CompletionCondition& completion_condition, WriteHandler& handler)
822 buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
823 completion_condition_(
824 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)),
825 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
829 #if defined(BOOST_ASIO_HAS_MOVE)
830 write_dynbuf_v2_op(const write_dynbuf_v2_op& other)
831 : stream_(other.stream_),
832 buffers_(other.buffers_),
833 completion_condition_(other.completion_condition_),
834 handler_(other.handler_)
838 write_dynbuf_v2_op(write_dynbuf_v2_op&& other)
839 : stream_(other.stream_),
840 buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),
841 completion_condition_(
842 BOOST_ASIO_MOVE_CAST(CompletionCondition)(
843 other.completion_condition_)),
844 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
847 #endif // defined(BOOST_ASIO_HAS_MOVE)
849 void operator()(const boost::system::error_code& ec,
850 std::size_t bytes_transferred, int start = 0)
855 async_write(stream_, buffers_.data(0, buffers_.size()),
856 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),
857 BOOST_ASIO_MOVE_CAST(write_dynbuf_v2_op)(*this));
859 buffers_.consume(bytes_transferred);
860 handler_(ec, static_cast<const std::size_t&>(bytes_transferred));
865 AsyncWriteStream& stream_;
866 DynamicBuffer_v2 buffers_;
867 CompletionCondition completion_condition_;
868 WriteHandler handler_;
871 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
872 typename CompletionCondition, typename WriteHandler>
873 inline void* asio_handler_allocate(std::size_t size,
874 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
875 CompletionCondition, WriteHandler>* this_handler)
877 return boost_asio_handler_alloc_helpers::allocate(
878 size, this_handler->handler_);
881 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
882 typename CompletionCondition, typename WriteHandler>
883 inline void asio_handler_deallocate(void* pointer, std::size_t size,
884 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
885 CompletionCondition, WriteHandler>* this_handler)
887 boost_asio_handler_alloc_helpers::deallocate(
888 pointer, size, this_handler->handler_);
891 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
892 typename CompletionCondition, typename WriteHandler>
893 inline bool asio_handler_is_continuation(
894 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
895 CompletionCondition, WriteHandler>* this_handler)
897 return boost_asio_handler_cont_helpers::is_continuation(
898 this_handler->handler_);
901 template <typename Function, typename AsyncWriteStream,
902 typename DynamicBuffer_v2, typename CompletionCondition,
903 typename WriteHandler>
904 inline void asio_handler_invoke(Function& function,
905 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
906 CompletionCondition, WriteHandler>* this_handler)
908 boost_asio_handler_invoke_helpers::invoke(
909 function, this_handler->handler_);
912 template <typename Function, typename AsyncWriteStream,
913 typename DynamicBuffer_v2, typename CompletionCondition,
914 typename WriteHandler>
915 inline void asio_handler_invoke(const Function& function,
916 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
917 CompletionCondition, WriteHandler>* this_handler)
919 boost_asio_handler_invoke_helpers::invoke(
920 function, this_handler->handler_);
923 template <typename AsyncWriteStream>
924 class initiate_async_write_dynbuf_v2
927 typedef typename AsyncWriteStream::executor_type executor_type;
929 explicit initiate_async_write_dynbuf_v2(AsyncWriteStream& stream)
934 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
936 return stream_.get_executor();
939 template <typename WriteHandler, typename DynamicBuffer_v2,
940 typename CompletionCondition>
941 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
942 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
943 BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
945 // If you get an error on the following line it means that your handler
946 // does not meet the documented type requirements for a WriteHandler.
947 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
949 non_const_lvalue<WriteHandler> handler2(handler);
950 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
951 write_dynbuf_v2_op<AsyncWriteStream,
952 typename decay<DynamicBuffer_v2>::type,
953 CompletionCondition, typename decay<WriteHandler>::type>(
954 stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
955 completion_cond2.value, handler2.value)(
956 boost::system::error_code(), 0, 1);
960 AsyncWriteStream& stream_;
962 } // namespace detail
964 #if !defined(GENERATING_DOCUMENTATION)
966 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
967 typename CompletionCondition, typename WriteHandler, typename Allocator>
968 struct associated_allocator<
969 detail::write_dynbuf_v2_op<AsyncWriteStream,
970 DynamicBuffer_v2, CompletionCondition, WriteHandler>,
973 typedef typename associated_allocator<WriteHandler, Allocator>::type type;
976 const detail::write_dynbuf_v2_op<AsyncWriteStream,
977 DynamicBuffer_v2, CompletionCondition, WriteHandler>& h,
978 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
980 return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
984 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
985 typename CompletionCondition, typename WriteHandler, typename Executor>
986 struct associated_executor<
987 detail::write_dynbuf_v2_op<AsyncWriteStream,
988 DynamicBuffer_v2, CompletionCondition, WriteHandler>,
991 typedef typename associated_executor<WriteHandler, Executor>::type type;
994 const detail::write_dynbuf_v2_op<AsyncWriteStream,
995 DynamicBuffer_v2, CompletionCondition, WriteHandler>& h,
996 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
998 return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
1002 #endif // !defined(GENERATING_DOCUMENTATION)
1004 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
1005 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1006 std::size_t)) WriteHandler>
1007 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
1008 void (boost::system::error_code, std::size_t))
1009 async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
1010 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
1012 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1015 return async_write(s,
1016 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
1017 transfer_all(), BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
1020 template <typename AsyncWriteStream,
1021 typename DynamicBuffer_v2, typename CompletionCondition,
1022 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1023 std::size_t)) WriteHandler>
1024 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
1025 void (boost::system::error_code, std::size_t))
1026 async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
1027 CompletionCondition completion_condition,
1028 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
1030 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1033 return async_initiate<WriteHandler,
1034 void (boost::system::error_code, std::size_t)>(
1035 detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>(s),
1036 handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
1037 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
1041 } // namespace boost
1043 #include <boost/asio/detail/pop_options.hpp>
1045 #endif // BOOST_ASIO_IMPL_WRITE_HPP