write.hpp 43 KB

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