write.hpp 40 KB

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