• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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