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