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_READ_HPP
12 #define BOOST_ASIO_IMPL_READ_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
19 #include <boost/asio/associated_allocator.hpp>
20 #include <boost/asio/associated_executor.hpp>
21 #include <boost/asio/buffer.hpp>
22 #include <boost/asio/completion_condition.hpp>
23 #include <boost/asio/detail/array_fwd.hpp>
24 #include <boost/asio/detail/base_from_completion_cond.hpp>
25 #include <boost/asio/detail/bind_handler.hpp>
26 #include <boost/asio/detail/consuming_buffers.hpp>
27 #include <boost/asio/detail/dependent_type.hpp>
28 #include <boost/asio/detail/handler_alloc_helpers.hpp>
29 #include <boost/asio/detail/handler_cont_helpers.hpp>
30 #include <boost/asio/detail/handler_invoke_helpers.hpp>
31 #include <boost/asio/detail/handler_tracking.hpp>
32 #include <boost/asio/detail/handler_type_requirements.hpp>
33 #include <boost/asio/detail/non_const_lvalue.hpp>
34 #include <boost/asio/detail/throw_error.hpp>
35 #include <boost/asio/error.hpp>
37 #include <boost/asio/detail/push_options.hpp>
44 template <typename SyncReadStream, typename MutableBufferSequence,
45 typename MutableBufferIterator, typename CompletionCondition>
46 std::size_t read_buffer_sequence(SyncReadStream& s,
47 const MutableBufferSequence& buffers, const MutableBufferIterator&,
48 CompletionCondition completion_condition, boost::system::error_code& ec)
50 ec = boost::system::error_code();
51 boost::asio::detail::consuming_buffers<mutable_buffer,
52 MutableBufferSequence, MutableBufferIterator> tmp(buffers);
55 if (std::size_t max_size = detail::adapt_completion_condition_result(
56 completion_condition(ec, tmp.total_consumed())))
57 tmp.consume(s.read_some(tmp.prepare(max_size), ec));
61 return tmp.total_consumed();
65 template <typename SyncReadStream, typename MutableBufferSequence,
66 typename CompletionCondition>
67 std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
68 CompletionCondition completion_condition, boost::system::error_code& ec,
70 is_mutable_buffer_sequence<MutableBufferSequence>::value
73 return detail::read_buffer_sequence(s, buffers,
74 boost::asio::buffer_sequence_begin(buffers),
75 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
78 template <typename SyncReadStream, typename MutableBufferSequence>
79 inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
81 is_mutable_buffer_sequence<MutableBufferSequence>::value
84 boost::system::error_code ec;
85 std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec);
86 boost::asio::detail::throw_error(ec, "read");
87 return bytes_transferred;
90 template <typename SyncReadStream, typename MutableBufferSequence>
91 inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
92 boost::system::error_code& ec,
94 is_mutable_buffer_sequence<MutableBufferSequence>::value
97 return read(s, buffers, transfer_all(), ec);
100 template <typename SyncReadStream, typename MutableBufferSequence,
101 typename CompletionCondition>
102 inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
103 CompletionCondition completion_condition,
105 is_mutable_buffer_sequence<MutableBufferSequence>::value
108 boost::system::error_code ec;
109 std::size_t bytes_transferred = read(s, buffers,
110 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
111 boost::asio::detail::throw_error(ec, "read");
112 return bytes_transferred;
115 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
117 template <typename SyncReadStream, typename DynamicBuffer_v1,
118 typename CompletionCondition>
119 std::size_t read(SyncReadStream& s,
120 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
121 CompletionCondition completion_condition, boost::system::error_code& ec,
123 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
124 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
127 typename decay<DynamicBuffer_v1>::type b(
128 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));
130 ec = boost::system::error_code();
131 std::size_t total_transferred = 0;
132 std::size_t max_size = detail::adapt_completion_condition_result(
133 completion_condition(ec, total_transferred));
134 std::size_t bytes_available = std::min<std::size_t>(
135 std::max<std::size_t>(512, b.capacity() - b.size()),
136 std::min<std::size_t>(max_size, b.max_size() - b.size()));
137 while (bytes_available > 0)
139 std::size_t bytes_transferred = s.read_some(b.prepare(bytes_available), ec);
140 b.commit(bytes_transferred);
141 total_transferred += bytes_transferred;
142 max_size = detail::adapt_completion_condition_result(
143 completion_condition(ec, total_transferred));
144 bytes_available = std::min<std::size_t>(
145 std::max<std::size_t>(512, b.capacity() - b.size()),
146 std::min<std::size_t>(max_size, b.max_size() - b.size()));
148 return total_transferred;
151 template <typename SyncReadStream, typename DynamicBuffer_v1>
152 inline std::size_t read(SyncReadStream& s,
153 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
155 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
156 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
159 boost::system::error_code ec;
160 std::size_t bytes_transferred = read(s,
161 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec);
162 boost::asio::detail::throw_error(ec, "read");
163 return bytes_transferred;
166 template <typename SyncReadStream, typename DynamicBuffer_v1>
167 inline std::size_t read(SyncReadStream& s,
168 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
169 boost::system::error_code& ec,
171 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
172 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
175 return read(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
179 template <typename SyncReadStream, typename DynamicBuffer_v1,
180 typename CompletionCondition>
181 inline std::size_t read(SyncReadStream& s,
182 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
183 CompletionCondition completion_condition,
185 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
186 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
189 boost::system::error_code ec;
190 std::size_t bytes_transferred = read(s,
191 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
192 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
193 boost::asio::detail::throw_error(ec, "read");
194 return bytes_transferred;
197 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
198 #if !defined(BOOST_ASIO_NO_IOSTREAM)
200 template <typename SyncReadStream, typename Allocator,
201 typename CompletionCondition>
202 inline std::size_t read(SyncReadStream& s,
203 boost::asio::basic_streambuf<Allocator>& b,
204 CompletionCondition completion_condition, boost::system::error_code& ec)
206 return read(s, basic_streambuf_ref<Allocator>(b),
207 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
210 template <typename SyncReadStream, typename Allocator>
211 inline std::size_t read(SyncReadStream& s,
212 boost::asio::basic_streambuf<Allocator>& b)
214 return read(s, basic_streambuf_ref<Allocator>(b));
217 template <typename SyncReadStream, typename Allocator>
218 inline std::size_t read(SyncReadStream& s,
219 boost::asio::basic_streambuf<Allocator>& b,
220 boost::system::error_code& ec)
222 return read(s, basic_streambuf_ref<Allocator>(b), ec);
225 template <typename SyncReadStream, typename Allocator,
226 typename CompletionCondition>
227 inline std::size_t read(SyncReadStream& s,
228 boost::asio::basic_streambuf<Allocator>& b,
229 CompletionCondition completion_condition)
231 return read(s, basic_streambuf_ref<Allocator>(b),
232 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
235 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
236 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
237 #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
239 template <typename SyncReadStream, typename DynamicBuffer_v2,
240 typename CompletionCondition>
241 std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
242 CompletionCondition completion_condition, boost::system::error_code& ec,
244 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
247 DynamicBuffer_v2& b = buffers;
249 ec = boost::system::error_code();
250 std::size_t total_transferred = 0;
251 std::size_t max_size = detail::adapt_completion_condition_result(
252 completion_condition(ec, total_transferred));
253 std::size_t bytes_available = std::min<std::size_t>(
254 std::max<std::size_t>(512, b.capacity() - b.size()),
255 std::min<std::size_t>(max_size, b.max_size() - b.size()));
256 while (bytes_available > 0)
258 std::size_t pos = b.size();
259 b.grow(bytes_available);
260 std::size_t bytes_transferred = s.read_some(
261 b.data(pos, bytes_available), ec);
262 b.shrink(bytes_available - bytes_transferred);
263 total_transferred += bytes_transferred;
264 max_size = detail::adapt_completion_condition_result(
265 completion_condition(ec, total_transferred));
266 bytes_available = std::min<std::size_t>(
267 std::max<std::size_t>(512, b.capacity() - b.size()),
268 std::min<std::size_t>(max_size, b.max_size() - b.size()));
270 return total_transferred;
273 template <typename SyncReadStream, typename DynamicBuffer_v2>
274 inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
276 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
279 boost::system::error_code ec;
280 std::size_t bytes_transferred = read(s,
281 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec);
282 boost::asio::detail::throw_error(ec, "read");
283 return bytes_transferred;
286 template <typename SyncReadStream, typename DynamicBuffer_v2>
287 inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
288 boost::system::error_code& ec,
290 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
293 return read(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
297 template <typename SyncReadStream, typename DynamicBuffer_v2,
298 typename CompletionCondition>
299 inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
300 CompletionCondition completion_condition,
302 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
305 boost::system::error_code ec;
306 std::size_t bytes_transferred = read(s,
307 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
308 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
309 boost::asio::detail::throw_error(ec, "read");
310 return bytes_transferred;
315 template <typename AsyncReadStream, typename MutableBufferSequence,
316 typename MutableBufferIterator, typename CompletionCondition,
317 typename ReadHandler>
319 : detail::base_from_completion_cond<CompletionCondition>
322 read_op(AsyncReadStream& stream, const MutableBufferSequence& buffers,
323 CompletionCondition& completion_condition, ReadHandler& handler)
324 : detail::base_from_completion_cond<
325 CompletionCondition>(completion_condition),
329 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
333 #if defined(BOOST_ASIO_HAS_MOVE)
334 read_op(const read_op& other)
335 : detail::base_from_completion_cond<CompletionCondition>(other),
336 stream_(other.stream_),
337 buffers_(other.buffers_),
338 start_(other.start_),
339 handler_(other.handler_)
343 read_op(read_op&& other)
344 : detail::base_from_completion_cond<CompletionCondition>(
345 BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
346 CompletionCondition>)(other)),
347 stream_(other.stream_),
348 buffers_(BOOST_ASIO_MOVE_CAST(buffers_type)(other.buffers_)),
349 start_(other.start_),
350 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
353 #endif // defined(BOOST_ASIO_HAS_MOVE)
355 void operator()(const boost::system::error_code& ec,
356 std::size_t bytes_transferred, int start = 0)
358 std::size_t max_size;
359 switch (start_ = start)
362 max_size = this->check_for_completion(ec, buffers_.total_consumed());
366 BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read"));
367 stream_.async_read_some(buffers_.prepare(max_size),
368 BOOST_ASIO_MOVE_CAST(read_op)(*this));
371 buffers_.consume(bytes_transferred);
372 if ((!ec && bytes_transferred == 0) || buffers_.empty())
374 max_size = this->check_for_completion(ec, buffers_.total_consumed());
375 } while (max_size > 0);
377 handler_(ec, buffers_.total_consumed());
382 typedef boost::asio::detail::consuming_buffers<mutable_buffer,
383 MutableBufferSequence, MutableBufferIterator> buffers_type;
385 AsyncReadStream& stream_;
386 buffers_type buffers_;
388 ReadHandler handler_;
391 template <typename AsyncReadStream, typename MutableBufferSequence,
392 typename MutableBufferIterator, typename CompletionCondition,
393 typename ReadHandler>
394 inline asio_handler_allocate_is_deprecated
395 asio_handler_allocate(std::size_t size,
396 read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
397 CompletionCondition, ReadHandler>* this_handler)
399 #if defined(BOOST_ASIO_NO_DEPRECATED)
400 boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
401 return asio_handler_allocate_is_no_longer_used();
402 #else // defined(BOOST_ASIO_NO_DEPRECATED)
403 return boost_asio_handler_alloc_helpers::allocate(
404 size, this_handler->handler_);
405 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
408 template <typename AsyncReadStream, typename MutableBufferSequence,
409 typename MutableBufferIterator, typename CompletionCondition,
410 typename ReadHandler>
411 inline asio_handler_deallocate_is_deprecated
412 asio_handler_deallocate(void* pointer, std::size_t size,
413 read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
414 CompletionCondition, ReadHandler>* this_handler)
416 boost_asio_handler_alloc_helpers::deallocate(
417 pointer, size, this_handler->handler_);
418 #if defined(BOOST_ASIO_NO_DEPRECATED)
419 return asio_handler_deallocate_is_no_longer_used();
420 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
423 template <typename AsyncReadStream, typename MutableBufferSequence,
424 typename MutableBufferIterator, typename CompletionCondition,
425 typename ReadHandler>
426 inline bool asio_handler_is_continuation(
427 read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
428 CompletionCondition, ReadHandler>* this_handler)
430 return this_handler->start_ == 0 ? true
431 : boost_asio_handler_cont_helpers::is_continuation(
432 this_handler->handler_);
435 template <typename Function, typename AsyncReadStream,
436 typename MutableBufferSequence, typename MutableBufferIterator,
437 typename CompletionCondition, typename ReadHandler>
438 inline asio_handler_invoke_is_deprecated
439 asio_handler_invoke(Function& function,
440 read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
441 CompletionCondition, ReadHandler>* this_handler)
443 boost_asio_handler_invoke_helpers::invoke(
444 function, this_handler->handler_);
445 #if defined(BOOST_ASIO_NO_DEPRECATED)
446 return asio_handler_invoke_is_no_longer_used();
447 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
450 template <typename Function, typename AsyncReadStream,
451 typename MutableBufferSequence, typename MutableBufferIterator,
452 typename CompletionCondition, typename ReadHandler>
453 inline asio_handler_invoke_is_deprecated
454 asio_handler_invoke(const Function& function,
455 read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
456 CompletionCondition, ReadHandler>* this_handler)
458 boost_asio_handler_invoke_helpers::invoke(
459 function, this_handler->handler_);
460 #if defined(BOOST_ASIO_NO_DEPRECATED)
461 return asio_handler_invoke_is_no_longer_used();
462 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
465 template <typename AsyncReadStream, typename MutableBufferSequence,
466 typename MutableBufferIterator, typename CompletionCondition,
467 typename ReadHandler>
468 inline void start_read_buffer_sequence_op(AsyncReadStream& stream,
469 const MutableBufferSequence& buffers, const MutableBufferIterator&,
470 CompletionCondition& completion_condition, ReadHandler& handler)
472 detail::read_op<AsyncReadStream, MutableBufferSequence,
473 MutableBufferIterator, CompletionCondition, ReadHandler>(
474 stream, buffers, completion_condition, handler)(
475 boost::system::error_code(), 0, 1);
478 template <typename AsyncReadStream>
479 class initiate_async_read_buffer_sequence
482 typedef typename AsyncReadStream::executor_type executor_type;
484 explicit initiate_async_read_buffer_sequence(AsyncReadStream& stream)
489 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
491 return stream_.get_executor();
494 template <typename ReadHandler, typename MutableBufferSequence,
495 typename CompletionCondition>
496 void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
497 const MutableBufferSequence& buffers,
498 BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
500 // If you get an error on the following line it means that your handler
501 // does not meet the documented type requirements for a ReadHandler.
502 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
504 non_const_lvalue<ReadHandler> handler2(handler);
505 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
506 start_read_buffer_sequence_op(stream_, buffers,
507 boost::asio::buffer_sequence_begin(buffers),
508 completion_cond2.value, handler2.value);
512 AsyncReadStream& stream_;
514 } // namespace detail
516 #if !defined(GENERATING_DOCUMENTATION)
518 template <typename AsyncReadStream, typename MutableBufferSequence,
519 typename MutableBufferIterator, typename CompletionCondition,
520 typename ReadHandler, typename Allocator>
521 struct associated_allocator<
522 detail::read_op<AsyncReadStream, MutableBufferSequence,
523 MutableBufferIterator, CompletionCondition, ReadHandler>,
526 typedef typename associated_allocator<ReadHandler, Allocator>::type type;
529 const detail::read_op<AsyncReadStream, MutableBufferSequence,
530 MutableBufferIterator, CompletionCondition, ReadHandler>& h,
531 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
533 return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
537 template <typename AsyncReadStream, typename MutableBufferSequence,
538 typename MutableBufferIterator, typename CompletionCondition,
539 typename ReadHandler, typename Executor>
540 struct associated_executor<
541 detail::read_op<AsyncReadStream, MutableBufferSequence,
542 MutableBufferIterator, CompletionCondition, ReadHandler>,
544 : detail::associated_executor_forwarding_base<ReadHandler, Executor>
546 typedef typename associated_executor<ReadHandler, Executor>::type type;
549 const detail::read_op<AsyncReadStream, MutableBufferSequence,
550 MutableBufferIterator, CompletionCondition, ReadHandler>& h,
551 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
553 return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
557 #endif // !defined(GENERATING_DOCUMENTATION)
559 template <typename AsyncReadStream,
560 typename MutableBufferSequence, typename CompletionCondition,
561 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
562 std::size_t)) ReadHandler>
563 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
564 void (boost::system::error_code, std::size_t))
565 async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
566 CompletionCondition completion_condition,
567 BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
569 is_mutable_buffer_sequence<MutableBufferSequence>::value
572 return async_initiate<ReadHandler,
573 void (boost::system::error_code, std::size_t)>(
574 detail::initiate_async_read_buffer_sequence<AsyncReadStream>(s), handler,
575 buffers, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
578 template <typename AsyncReadStream, typename MutableBufferSequence,
579 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
580 std::size_t)) ReadHandler>
581 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
582 void (boost::system::error_code, std::size_t))
583 async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
584 BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
586 is_mutable_buffer_sequence<MutableBufferSequence>::value
589 return async_initiate<ReadHandler,
590 void (boost::system::error_code, std::size_t)>(
591 detail::initiate_async_read_buffer_sequence<AsyncReadStream>(s),
592 handler, buffers, transfer_all());
595 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
599 template <typename AsyncReadStream, typename DynamicBuffer_v1,
600 typename CompletionCondition, typename ReadHandler>
601 class read_dynbuf_v1_op
602 : detail::base_from_completion_cond<CompletionCondition>
605 template <typename BufferSequence>
606 read_dynbuf_v1_op(AsyncReadStream& stream,
607 BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
608 CompletionCondition& completion_condition, ReadHandler& handler)
609 : detail::base_from_completion_cond<
610 CompletionCondition>(completion_condition),
612 buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
614 total_transferred_(0),
615 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
619 #if defined(BOOST_ASIO_HAS_MOVE)
620 read_dynbuf_v1_op(const read_dynbuf_v1_op& other)
621 : detail::base_from_completion_cond<CompletionCondition>(other),
622 stream_(other.stream_),
623 buffers_(other.buffers_),
624 start_(other.start_),
625 total_transferred_(other.total_transferred_),
626 handler_(other.handler_)
630 read_dynbuf_v1_op(read_dynbuf_v1_op&& other)
631 : detail::base_from_completion_cond<CompletionCondition>(
632 BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
633 CompletionCondition>)(other)),
634 stream_(other.stream_),
635 buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),
636 start_(other.start_),
637 total_transferred_(other.total_transferred_),
638 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
641 #endif // defined(BOOST_ASIO_HAS_MOVE)
643 void operator()(const boost::system::error_code& ec,
644 std::size_t bytes_transferred, int start = 0)
646 std::size_t max_size, bytes_available;
647 switch (start_ = start)
650 max_size = this->check_for_completion(ec, total_transferred_);
651 bytes_available = std::min<std::size_t>(
652 std::max<std::size_t>(512,
653 buffers_.capacity() - buffers_.size()),
654 std::min<std::size_t>(max_size,
655 buffers_.max_size() - buffers_.size()));
659 BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read"));
660 stream_.async_read_some(buffers_.prepare(bytes_available),
661 BOOST_ASIO_MOVE_CAST(read_dynbuf_v1_op)(*this));
664 total_transferred_ += bytes_transferred;
665 buffers_.commit(bytes_transferred);
666 max_size = this->check_for_completion(ec, total_transferred_);
667 bytes_available = std::min<std::size_t>(
668 std::max<std::size_t>(512,
669 buffers_.capacity() - buffers_.size()),
670 std::min<std::size_t>(max_size,
671 buffers_.max_size() - buffers_.size()));
672 if ((!ec && bytes_transferred == 0) || bytes_available == 0)
676 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
681 AsyncReadStream& stream_;
682 DynamicBuffer_v1 buffers_;
684 std::size_t total_transferred_;
685 ReadHandler handler_;
688 template <typename AsyncReadStream, typename DynamicBuffer_v1,
689 typename CompletionCondition, typename ReadHandler>
690 inline asio_handler_allocate_is_deprecated
691 asio_handler_allocate(std::size_t size,
692 read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
693 CompletionCondition, ReadHandler>* this_handler)
695 #if defined(BOOST_ASIO_NO_DEPRECATED)
696 boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
697 return asio_handler_allocate_is_no_longer_used();
698 #else // defined(BOOST_ASIO_NO_DEPRECATED)
699 return boost_asio_handler_alloc_helpers::allocate(
700 size, this_handler->handler_);
701 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
704 template <typename AsyncReadStream, typename DynamicBuffer_v1,
705 typename CompletionCondition, typename ReadHandler>
706 inline asio_handler_deallocate_is_deprecated
707 asio_handler_deallocate(void* pointer, std::size_t size,
708 read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
709 CompletionCondition, ReadHandler>* this_handler)
711 boost_asio_handler_alloc_helpers::deallocate(
712 pointer, size, this_handler->handler_);
713 #if defined(BOOST_ASIO_NO_DEPRECATED)
714 return asio_handler_deallocate_is_no_longer_used();
715 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
718 template <typename AsyncReadStream, typename DynamicBuffer_v1,
719 typename CompletionCondition, typename ReadHandler>
720 inline bool asio_handler_is_continuation(
721 read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
722 CompletionCondition, ReadHandler>* this_handler)
724 return this_handler->start_ == 0 ? true
725 : boost_asio_handler_cont_helpers::is_continuation(
726 this_handler->handler_);
729 template <typename Function, typename AsyncReadStream,
730 typename DynamicBuffer_v1, typename CompletionCondition,
731 typename ReadHandler>
732 inline asio_handler_invoke_is_deprecated
733 asio_handler_invoke(Function& function,
734 read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
735 CompletionCondition, ReadHandler>* this_handler)
737 boost_asio_handler_invoke_helpers::invoke(
738 function, this_handler->handler_);
739 #if defined(BOOST_ASIO_NO_DEPRECATED)
740 return asio_handler_invoke_is_no_longer_used();
741 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
744 template <typename Function, typename AsyncReadStream,
745 typename DynamicBuffer_v1, typename CompletionCondition,
746 typename ReadHandler>
747 inline asio_handler_invoke_is_deprecated
748 asio_handler_invoke(const Function& function,
749 read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
750 CompletionCondition, ReadHandler>* this_handler)
752 boost_asio_handler_invoke_helpers::invoke(
753 function, this_handler->handler_);
754 #if defined(BOOST_ASIO_NO_DEPRECATED)
755 return asio_handler_invoke_is_no_longer_used();
756 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
759 template <typename AsyncReadStream>
760 class initiate_async_read_dynbuf_v1
763 typedef typename AsyncReadStream::executor_type executor_type;
765 explicit initiate_async_read_dynbuf_v1(AsyncReadStream& stream)
770 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
772 return stream_.get_executor();
775 template <typename ReadHandler, typename DynamicBuffer_v1,
776 typename CompletionCondition>
777 void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
778 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
779 BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
781 // If you get an error on the following line it means that your handler
782 // does not meet the documented type requirements for a ReadHandler.
783 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
785 non_const_lvalue<ReadHandler> handler2(handler);
786 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
787 read_dynbuf_v1_op<AsyncReadStream, typename decay<DynamicBuffer_v1>::type,
788 CompletionCondition, typename decay<ReadHandler>::type>(
789 stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
790 completion_cond2.value, handler2.value)(
791 boost::system::error_code(), 0, 1);
795 AsyncReadStream& stream_;
797 } // namespace detail
799 #if !defined(GENERATING_DOCUMENTATION)
801 template <typename AsyncReadStream, typename DynamicBuffer_v1,
802 typename CompletionCondition, typename ReadHandler, typename Allocator>
803 struct associated_allocator<
804 detail::read_dynbuf_v1_op<AsyncReadStream,
805 DynamicBuffer_v1, CompletionCondition, ReadHandler>,
808 typedef typename associated_allocator<ReadHandler, Allocator>::type type;
811 const detail::read_dynbuf_v1_op<AsyncReadStream,
812 DynamicBuffer_v1, CompletionCondition, ReadHandler>& h,
813 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
815 return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
819 template <typename AsyncReadStream, typename DynamicBuffer_v1,
820 typename CompletionCondition, typename ReadHandler, typename Executor>
821 struct associated_executor<
822 detail::read_dynbuf_v1_op<AsyncReadStream,
823 DynamicBuffer_v1, CompletionCondition, ReadHandler>,
825 : detail::associated_executor_forwarding_base<ReadHandler, Executor>
827 typedef typename associated_executor<ReadHandler, Executor>::type type;
830 const detail::read_dynbuf_v1_op<AsyncReadStream,
831 DynamicBuffer_v1, CompletionCondition, ReadHandler>& h,
832 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
834 return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
838 #endif // !defined(GENERATING_DOCUMENTATION)
840 template <typename AsyncReadStream, typename DynamicBuffer_v1,
841 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
842 std::size_t)) ReadHandler>
843 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
844 void (boost::system::error_code, std::size_t))
845 async_read(AsyncReadStream& s,
846 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
847 BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
849 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
850 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
854 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
855 transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
858 template <typename AsyncReadStream,
859 typename DynamicBuffer_v1, typename CompletionCondition,
860 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
861 std::size_t)) ReadHandler>
862 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
863 void (boost::system::error_code, std::size_t))
864 async_read(AsyncReadStream& s,
865 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
866 CompletionCondition completion_condition,
867 BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
869 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
870 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
873 return async_initiate<ReadHandler,
874 void (boost::system::error_code, std::size_t)>(
875 detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),
876 handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
877 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
880 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
881 #if !defined(BOOST_ASIO_NO_IOSTREAM)
883 template <typename AsyncReadStream, typename Allocator,
884 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
885 std::size_t)) ReadHandler>
886 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
887 void (boost::system::error_code, std::size_t))
888 async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
889 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
891 return async_read(s, basic_streambuf_ref<Allocator>(b),
892 BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
895 template <typename AsyncReadStream,
896 typename Allocator, typename CompletionCondition,
897 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
898 std::size_t)) ReadHandler>
899 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
900 void (boost::system::error_code, std::size_t))
901 async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
902 CompletionCondition completion_condition,
903 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
905 return async_read(s, basic_streambuf_ref<Allocator>(b),
906 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition),
907 BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
910 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
911 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
912 #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
916 template <typename AsyncReadStream, typename DynamicBuffer_v2,
917 typename CompletionCondition, typename ReadHandler>
918 class read_dynbuf_v2_op
919 : detail::base_from_completion_cond<CompletionCondition>
922 template <typename BufferSequence>
923 read_dynbuf_v2_op(AsyncReadStream& stream,
924 BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
925 CompletionCondition& completion_condition, ReadHandler& handler)
926 : detail::base_from_completion_cond<
927 CompletionCondition>(completion_condition),
929 buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
931 total_transferred_(0),
933 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
937 #if defined(BOOST_ASIO_HAS_MOVE)
938 read_dynbuf_v2_op(const read_dynbuf_v2_op& other)
939 : detail::base_from_completion_cond<CompletionCondition>(other),
940 stream_(other.stream_),
941 buffers_(other.buffers_),
942 start_(other.start_),
943 total_transferred_(other.total_transferred_),
944 bytes_available_(other.bytes_available_),
945 handler_(other.handler_)
949 read_dynbuf_v2_op(read_dynbuf_v2_op&& other)
950 : detail::base_from_completion_cond<CompletionCondition>(
951 BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
952 CompletionCondition>)(other)),
953 stream_(other.stream_),
954 buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),
955 start_(other.start_),
956 total_transferred_(other.total_transferred_),
957 bytes_available_(other.bytes_available_),
958 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
961 #endif // defined(BOOST_ASIO_HAS_MOVE)
963 void operator()(const boost::system::error_code& ec,
964 std::size_t bytes_transferred, int start = 0)
966 std::size_t max_size, pos;
967 switch (start_ = start)
970 max_size = this->check_for_completion(ec, total_transferred_);
971 bytes_available_ = std::min<std::size_t>(
972 std::max<std::size_t>(512,
973 buffers_.capacity() - buffers_.size()),
974 std::min<std::size_t>(max_size,
975 buffers_.max_size() - buffers_.size()));
978 pos = buffers_.size();
979 buffers_.grow(bytes_available_);
981 BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read"));
982 stream_.async_read_some(buffers_.data(pos, bytes_available_),
983 BOOST_ASIO_MOVE_CAST(read_dynbuf_v2_op)(*this));
986 total_transferred_ += bytes_transferred;
987 buffers_.shrink(bytes_available_ - bytes_transferred);
988 max_size = this->check_for_completion(ec, total_transferred_);
989 bytes_available_ = std::min<std::size_t>(
990 std::max<std::size_t>(512,
991 buffers_.capacity() - buffers_.size()),
992 std::min<std::size_t>(max_size,
993 buffers_.max_size() - buffers_.size()));
994 if ((!ec && bytes_transferred == 0) || bytes_available_ == 0)
998 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
1003 AsyncReadStream& stream_;
1004 DynamicBuffer_v2 buffers_;
1006 std::size_t total_transferred_;
1007 std::size_t bytes_available_;
1008 ReadHandler handler_;
1011 template <typename AsyncReadStream, typename DynamicBuffer_v2,
1012 typename CompletionCondition, typename ReadHandler>
1013 inline asio_handler_allocate_is_deprecated
1014 asio_handler_allocate(std::size_t size,
1015 read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
1016 CompletionCondition, ReadHandler>* this_handler)
1018 #if defined(BOOST_ASIO_NO_DEPRECATED)
1019 boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
1020 return asio_handler_allocate_is_no_longer_used();
1021 #else // defined(BOOST_ASIO_NO_DEPRECATED)
1022 return boost_asio_handler_alloc_helpers::allocate(
1023 size, this_handler->handler_);
1024 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
1027 template <typename AsyncReadStream, typename DynamicBuffer_v2,
1028 typename CompletionCondition, typename ReadHandler>
1029 inline asio_handler_deallocate_is_deprecated
1030 asio_handler_deallocate(void* pointer, std::size_t size,
1031 read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
1032 CompletionCondition, ReadHandler>* this_handler)
1034 boost_asio_handler_alloc_helpers::deallocate(
1035 pointer, size, this_handler->handler_);
1036 #if defined(BOOST_ASIO_NO_DEPRECATED)
1037 return asio_handler_deallocate_is_no_longer_used();
1038 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
1041 template <typename AsyncReadStream, typename DynamicBuffer_v2,
1042 typename CompletionCondition, typename ReadHandler>
1043 inline bool asio_handler_is_continuation(
1044 read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
1045 CompletionCondition, ReadHandler>* this_handler)
1047 return this_handler->start_ == 0 ? true
1048 : boost_asio_handler_cont_helpers::is_continuation(
1049 this_handler->handler_);
1052 template <typename Function, typename AsyncReadStream,
1053 typename DynamicBuffer_v2, typename CompletionCondition,
1054 typename ReadHandler>
1055 inline asio_handler_invoke_is_deprecated
1056 asio_handler_invoke(Function& function,
1057 read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
1058 CompletionCondition, ReadHandler>* this_handler)
1060 boost_asio_handler_invoke_helpers::invoke(
1061 function, this_handler->handler_);
1062 #if defined(BOOST_ASIO_NO_DEPRECATED)
1063 return asio_handler_invoke_is_no_longer_used();
1064 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
1067 template <typename Function, typename AsyncReadStream,
1068 typename DynamicBuffer_v2, typename CompletionCondition,
1069 typename ReadHandler>
1070 inline asio_handler_invoke_is_deprecated
1071 asio_handler_invoke(const Function& function,
1072 read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
1073 CompletionCondition, ReadHandler>* this_handler)
1075 boost_asio_handler_invoke_helpers::invoke(
1076 function, this_handler->handler_);
1077 #if defined(BOOST_ASIO_NO_DEPRECATED)
1078 return asio_handler_invoke_is_no_longer_used();
1079 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
1082 template <typename AsyncReadStream>
1083 class initiate_async_read_dynbuf_v2
1086 typedef typename AsyncReadStream::executor_type executor_type;
1088 explicit initiate_async_read_dynbuf_v2(AsyncReadStream& stream)
1093 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
1095 return stream_.get_executor();
1098 template <typename ReadHandler, typename DynamicBuffer_v2,
1099 typename CompletionCondition>
1100 void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
1101 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
1102 BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
1104 // If you get an error on the following line it means that your handler
1105 // does not meet the documented type requirements for a ReadHandler.
1106 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
1108 non_const_lvalue<ReadHandler> handler2(handler);
1109 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
1110 read_dynbuf_v2_op<AsyncReadStream, typename decay<DynamicBuffer_v2>::type,
1111 CompletionCondition, typename decay<ReadHandler>::type>(
1112 stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
1113 completion_cond2.value, handler2.value)(
1114 boost::system::error_code(), 0, 1);
1118 AsyncReadStream& stream_;
1120 } // namespace detail
1122 #if !defined(GENERATING_DOCUMENTATION)
1124 template <typename AsyncReadStream, typename DynamicBuffer_v2,
1125 typename CompletionCondition, typename ReadHandler, typename Allocator>
1126 struct associated_allocator<
1127 detail::read_dynbuf_v2_op<AsyncReadStream,
1128 DynamicBuffer_v2, CompletionCondition, ReadHandler>,
1131 typedef typename associated_allocator<ReadHandler, Allocator>::type type;
1134 const detail::read_dynbuf_v2_op<AsyncReadStream,
1135 DynamicBuffer_v2, CompletionCondition, ReadHandler>& h,
1136 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
1138 return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
1142 template <typename AsyncReadStream, typename DynamicBuffer_v2,
1143 typename CompletionCondition, typename ReadHandler, typename Executor>
1144 struct associated_executor<
1145 detail::read_dynbuf_v2_op<AsyncReadStream,
1146 DynamicBuffer_v2, CompletionCondition, ReadHandler>,
1148 : detail::associated_executor_forwarding_base<ReadHandler, Executor>
1150 typedef typename associated_executor<ReadHandler, Executor>::type type;
1153 const detail::read_dynbuf_v2_op<AsyncReadStream,
1154 DynamicBuffer_v2, CompletionCondition, ReadHandler>& h,
1155 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
1157 return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
1161 #endif // !defined(GENERATING_DOCUMENTATION)
1163 template <typename AsyncReadStream, typename DynamicBuffer_v2,
1164 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1165 std::size_t)) ReadHandler>
1166 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
1167 void (boost::system::error_code, std::size_t))
1168 async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
1169 BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
1171 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1174 return async_read(s,
1175 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
1176 transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
1179 template <typename AsyncReadStream,
1180 typename DynamicBuffer_v2, typename CompletionCondition,
1181 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1182 std::size_t)) ReadHandler>
1183 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
1184 void (boost::system::error_code, std::size_t))
1185 async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
1186 CompletionCondition completion_condition,
1187 BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
1189 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1192 return async_initiate<ReadHandler,
1193 void (boost::system::error_code, std::size_t)>(
1194 detail::initiate_async_read_dynbuf_v2<AsyncReadStream>(s),
1195 handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
1196 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
1200 } // namespace boost
1202 #include <boost/asio/detail/pop_options.hpp>
1204 #endif // BOOST_ASIO_IMPL_READ_HPP