1 //
2 // impl/write.hpp
3 // ~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 #ifndef BOOST_ASIO_IMPL_WRITE_HPP
12 #define BOOST_ASIO_IMPL_WRITE_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18 #include <boost/asio/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_tracking.hpp>
31 #include <boost/asio/detail/handler_type_requirements.hpp>
32 #include <boost/asio/detail/non_const_lvalue.hpp>
33 #include <boost/asio/detail/throw_error.hpp>
34
35 #include <boost/asio/detail/push_options.hpp>
36
37 namespace boost {
38 namespace asio {
39
40 namespace detail
41 {
42 template <typename SyncWriteStream, typename ConstBufferSequence,
43 typename ConstBufferIterator, typename CompletionCondition>
write_buffer_sequence(SyncWriteStream & s,const ConstBufferSequence & buffers,const ConstBufferIterator &,CompletionCondition completion_condition,boost::system::error_code & ec)44 std::size_t write_buffer_sequence(SyncWriteStream& s,
45 const ConstBufferSequence& buffers, const ConstBufferIterator&,
46 CompletionCondition completion_condition, boost::system::error_code& ec)
47 {
48 ec = boost::system::error_code();
49 boost::asio::detail::consuming_buffers<const_buffer,
50 ConstBufferSequence, ConstBufferIterator> tmp(buffers);
51 while (!tmp.empty())
52 {
53 if (std::size_t max_size = detail::adapt_completion_condition_result(
54 completion_condition(ec, tmp.total_consumed())))
55 tmp.consume(s.write_some(tmp.prepare(max_size), ec));
56 else
57 break;
58 }
59 return tmp.total_consumed();
60 }
61 } // namespace detail
62
63 template <typename SyncWriteStream, typename ConstBufferSequence,
64 typename CompletionCondition>
write(SyncWriteStream & s,const ConstBufferSequence & buffers,CompletionCondition completion_condition,boost::system::error_code & ec,typename constraint<is_const_buffer_sequence<ConstBufferSequence>::value>::type)65 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
66 CompletionCondition completion_condition, boost::system::error_code& ec,
67 typename constraint<
68 is_const_buffer_sequence<ConstBufferSequence>::value
69 >::type)
70 {
71 return detail::write_buffer_sequence(s, buffers,
72 boost::asio::buffer_sequence_begin(buffers),
73 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
74 }
75
76 template <typename SyncWriteStream, typename ConstBufferSequence>
write(SyncWriteStream & s,const ConstBufferSequence & buffers,typename constraint<is_const_buffer_sequence<ConstBufferSequence>::value>::type)77 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
78 typename constraint<
79 is_const_buffer_sequence<ConstBufferSequence>::value
80 >::type)
81 {
82 boost::system::error_code ec;
83 std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec);
84 boost::asio::detail::throw_error(ec, "write");
85 return bytes_transferred;
86 }
87
88 template <typename SyncWriteStream, typename ConstBufferSequence>
write(SyncWriteStream & s,const ConstBufferSequence & buffers,boost::system::error_code & ec,typename constraint<is_const_buffer_sequence<ConstBufferSequence>::value>::type)89 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
90 boost::system::error_code& ec,
91 typename constraint<
92 is_const_buffer_sequence<ConstBufferSequence>::value
93 >::type)
94 {
95 return write(s, buffers, transfer_all(), ec);
96 }
97
98 template <typename SyncWriteStream, typename ConstBufferSequence,
99 typename CompletionCondition>
write(SyncWriteStream & s,const ConstBufferSequence & buffers,CompletionCondition completion_condition,typename constraint<is_const_buffer_sequence<ConstBufferSequence>::value>::type)100 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
101 CompletionCondition completion_condition,
102 typename constraint<
103 is_const_buffer_sequence<ConstBufferSequence>::value
104 >::type)
105 {
106 boost::system::error_code ec;
107 std::size_t bytes_transferred = write(s, buffers,
108 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
109 boost::asio::detail::throw_error(ec, "write");
110 return bytes_transferred;
111 }
112
113 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
114
115 template <typename SyncWriteStream, typename DynamicBuffer_v1,
116 typename CompletionCondition>
write(SyncWriteStream & s,BOOST_ASIO_MOVE_ARG (DynamicBuffer_v1)buffers,CompletionCondition completion_condition,boost::system::error_code & ec,typename constraint<is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value>::type,typename constraint<!is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value>::type)117 std::size_t write(SyncWriteStream& s,
118 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
119 CompletionCondition completion_condition, boost::system::error_code& ec,
120 typename constraint<
121 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
122 >::type,
123 typename constraint<
124 !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
125 >::type)
126 {
127 typename decay<DynamicBuffer_v1>::type b(
128 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));
129
130 std::size_t bytes_transferred = write(s, b.data(),
131 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
132 b.consume(bytes_transferred);
133 return bytes_transferred;
134 }
135
136 template <typename SyncWriteStream, typename DynamicBuffer_v1>
write(SyncWriteStream & s,BOOST_ASIO_MOVE_ARG (DynamicBuffer_v1)buffers,typename constraint<is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value>::type,typename constraint<!is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value>::type)137 inline std::size_t write(SyncWriteStream& s,
138 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
139 typename constraint<
140 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
141 >::type,
142 typename constraint<
143 !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
144 >::type)
145 {
146 boost::system::error_code ec;
147 std::size_t bytes_transferred = write(s,
148 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
149 transfer_all(), ec);
150 boost::asio::detail::throw_error(ec, "write");
151 return bytes_transferred;
152 }
153
154 template <typename SyncWriteStream, typename DynamicBuffer_v1>
write(SyncWriteStream & s,BOOST_ASIO_MOVE_ARG (DynamicBuffer_v1)buffers,boost::system::error_code & ec,typename constraint<is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value>::type,typename constraint<!is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value>::type)155 inline std::size_t write(SyncWriteStream& s,
156 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
157 boost::system::error_code& ec,
158 typename constraint<
159 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
160 >::type,
161 typename constraint<
162 !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
163 >::type)
164 {
165 return write(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
166 transfer_all(), ec);
167 }
168
169 template <typename SyncWriteStream, typename DynamicBuffer_v1,
170 typename CompletionCondition>
write(SyncWriteStream & s,BOOST_ASIO_MOVE_ARG (DynamicBuffer_v1)buffers,CompletionCondition completion_condition,typename constraint<is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value>::type,typename constraint<!is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value>::type)171 inline std::size_t write(SyncWriteStream& s,
172 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
173 CompletionCondition completion_condition,
174 typename constraint<
175 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
176 >::type,
177 typename constraint<
178 !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
179 >::type)
180 {
181 boost::system::error_code ec;
182 std::size_t bytes_transferred = write(s,
183 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
184 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
185 boost::asio::detail::throw_error(ec, "write");
186 return bytes_transferred;
187 }
188
189 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
190 #if !defined(BOOST_ASIO_NO_IOSTREAM)
191
192 template <typename SyncWriteStream, typename Allocator,
193 typename CompletionCondition>
write(SyncWriteStream & s,boost::asio::basic_streambuf<Allocator> & b,CompletionCondition completion_condition,boost::system::error_code & ec)194 inline std::size_t write(SyncWriteStream& s,
195 boost::asio::basic_streambuf<Allocator>& b,
196 CompletionCondition completion_condition, boost::system::error_code& ec)
197 {
198 return write(s, basic_streambuf_ref<Allocator>(b),
199 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
200 }
201
202 template <typename SyncWriteStream, typename Allocator>
write(SyncWriteStream & s,boost::asio::basic_streambuf<Allocator> & b)203 inline std::size_t write(SyncWriteStream& s,
204 boost::asio::basic_streambuf<Allocator>& b)
205 {
206 return write(s, basic_streambuf_ref<Allocator>(b));
207 }
208
209 template <typename SyncWriteStream, typename Allocator>
write(SyncWriteStream & s,boost::asio::basic_streambuf<Allocator> & b,boost::system::error_code & ec)210 inline std::size_t write(SyncWriteStream& s,
211 boost::asio::basic_streambuf<Allocator>& b,
212 boost::system::error_code& ec)
213 {
214 return write(s, basic_streambuf_ref<Allocator>(b), ec);
215 }
216
217 template <typename SyncWriteStream, typename Allocator,
218 typename CompletionCondition>
write(SyncWriteStream & s,boost::asio::basic_streambuf<Allocator> & b,CompletionCondition completion_condition)219 inline std::size_t write(SyncWriteStream& s,
220 boost::asio::basic_streambuf<Allocator>& b,
221 CompletionCondition completion_condition)
222 {
223 return write(s, basic_streambuf_ref<Allocator>(b),
224 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
225 }
226
227 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
228 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
229 #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
230
231 template <typename SyncWriteStream, typename DynamicBuffer_v2,
232 typename CompletionCondition>
write(SyncWriteStream & s,DynamicBuffer_v2 buffers,CompletionCondition completion_condition,boost::system::error_code & ec,typename constraint<is_dynamic_buffer_v2<DynamicBuffer_v2>::value>::type)233 std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
234 CompletionCondition completion_condition, boost::system::error_code& ec,
235 typename constraint<
236 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
237 >::type)
238 {
239 std::size_t bytes_transferred = write(s, buffers.data(0, buffers.size()),
240 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
241 buffers.consume(bytes_transferred);
242 return bytes_transferred;
243 }
244
245 template <typename SyncWriteStream, typename DynamicBuffer_v2>
write(SyncWriteStream & s,DynamicBuffer_v2 buffers,typename constraint<is_dynamic_buffer_v2<DynamicBuffer_v2>::value>::type)246 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
247 typename constraint<
248 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
249 >::type)
250 {
251 boost::system::error_code ec;
252 std::size_t bytes_transferred = write(s,
253 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
254 transfer_all(), ec);
255 boost::asio::detail::throw_error(ec, "write");
256 return bytes_transferred;
257 }
258
259 template <typename SyncWriteStream, typename DynamicBuffer_v2>
write(SyncWriteStream & s,DynamicBuffer_v2 buffers,boost::system::error_code & ec,typename constraint<is_dynamic_buffer_v2<DynamicBuffer_v2>::value>::type)260 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
261 boost::system::error_code& ec,
262 typename constraint<
263 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
264 >::type)
265 {
266 return write(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
267 transfer_all(), ec);
268 }
269
270 template <typename SyncWriteStream, typename DynamicBuffer_v2,
271 typename CompletionCondition>
write(SyncWriteStream & s,DynamicBuffer_v2 buffers,CompletionCondition completion_condition,typename constraint<is_dynamic_buffer_v2<DynamicBuffer_v2>::value>::type)272 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
273 CompletionCondition completion_condition,
274 typename constraint<
275 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
276 >::type)
277 {
278 boost::system::error_code ec;
279 std::size_t bytes_transferred = write(s,
280 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
281 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
282 boost::asio::detail::throw_error(ec, "write");
283 return bytes_transferred;
284 }
285
286 namespace detail
287 {
288 template <typename AsyncWriteStream, typename ConstBufferSequence,
289 typename ConstBufferIterator, typename CompletionCondition,
290 typename WriteHandler>
291 class write_op
292 : detail::base_from_completion_cond<CompletionCondition>
293 {
294 public:
write_op(AsyncWriteStream & stream,const ConstBufferSequence & buffers,CompletionCondition & completion_condition,WriteHandler & handler)295 write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers,
296 CompletionCondition& completion_condition, WriteHandler& handler)
297 : detail::base_from_completion_cond<
298 CompletionCondition>(completion_condition),
299 stream_(stream),
300 buffers_(buffers),
301 start_(0),
302 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
303 {
304 }
305
306 #if defined(BOOST_ASIO_HAS_MOVE)
write_op(const write_op & other)307 write_op(const write_op& other)
308 : detail::base_from_completion_cond<CompletionCondition>(other),
309 stream_(other.stream_),
310 buffers_(other.buffers_),
311 start_(other.start_),
312 handler_(other.handler_)
313 {
314 }
315
write_op(write_op && other)316 write_op(write_op&& other)
317 : detail::base_from_completion_cond<CompletionCondition>(
318 BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
319 CompletionCondition>)(other)),
320 stream_(other.stream_),
321 buffers_(BOOST_ASIO_MOVE_CAST(buffers_type)(other.buffers_)),
322 start_(other.start_),
323 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
324 {
325 }
326 #endif // defined(BOOST_ASIO_HAS_MOVE)
327
operator ()(const boost::system::error_code & ec,std::size_t bytes_transferred,int start=0)328 void operator()(const boost::system::error_code& ec,
329 std::size_t bytes_transferred, int start = 0)
330 {
331 std::size_t max_size;
332 switch (start_ = start)
333 {
334 case 1:
335 max_size = this->check_for_completion(ec, buffers_.total_consumed());
336 do
337 {
338 {
339 BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_write"));
340 stream_.async_write_some(buffers_.prepare(max_size),
341 BOOST_ASIO_MOVE_CAST(write_op)(*this));
342 }
343 return; default:
344 buffers_.consume(bytes_transferred);
345 if ((!ec && bytes_transferred == 0) || buffers_.empty())
346 break;
347 max_size = this->check_for_completion(ec, buffers_.total_consumed());
348 } while (max_size > 0);
349
350 handler_(ec, buffers_.total_consumed());
351 }
352 }
353
354 //private:
355 typedef boost::asio::detail::consuming_buffers<const_buffer,
356 ConstBufferSequence, ConstBufferIterator> buffers_type;
357
358 AsyncWriteStream& stream_;
359 buffers_type buffers_;
360 int start_;
361 WriteHandler handler_;
362 };
363
364 template <typename AsyncWriteStream, typename ConstBufferSequence,
365 typename ConstBufferIterator, typename CompletionCondition,
366 typename WriteHandler>
367 inline asio_handler_allocate_is_deprecated
asio_handler_allocate(std::size_t size,write_op<AsyncWriteStream,ConstBufferSequence,ConstBufferIterator,CompletionCondition,WriteHandler> * this_handler)368 asio_handler_allocate(std::size_t size,
369 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
370 CompletionCondition, WriteHandler>* this_handler)
371 {
372 #if defined(BOOST_ASIO_NO_DEPRECATED)
373 boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
374 return asio_handler_allocate_is_no_longer_used();
375 #else // defined(BOOST_ASIO_NO_DEPRECATED)
376 return boost_asio_handler_alloc_helpers::allocate(
377 size, this_handler->handler_);
378 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
379 }
380
381 template <typename AsyncWriteStream, typename ConstBufferSequence,
382 typename ConstBufferIterator, typename CompletionCondition,
383 typename WriteHandler>
384 inline asio_handler_deallocate_is_deprecated
asio_handler_deallocate(void * pointer,std::size_t size,write_op<AsyncWriteStream,ConstBufferSequence,ConstBufferIterator,CompletionCondition,WriteHandler> * this_handler)385 asio_handler_deallocate(void* pointer, std::size_t size,
386 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
387 CompletionCondition, WriteHandler>* this_handler)
388 {
389 boost_asio_handler_alloc_helpers::deallocate(
390 pointer, size, this_handler->handler_);
391 #if defined(BOOST_ASIO_NO_DEPRECATED)
392 return asio_handler_deallocate_is_no_longer_used();
393 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
394 }
395
396 template <typename AsyncWriteStream, typename ConstBufferSequence,
397 typename ConstBufferIterator, typename CompletionCondition,
398 typename WriteHandler>
asio_handler_is_continuation(write_op<AsyncWriteStream,ConstBufferSequence,ConstBufferIterator,CompletionCondition,WriteHandler> * this_handler)399 inline bool asio_handler_is_continuation(
400 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
401 CompletionCondition, WriteHandler>* this_handler)
402 {
403 return this_handler->start_ == 0 ? true
404 : boost_asio_handler_cont_helpers::is_continuation(
405 this_handler->handler_);
406 }
407
408 template <typename Function, typename AsyncWriteStream,
409 typename ConstBufferSequence, typename ConstBufferIterator,
410 typename CompletionCondition, typename WriteHandler>
411 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(Function & function,write_op<AsyncWriteStream,ConstBufferSequence,ConstBufferIterator,CompletionCondition,WriteHandler> * this_handler)412 asio_handler_invoke(Function& function,
413 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
414 CompletionCondition, WriteHandler>* this_handler)
415 {
416 boost_asio_handler_invoke_helpers::invoke(
417 function, this_handler->handler_);
418 #if defined(BOOST_ASIO_NO_DEPRECATED)
419 return asio_handler_invoke_is_no_longer_used();
420 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
421 }
422
423 template <typename Function, typename AsyncWriteStream,
424 typename ConstBufferSequence, typename ConstBufferIterator,
425 typename CompletionCondition, typename WriteHandler>
426 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(const Function & function,write_op<AsyncWriteStream,ConstBufferSequence,ConstBufferIterator,CompletionCondition,WriteHandler> * this_handler)427 asio_handler_invoke(const Function& function,
428 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
429 CompletionCondition, WriteHandler>* this_handler)
430 {
431 boost_asio_handler_invoke_helpers::invoke(
432 function, this_handler->handler_);
433 #if defined(BOOST_ASIO_NO_DEPRECATED)
434 return asio_handler_invoke_is_no_longer_used();
435 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
436 }
437
438 template <typename AsyncWriteStream, typename ConstBufferSequence,
439 typename ConstBufferIterator, typename CompletionCondition,
440 typename WriteHandler>
start_write_buffer_sequence_op(AsyncWriteStream & stream,const ConstBufferSequence & buffers,const ConstBufferIterator &,CompletionCondition & completion_condition,WriteHandler & handler)441 inline void start_write_buffer_sequence_op(AsyncWriteStream& stream,
442 const ConstBufferSequence& buffers, const ConstBufferIterator&,
443 CompletionCondition& completion_condition, WriteHandler& handler)
444 {
445 detail::write_op<AsyncWriteStream, ConstBufferSequence,
446 ConstBufferIterator, CompletionCondition, WriteHandler>(
447 stream, buffers, completion_condition, handler)(
448 boost::system::error_code(), 0, 1);
449 }
450
451 template <typename AsyncWriteStream>
452 class initiate_async_write_buffer_sequence
453 {
454 public:
455 typedef typename AsyncWriteStream::executor_type executor_type;
456
initiate_async_write_buffer_sequence(AsyncWriteStream & stream)457 explicit initiate_async_write_buffer_sequence(AsyncWriteStream& stream)
458 : stream_(stream)
459 {
460 }
461
get_executor() const462 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
463 {
464 return stream_.get_executor();
465 }
466
467 template <typename WriteHandler, typename ConstBufferSequence,
468 typename CompletionCondition>
operator ()(BOOST_ASIO_MOVE_ARG (WriteHandler)handler,const ConstBufferSequence & buffers,BOOST_ASIO_MOVE_ARG (CompletionCondition)completion_cond) const469 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
470 const ConstBufferSequence& buffers,
471 BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
472 {
473 // If you get an error on the following line it means that your handler
474 // does not meet the documented type requirements for a WriteHandler.
475 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
476
477 non_const_lvalue<WriteHandler> handler2(handler);
478 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
479 start_write_buffer_sequence_op(stream_, buffers,
480 boost::asio::buffer_sequence_begin(buffers),
481 completion_cond2.value, handler2.value);
482 }
483
484 private:
485 AsyncWriteStream& stream_;
486 };
487 } // namespace detail
488
489 #if !defined(GENERATING_DOCUMENTATION)
490
491 template <typename AsyncWriteStream, typename ConstBufferSequence,
492 typename ConstBufferIterator, typename CompletionCondition,
493 typename WriteHandler, typename Allocator>
494 struct associated_allocator<
495 detail::write_op<AsyncWriteStream, ConstBufferSequence,
496 ConstBufferIterator, CompletionCondition, WriteHandler>,
497 Allocator>
498 {
499 typedef typename associated_allocator<WriteHandler, Allocator>::type type;
500
getboost::asio::associated_allocator501 static type get(
502 const detail::write_op<AsyncWriteStream, ConstBufferSequence,
503 ConstBufferIterator, CompletionCondition, WriteHandler>& h,
504 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
505 {
506 return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
507 }
508 };
509
510 template <typename AsyncWriteStream, typename ConstBufferSequence,
511 typename ConstBufferIterator, typename CompletionCondition,
512 typename WriteHandler, typename Executor>
513 struct associated_executor<
514 detail::write_op<AsyncWriteStream, ConstBufferSequence,
515 ConstBufferIterator, CompletionCondition, WriteHandler>,
516 Executor>
517 : detail::associated_executor_forwarding_base<WriteHandler, Executor>
518 {
519 typedef typename associated_executor<WriteHandler, Executor>::type type;
520
getboost::asio::associated_executor521 static type get(
522 const detail::write_op<AsyncWriteStream, ConstBufferSequence,
523 ConstBufferIterator, CompletionCondition, WriteHandler>& h,
524 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
525 {
526 return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
527 }
528 };
529
530 #endif // !defined(GENERATING_DOCUMENTATION)
531
532 template <typename AsyncWriteStream,
533 typename ConstBufferSequence, typename CompletionCondition,
534 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
535 std::size_t)) WriteHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,void (boost::system::error_code,std::size_t))536 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
537 void (boost::system::error_code, std::size_t))
538 async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
539 CompletionCondition completion_condition,
540 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
541 typename constraint<
542 is_const_buffer_sequence<ConstBufferSequence>::value
543 >::type)
544 {
545 return async_initiate<WriteHandler,
546 void (boost::system::error_code, std::size_t)>(
547 detail::initiate_async_write_buffer_sequence<AsyncWriteStream>(s),
548 handler, buffers,
549 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
550 }
551
552 template <typename AsyncWriteStream, typename ConstBufferSequence,
553 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
554 std::size_t)) WriteHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,void (boost::system::error_code,std::size_t))555 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
556 void (boost::system::error_code, std::size_t))
557 async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
558 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
559 typename constraint<
560 is_const_buffer_sequence<ConstBufferSequence>::value
561 >::type)
562 {
563 return async_initiate<WriteHandler,
564 void (boost::system::error_code, std::size_t)>(
565 detail::initiate_async_write_buffer_sequence<AsyncWriteStream>(s),
566 handler, buffers, transfer_all());
567 }
568
569 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
570
571 namespace detail
572 {
573 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
574 typename CompletionCondition, typename WriteHandler>
575 class write_dynbuf_v1_op
576 {
577 public:
578 template <typename BufferSequence>
write_dynbuf_v1_op(AsyncWriteStream & stream,BOOST_ASIO_MOVE_ARG (BufferSequence)buffers,CompletionCondition & completion_condition,WriteHandler & handler)579 write_dynbuf_v1_op(AsyncWriteStream& stream,
580 BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
581 CompletionCondition& completion_condition, WriteHandler& handler)
582 : stream_(stream),
583 buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
584 completion_condition_(
585 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)),
586 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
587 {
588 }
589
590 #if defined(BOOST_ASIO_HAS_MOVE)
write_dynbuf_v1_op(const write_dynbuf_v1_op & other)591 write_dynbuf_v1_op(const write_dynbuf_v1_op& other)
592 : stream_(other.stream_),
593 buffers_(other.buffers_),
594 completion_condition_(other.completion_condition_),
595 handler_(other.handler_)
596 {
597 }
598
write_dynbuf_v1_op(write_dynbuf_v1_op && other)599 write_dynbuf_v1_op(write_dynbuf_v1_op&& other)
600 : stream_(other.stream_),
601 buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),
602 completion_condition_(
603 BOOST_ASIO_MOVE_CAST(CompletionCondition)(
604 other.completion_condition_)),
605 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
606 {
607 }
608 #endif // defined(BOOST_ASIO_HAS_MOVE)
609
operator ()(const boost::system::error_code & ec,std::size_t bytes_transferred,int start=0)610 void operator()(const boost::system::error_code& ec,
611 std::size_t bytes_transferred, int start = 0)
612 {
613 switch (start)
614 {
615 case 1:
616 async_write(stream_, buffers_.data(),
617 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),
618 BOOST_ASIO_MOVE_CAST(write_dynbuf_v1_op)(*this));
619 return; default:
620 buffers_.consume(bytes_transferred);
621 handler_(ec, static_cast<const std::size_t&>(bytes_transferred));
622 }
623 }
624
625 //private:
626 AsyncWriteStream& stream_;
627 DynamicBuffer_v1 buffers_;
628 CompletionCondition completion_condition_;
629 WriteHandler handler_;
630 };
631
632 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
633 typename CompletionCondition, typename WriteHandler>
634 inline asio_handler_allocate_is_deprecated
asio_handler_allocate(std::size_t size,write_dynbuf_v1_op<AsyncWriteStream,DynamicBuffer_v1,CompletionCondition,WriteHandler> * this_handler)635 asio_handler_allocate(std::size_t size,
636 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
637 CompletionCondition, WriteHandler>* this_handler)
638 {
639 #if defined(BOOST_ASIO_NO_DEPRECATED)
640 boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
641 return asio_handler_allocate_is_no_longer_used();
642 #else // defined(BOOST_ASIO_NO_DEPRECATED)
643 return boost_asio_handler_alloc_helpers::allocate(
644 size, this_handler->handler_);
645 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
646 }
647
648 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
649 typename CompletionCondition, typename WriteHandler>
650 inline asio_handler_deallocate_is_deprecated
asio_handler_deallocate(void * pointer,std::size_t size,write_dynbuf_v1_op<AsyncWriteStream,DynamicBuffer_v1,CompletionCondition,WriteHandler> * this_handler)651 asio_handler_deallocate(void* pointer, std::size_t size,
652 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
653 CompletionCondition, WriteHandler>* this_handler)
654 {
655 boost_asio_handler_alloc_helpers::deallocate(
656 pointer, size, this_handler->handler_);
657 #if defined(BOOST_ASIO_NO_DEPRECATED)
658 return asio_handler_deallocate_is_no_longer_used();
659 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
660 }
661
662 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
663 typename CompletionCondition, typename WriteHandler>
asio_handler_is_continuation(write_dynbuf_v1_op<AsyncWriteStream,DynamicBuffer_v1,CompletionCondition,WriteHandler> * this_handler)664 inline bool asio_handler_is_continuation(
665 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
666 CompletionCondition, WriteHandler>* this_handler)
667 {
668 return boost_asio_handler_cont_helpers::is_continuation(
669 this_handler->handler_);
670 }
671
672 template <typename Function, typename AsyncWriteStream,
673 typename DynamicBuffer_v1, typename CompletionCondition,
674 typename WriteHandler>
675 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(Function & function,write_dynbuf_v1_op<AsyncWriteStream,DynamicBuffer_v1,CompletionCondition,WriteHandler> * this_handler)676 asio_handler_invoke(Function& function,
677 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
678 CompletionCondition, WriteHandler>* this_handler)
679 {
680 boost_asio_handler_invoke_helpers::invoke(
681 function, this_handler->handler_);
682 #if defined(BOOST_ASIO_NO_DEPRECATED)
683 return asio_handler_invoke_is_no_longer_used();
684 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
685 }
686
687 template <typename Function, typename AsyncWriteStream,
688 typename DynamicBuffer_v1, typename CompletionCondition,
689 typename WriteHandler>
690 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(const Function & function,write_dynbuf_v1_op<AsyncWriteStream,DynamicBuffer_v1,CompletionCondition,WriteHandler> * this_handler)691 asio_handler_invoke(const Function& function,
692 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
693 CompletionCondition, WriteHandler>* this_handler)
694 {
695 boost_asio_handler_invoke_helpers::invoke(
696 function, this_handler->handler_);
697 #if defined(BOOST_ASIO_NO_DEPRECATED)
698 return asio_handler_invoke_is_no_longer_used();
699 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
700 }
701
702 template <typename AsyncWriteStream>
703 class initiate_async_write_dynbuf_v1
704 {
705 public:
706 typedef typename AsyncWriteStream::executor_type executor_type;
707
initiate_async_write_dynbuf_v1(AsyncWriteStream & stream)708 explicit initiate_async_write_dynbuf_v1(AsyncWriteStream& stream)
709 : stream_(stream)
710 {
711 }
712
get_executor() const713 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
714 {
715 return stream_.get_executor();
716 }
717
718 template <typename WriteHandler, typename DynamicBuffer_v1,
719 typename CompletionCondition>
operator ()(BOOST_ASIO_MOVE_ARG (WriteHandler)handler,BOOST_ASIO_MOVE_ARG (DynamicBuffer_v1)buffers,BOOST_ASIO_MOVE_ARG (CompletionCondition)completion_cond) const720 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
721 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
722 BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
723 {
724 // If you get an error on the following line it means that your handler
725 // does not meet the documented type requirements for a WriteHandler.
726 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
727
728 non_const_lvalue<WriteHandler> handler2(handler);
729 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
730 write_dynbuf_v1_op<AsyncWriteStream,
731 typename decay<DynamicBuffer_v1>::type,
732 CompletionCondition, typename decay<WriteHandler>::type>(
733 stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
734 completion_cond2.value, handler2.value)(
735 boost::system::error_code(), 0, 1);
736 }
737
738 private:
739 AsyncWriteStream& stream_;
740 };
741 } // namespace detail
742
743 #if !defined(GENERATING_DOCUMENTATION)
744
745 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
746 typename CompletionCondition, typename WriteHandler, typename Allocator>
747 struct associated_allocator<
748 detail::write_dynbuf_v1_op<AsyncWriteStream,
749 DynamicBuffer_v1, CompletionCondition, WriteHandler>,
750 Allocator>
751 {
752 typedef typename associated_allocator<WriteHandler, Allocator>::type type;
753
getboost::asio::associated_allocator754 static type get(
755 const detail::write_dynbuf_v1_op<AsyncWriteStream,
756 DynamicBuffer_v1, CompletionCondition, WriteHandler>& h,
757 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
758 {
759 return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
760 }
761 };
762
763 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
764 typename CompletionCondition, typename WriteHandler, typename Executor>
765 struct associated_executor<
766 detail::write_dynbuf_v1_op<AsyncWriteStream,
767 DynamicBuffer_v1, CompletionCondition, WriteHandler>,
768 Executor>
769 : detail::associated_executor_forwarding_base<WriteHandler, Executor>
770 {
771 typedef typename associated_executor<WriteHandler, Executor>::type type;
772
getboost::asio::associated_executor773 static type get(
774 const detail::write_dynbuf_v1_op<AsyncWriteStream,
775 DynamicBuffer_v1, CompletionCondition, WriteHandler>& h,
776 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
777 {
778 return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
779 }
780 };
781
782 #endif // !defined(GENERATING_DOCUMENTATION)
783
784 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
785 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
786 std::size_t)) WriteHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,void (boost::system::error_code,std::size_t))787 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
788 void (boost::system::error_code, std::size_t))
789 async_write(AsyncWriteStream& s,
790 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
791 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
792 typename constraint<
793 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
794 >::type,
795 typename constraint<
796 !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
797 >::type)
798 {
799 return async_write(s,
800 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
801 transfer_all(), BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
802 }
803
804 template <typename AsyncWriteStream,
805 typename DynamicBuffer_v1, typename CompletionCondition,
806 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
807 std::size_t)) WriteHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,void (boost::system::error_code,std::size_t))808 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
809 void (boost::system::error_code, std::size_t))
810 async_write(AsyncWriteStream& s,
811 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
812 CompletionCondition completion_condition,
813 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
814 typename constraint<
815 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
816 >::type,
817 typename constraint<
818 !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
819 >::type)
820 {
821 return async_initiate<WriteHandler,
822 void (boost::system::error_code, std::size_t)>(
823 detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),
824 handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
825 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
826 }
827
828 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
829 #if !defined(BOOST_ASIO_NO_IOSTREAM)
830
831 template <typename AsyncWriteStream, typename Allocator,
832 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
833 std::size_t)) WriteHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,void (boost::system::error_code,std::size_t))834 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
835 void (boost::system::error_code, std::size_t))
836 async_write(AsyncWriteStream& s,
837 boost::asio::basic_streambuf<Allocator>& b,
838 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
839 {
840 return async_write(s, basic_streambuf_ref<Allocator>(b),
841 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
842 }
843
844 template <typename AsyncWriteStream,
845 typename Allocator, typename CompletionCondition,
846 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
847 std::size_t)) WriteHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,void (boost::system::error_code,std::size_t))848 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
849 void (boost::system::error_code, std::size_t))
850 async_write(AsyncWriteStream& s,
851 boost::asio::basic_streambuf<Allocator>& b,
852 CompletionCondition completion_condition,
853 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
854 {
855 return async_write(s, basic_streambuf_ref<Allocator>(b),
856 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition),
857 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
858 }
859
860 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
861 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
862 #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
863
864 namespace detail
865 {
866 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
867 typename CompletionCondition, typename WriteHandler>
868 class write_dynbuf_v2_op
869 {
870 public:
871 template <typename BufferSequence>
write_dynbuf_v2_op(AsyncWriteStream & stream,BOOST_ASIO_MOVE_ARG (BufferSequence)buffers,CompletionCondition & completion_condition,WriteHandler & handler)872 write_dynbuf_v2_op(AsyncWriteStream& stream,
873 BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
874 CompletionCondition& completion_condition, WriteHandler& handler)
875 : stream_(stream),
876 buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
877 completion_condition_(
878 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)),
879 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
880 {
881 }
882
883 #if defined(BOOST_ASIO_HAS_MOVE)
write_dynbuf_v2_op(const write_dynbuf_v2_op & other)884 write_dynbuf_v2_op(const write_dynbuf_v2_op& other)
885 : stream_(other.stream_),
886 buffers_(other.buffers_),
887 completion_condition_(other.completion_condition_),
888 handler_(other.handler_)
889 {
890 }
891
write_dynbuf_v2_op(write_dynbuf_v2_op && other)892 write_dynbuf_v2_op(write_dynbuf_v2_op&& other)
893 : stream_(other.stream_),
894 buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),
895 completion_condition_(
896 BOOST_ASIO_MOVE_CAST(CompletionCondition)(
897 other.completion_condition_)),
898 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
899 {
900 }
901 #endif // defined(BOOST_ASIO_HAS_MOVE)
902
operator ()(const boost::system::error_code & ec,std::size_t bytes_transferred,int start=0)903 void operator()(const boost::system::error_code& ec,
904 std::size_t bytes_transferred, int start = 0)
905 {
906 switch (start)
907 {
908 case 1:
909 async_write(stream_, buffers_.data(0, buffers_.size()),
910 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),
911 BOOST_ASIO_MOVE_CAST(write_dynbuf_v2_op)(*this));
912 return; default:
913 buffers_.consume(bytes_transferred);
914 handler_(ec, static_cast<const std::size_t&>(bytes_transferred));
915 }
916 }
917
918 //private:
919 AsyncWriteStream& stream_;
920 DynamicBuffer_v2 buffers_;
921 CompletionCondition completion_condition_;
922 WriteHandler handler_;
923 };
924
925 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
926 typename CompletionCondition, typename WriteHandler>
927 inline asio_handler_allocate_is_deprecated
asio_handler_allocate(std::size_t size,write_dynbuf_v2_op<AsyncWriteStream,DynamicBuffer_v2,CompletionCondition,WriteHandler> * this_handler)928 asio_handler_allocate(std::size_t size,
929 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
930 CompletionCondition, WriteHandler>* this_handler)
931 {
932 #if defined(BOOST_ASIO_NO_DEPRECATED)
933 boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
934 return asio_handler_allocate_is_no_longer_used();
935 #else // defined(BOOST_ASIO_NO_DEPRECATED)
936 return boost_asio_handler_alloc_helpers::allocate(
937 size, this_handler->handler_);
938 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
939 }
940
941 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
942 typename CompletionCondition, typename WriteHandler>
943 inline asio_handler_deallocate_is_deprecated
asio_handler_deallocate(void * pointer,std::size_t size,write_dynbuf_v2_op<AsyncWriteStream,DynamicBuffer_v2,CompletionCondition,WriteHandler> * this_handler)944 asio_handler_deallocate(void* pointer, std::size_t size,
945 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
946 CompletionCondition, WriteHandler>* this_handler)
947 {
948 boost_asio_handler_alloc_helpers::deallocate(
949 pointer, size, this_handler->handler_);
950 #if defined(BOOST_ASIO_NO_DEPRECATED)
951 return asio_handler_deallocate_is_no_longer_used();
952 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
953 }
954
955 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
956 typename CompletionCondition, typename WriteHandler>
asio_handler_is_continuation(write_dynbuf_v2_op<AsyncWriteStream,DynamicBuffer_v2,CompletionCondition,WriteHandler> * this_handler)957 inline bool asio_handler_is_continuation(
958 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
959 CompletionCondition, WriteHandler>* this_handler)
960 {
961 return boost_asio_handler_cont_helpers::is_continuation(
962 this_handler->handler_);
963 }
964
965 template <typename Function, typename AsyncWriteStream,
966 typename DynamicBuffer_v2, typename CompletionCondition,
967 typename WriteHandler>
968 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(Function & function,write_dynbuf_v2_op<AsyncWriteStream,DynamicBuffer_v2,CompletionCondition,WriteHandler> * this_handler)969 asio_handler_invoke(Function& function,
970 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
971 CompletionCondition, WriteHandler>* this_handler)
972 {
973 boost_asio_handler_invoke_helpers::invoke(
974 function, this_handler->handler_);
975 #if defined(BOOST_ASIO_NO_DEPRECATED)
976 return asio_handler_invoke_is_no_longer_used();
977 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
978 }
979
980 template <typename Function, typename AsyncWriteStream,
981 typename DynamicBuffer_v2, typename CompletionCondition,
982 typename WriteHandler>
983 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(const Function & function,write_dynbuf_v2_op<AsyncWriteStream,DynamicBuffer_v2,CompletionCondition,WriteHandler> * this_handler)984 asio_handler_invoke(const Function& function,
985 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
986 CompletionCondition, WriteHandler>* this_handler)
987 {
988 boost_asio_handler_invoke_helpers::invoke(
989 function, this_handler->handler_);
990 #if defined(BOOST_ASIO_NO_DEPRECATED)
991 return asio_handler_invoke_is_no_longer_used();
992 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
993 }
994
995 template <typename AsyncWriteStream>
996 class initiate_async_write_dynbuf_v2
997 {
998 public:
999 typedef typename AsyncWriteStream::executor_type executor_type;
1000
initiate_async_write_dynbuf_v2(AsyncWriteStream & stream)1001 explicit initiate_async_write_dynbuf_v2(AsyncWriteStream& stream)
1002 : stream_(stream)
1003 {
1004 }
1005
get_executor() const1006 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
1007 {
1008 return stream_.get_executor();
1009 }
1010
1011 template <typename WriteHandler, typename DynamicBuffer_v2,
1012 typename CompletionCondition>
operator ()(BOOST_ASIO_MOVE_ARG (WriteHandler)handler,BOOST_ASIO_MOVE_ARG (DynamicBuffer_v2)buffers,BOOST_ASIO_MOVE_ARG (CompletionCondition)completion_cond) const1013 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
1014 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
1015 BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
1016 {
1017 // If you get an error on the following line it means that your handler
1018 // does not meet the documented type requirements for a WriteHandler.
1019 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
1020
1021 non_const_lvalue<WriteHandler> handler2(handler);
1022 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
1023 write_dynbuf_v2_op<AsyncWriteStream,
1024 typename decay<DynamicBuffer_v2>::type,
1025 CompletionCondition, typename decay<WriteHandler>::type>(
1026 stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
1027 completion_cond2.value, handler2.value)(
1028 boost::system::error_code(), 0, 1);
1029 }
1030
1031 private:
1032 AsyncWriteStream& stream_;
1033 };
1034 } // namespace detail
1035
1036 #if !defined(GENERATING_DOCUMENTATION)
1037
1038 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
1039 typename CompletionCondition, typename WriteHandler, typename Allocator>
1040 struct associated_allocator<
1041 detail::write_dynbuf_v2_op<AsyncWriteStream,
1042 DynamicBuffer_v2, CompletionCondition, WriteHandler>,
1043 Allocator>
1044 {
1045 typedef typename associated_allocator<WriteHandler, Allocator>::type type;
1046
getboost::asio::associated_allocator1047 static type get(
1048 const detail::write_dynbuf_v2_op<AsyncWriteStream,
1049 DynamicBuffer_v2, CompletionCondition, WriteHandler>& h,
1050 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
1051 {
1052 return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
1053 }
1054 };
1055
1056 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
1057 typename CompletionCondition, typename WriteHandler, typename Executor>
1058 struct associated_executor<
1059 detail::write_dynbuf_v2_op<AsyncWriteStream,
1060 DynamicBuffer_v2, CompletionCondition, WriteHandler>,
1061 Executor>
1062 : detail::associated_executor_forwarding_base<WriteHandler, Executor>
1063 {
1064 typedef typename associated_executor<WriteHandler, Executor>::type type;
1065
getboost::asio::associated_executor1066 static type get(
1067 const detail::write_dynbuf_v2_op<AsyncWriteStream,
1068 DynamicBuffer_v2, CompletionCondition, WriteHandler>& h,
1069 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
1070 {
1071 return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
1072 }
1073 };
1074
1075 #endif // !defined(GENERATING_DOCUMENTATION)
1076
1077 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
1078 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1079 std::size_t)) WriteHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,void (boost::system::error_code,std::size_t))1080 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
1081 void (boost::system::error_code, std::size_t))
1082 async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
1083 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
1084 typename constraint<
1085 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1086 >::type)
1087 {
1088 return async_write(s,
1089 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
1090 transfer_all(), BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
1091 }
1092
1093 template <typename AsyncWriteStream,
1094 typename DynamicBuffer_v2, typename CompletionCondition,
1095 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1096 std::size_t)) WriteHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,void (boost::system::error_code,std::size_t))1097 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
1098 void (boost::system::error_code, std::size_t))
1099 async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
1100 CompletionCondition completion_condition,
1101 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
1102 typename constraint<
1103 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1104 >::type)
1105 {
1106 return async_initiate<WriteHandler,
1107 void (boost::system::error_code, std::size_t)>(
1108 detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>(s),
1109 handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
1110 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
1111 }
1112
1113 } // namespace asio
1114 } // namespace boost
1115
1116 #include <boost/asio/detail/pop_options.hpp>
1117
1118 #endif // BOOST_ASIO_IMPL_WRITE_HPP
1119