compose.hpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. //
  2. // impl/compose.hpp
  3. // ~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_IMPL_COMPOSE_HPP
  11. #define BOOST_ASIO_IMPL_COMPOSE_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/config.hpp>
  16. #include <boost/asio/associated_executor.hpp>
  17. #include <boost/asio/detail/handler_alloc_helpers.hpp>
  18. #include <boost/asio/detail/handler_cont_helpers.hpp>
  19. #include <boost/asio/detail/handler_invoke_helpers.hpp>
  20. #include <boost/asio/detail/type_traits.hpp>
  21. #include <boost/asio/detail/variadic_templates.hpp>
  22. #include <boost/asio/execution/executor.hpp>
  23. #include <boost/asio/execution/outstanding_work.hpp>
  24. #include <boost/asio/executor_work_guard.hpp>
  25. #include <boost/asio/is_executor.hpp>
  26. #include <boost/asio/system_executor.hpp>
  27. #include <boost/asio/detail/push_options.hpp>
  28. namespace boost {
  29. namespace asio {
  30. namespace detail
  31. {
  32. template <typename Executor, typename = void>
  33. class composed_work_guard
  34. {
  35. public:
  36. typedef typename decay<
  37. typename prefer_result<Executor,
  38. execution::outstanding_work_t::tracked_t
  39. >::type
  40. >::type executor_type;
  41. composed_work_guard(const Executor& ex)
  42. : executor_(boost::asio::prefer(ex, execution::outstanding_work.tracked))
  43. {
  44. }
  45. void reset()
  46. {
  47. }
  48. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  49. {
  50. return executor_;
  51. }
  52. private:
  53. executor_type executor_;
  54. };
  55. #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
  56. template <typename Executor>
  57. struct composed_work_guard<Executor,
  58. typename enable_if<
  59. !execution::is_executor<Executor>::value
  60. >::type> : executor_work_guard<Executor>
  61. {
  62. composed_work_guard(const Executor& ex)
  63. : executor_work_guard<Executor>(ex)
  64. {
  65. }
  66. };
  67. #endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
  68. template <typename>
  69. struct composed_io_executors;
  70. template <>
  71. struct composed_io_executors<void()>
  72. {
  73. composed_io_executors() BOOST_ASIO_NOEXCEPT
  74. : head_(system_executor())
  75. {
  76. }
  77. typedef system_executor head_type;
  78. system_executor head_;
  79. };
  80. inline composed_io_executors<void()> make_composed_io_executors()
  81. {
  82. return composed_io_executors<void()>();
  83. }
  84. template <typename Head>
  85. struct composed_io_executors<void(Head)>
  86. {
  87. explicit composed_io_executors(const Head& ex) BOOST_ASIO_NOEXCEPT
  88. : head_(ex)
  89. {
  90. }
  91. typedef Head head_type;
  92. Head head_;
  93. };
  94. template <typename Head>
  95. inline composed_io_executors<void(Head)>
  96. make_composed_io_executors(const Head& head)
  97. {
  98. return composed_io_executors<void(Head)>(head);
  99. }
  100. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  101. template <typename Head, typename... Tail>
  102. struct composed_io_executors<void(Head, Tail...)>
  103. {
  104. explicit composed_io_executors(const Head& head,
  105. const Tail&... tail) BOOST_ASIO_NOEXCEPT
  106. : head_(head),
  107. tail_(tail...)
  108. {
  109. }
  110. void reset()
  111. {
  112. head_.reset();
  113. tail_.reset();
  114. }
  115. typedef Head head_type;
  116. Head head_;
  117. composed_io_executors<void(Tail...)> tail_;
  118. };
  119. template <typename Head, typename... Tail>
  120. inline composed_io_executors<void(Head, Tail...)>
  121. make_composed_io_executors(const Head& head, const Tail&... tail)
  122. {
  123. return composed_io_executors<void(Head, Tail...)>(head, tail...);
  124. }
  125. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  126. #define BOOST_ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF(n) \
  127. template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  128. struct composed_io_executors<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
  129. { \
  130. explicit composed_io_executors(const Head& head, \
  131. BOOST_ASIO_VARIADIC_CONSTREF_PARAMS(n)) BOOST_ASIO_NOEXCEPT \
  132. : head_(head), \
  133. tail_(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) \
  134. { \
  135. } \
  136. \
  137. void reset() \
  138. { \
  139. head_.reset(); \
  140. tail_.reset(); \
  141. } \
  142. \
  143. typedef Head head_type; \
  144. Head head_; \
  145. composed_io_executors<void(BOOST_ASIO_VARIADIC_TARGS(n))> tail_; \
  146. }; \
  147. \
  148. template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  149. inline composed_io_executors<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
  150. make_composed_io_executors(const Head& head, \
  151. BOOST_ASIO_VARIADIC_CONSTREF_PARAMS(n)) \
  152. { \
  153. return composed_io_executors< \
  154. void(Head, BOOST_ASIO_VARIADIC_TARGS(n))>( \
  155. head, BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)); \
  156. } \
  157. /**/
  158. BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF)
  159. #undef BOOST_ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF
  160. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  161. template <typename>
  162. struct composed_work;
  163. template <>
  164. struct composed_work<void()>
  165. {
  166. typedef composed_io_executors<void()> executors_type;
  167. composed_work(const executors_type&) BOOST_ASIO_NOEXCEPT
  168. : head_(system_executor())
  169. {
  170. }
  171. void reset()
  172. {
  173. head_.reset();
  174. }
  175. typedef system_executor head_type;
  176. composed_work_guard<system_executor> head_;
  177. };
  178. template <typename Head>
  179. struct composed_work<void(Head)>
  180. {
  181. typedef composed_io_executors<void(Head)> executors_type;
  182. explicit composed_work(const executors_type& ex) BOOST_ASIO_NOEXCEPT
  183. : head_(ex.head_)
  184. {
  185. }
  186. void reset()
  187. {
  188. head_.reset();
  189. }
  190. typedef Head head_type;
  191. composed_work_guard<Head> head_;
  192. };
  193. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  194. template <typename Head, typename... Tail>
  195. struct composed_work<void(Head, Tail...)>
  196. {
  197. typedef composed_io_executors<void(Head, Tail...)> executors_type;
  198. explicit composed_work(const executors_type& ex) BOOST_ASIO_NOEXCEPT
  199. : head_(ex.head_),
  200. tail_(ex.tail_)
  201. {
  202. }
  203. void reset()
  204. {
  205. head_.reset();
  206. tail_.reset();
  207. }
  208. typedef Head head_type;
  209. composed_work_guard<Head> head_;
  210. composed_work<void(Tail...)> tail_;
  211. };
  212. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  213. #define BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF(n) \
  214. template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  215. struct composed_work<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
  216. { \
  217. typedef composed_io_executors<void(Head, \
  218. BOOST_ASIO_VARIADIC_TARGS(n))> executors_type; \
  219. \
  220. explicit composed_work(const executors_type& ex) BOOST_ASIO_NOEXCEPT \
  221. : head_(ex.head_), \
  222. tail_(ex.tail_) \
  223. { \
  224. } \
  225. \
  226. void reset() \
  227. { \
  228. head_.reset(); \
  229. tail_.reset(); \
  230. } \
  231. \
  232. typedef Head head_type; \
  233. composed_work_guard<Head> head_; \
  234. composed_work<void(BOOST_ASIO_VARIADIC_TARGS(n))> tail_; \
  235. }; \
  236. /**/
  237. BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF)
  238. #undef BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF
  239. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  240. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  241. template <typename Impl, typename Work, typename Handler, typename Signature>
  242. class composed_op;
  243. template <typename Impl, typename Work, typename Handler,
  244. typename R, typename... Args>
  245. class composed_op<Impl, Work, Handler, R(Args...)>
  246. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  247. template <typename Impl, typename Work, typename Handler, typename Signature>
  248. class composed_op
  249. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  250. {
  251. public:
  252. template <typename I, typename W, typename H>
  253. composed_op(BOOST_ASIO_MOVE_ARG(I) impl,
  254. BOOST_ASIO_MOVE_ARG(W) work,
  255. BOOST_ASIO_MOVE_ARG(H) handler)
  256. : impl_(BOOST_ASIO_MOVE_CAST(I)(impl)),
  257. work_(BOOST_ASIO_MOVE_CAST(W)(work)),
  258. handler_(BOOST_ASIO_MOVE_CAST(H)(handler)),
  259. invocations_(0)
  260. {
  261. }
  262. #if defined(BOOST_ASIO_HAS_MOVE)
  263. composed_op(composed_op&& other)
  264. : impl_(BOOST_ASIO_MOVE_CAST(Impl)(other.impl_)),
  265. work_(BOOST_ASIO_MOVE_CAST(Work)(other.work_)),
  266. handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
  267. invocations_(other.invocations_)
  268. {
  269. }
  270. #endif // defined(BOOST_ASIO_HAS_MOVE)
  271. typedef typename associated_executor<Handler,
  272. typename composed_work_guard<
  273. typename Work::head_type
  274. >::executor_type
  275. >::type executor_type;
  276. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  277. {
  278. return (get_associated_executor)(handler_, work_.head_.get_executor());
  279. }
  280. typedef typename associated_allocator<Handler,
  281. std::allocator<void> >::type allocator_type;
  282. allocator_type get_allocator() const BOOST_ASIO_NOEXCEPT
  283. {
  284. return (get_associated_allocator)(handler_, std::allocator<void>());
  285. }
  286. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  287. template<typename... T>
  288. void operator()(BOOST_ASIO_MOVE_ARG(T)... t)
  289. {
  290. if (invocations_ < ~0u)
  291. ++invocations_;
  292. impl_(*this, BOOST_ASIO_MOVE_CAST(T)(t)...);
  293. }
  294. void complete(Args... args)
  295. {
  296. this->work_.reset();
  297. this->handler_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
  298. }
  299. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  300. void operator()()
  301. {
  302. if (invocations_ < ~0u)
  303. ++invocations_;
  304. impl_(*this);
  305. }
  306. void complete()
  307. {
  308. this->work_.reset();
  309. this->handler_();
  310. }
  311. #define BOOST_ASIO_PRIVATE_COMPOSED_OP_DEF(n) \
  312. template<BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  313. void operator()(BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
  314. { \
  315. if (invocations_ < ~0u) \
  316. ++invocations_; \
  317. impl_(*this, BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
  318. } \
  319. \
  320. template<BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  321. void complete(BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
  322. { \
  323. this->work_.reset(); \
  324. this->handler_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
  325. } \
  326. /**/
  327. BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPOSED_OP_DEF)
  328. #undef BOOST_ASIO_PRIVATE_COMPOSED_OP_DEF
  329. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  330. //private:
  331. Impl impl_;
  332. Work work_;
  333. Handler handler_;
  334. unsigned invocations_;
  335. };
  336. template <typename Impl, typename Work, typename Handler, typename Signature>
  337. inline asio_handler_allocate_is_deprecated
  338. asio_handler_allocate(std::size_t size,
  339. composed_op<Impl, Work, Handler, Signature>* this_handler)
  340. {
  341. #if defined(BOOST_ASIO_NO_DEPRECATED)
  342. boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
  343. return asio_handler_allocate_is_no_longer_used();
  344. #else // defined(BOOST_ASIO_NO_DEPRECATED)
  345. return boost_asio_handler_alloc_helpers::allocate(
  346. size, this_handler->handler_);
  347. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  348. }
  349. template <typename Impl, typename Work, typename Handler, typename Signature>
  350. inline asio_handler_deallocate_is_deprecated
  351. asio_handler_deallocate(void* pointer, std::size_t size,
  352. composed_op<Impl, Work, Handler, Signature>* this_handler)
  353. {
  354. boost_asio_handler_alloc_helpers::deallocate(
  355. pointer, size, this_handler->handler_);
  356. #if defined(BOOST_ASIO_NO_DEPRECATED)
  357. return asio_handler_deallocate_is_no_longer_used();
  358. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  359. }
  360. template <typename Impl, typename Work, typename Handler, typename Signature>
  361. inline bool asio_handler_is_continuation(
  362. composed_op<Impl, Work, Handler, Signature>* this_handler)
  363. {
  364. return this_handler->invocations_ > 1 ? true
  365. : boost_asio_handler_cont_helpers::is_continuation(
  366. this_handler->handler_);
  367. }
  368. template <typename Function, typename Impl,
  369. typename Work, typename Handler, typename Signature>
  370. inline asio_handler_invoke_is_deprecated
  371. asio_handler_invoke(Function& function,
  372. composed_op<Impl, Work, Handler, Signature>* this_handler)
  373. {
  374. boost_asio_handler_invoke_helpers::invoke(
  375. function, this_handler->handler_);
  376. #if defined(BOOST_ASIO_NO_DEPRECATED)
  377. return asio_handler_invoke_is_no_longer_used();
  378. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  379. }
  380. template <typename Function, typename Impl,
  381. typename Work, typename Handler, typename Signature>
  382. inline asio_handler_invoke_is_deprecated
  383. asio_handler_invoke(const Function& function,
  384. composed_op<Impl, Work, Handler, Signature>* this_handler)
  385. {
  386. boost_asio_handler_invoke_helpers::invoke(
  387. function, this_handler->handler_);
  388. #if defined(BOOST_ASIO_NO_DEPRECATED)
  389. return asio_handler_invoke_is_no_longer_used();
  390. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  391. }
  392. template <typename Signature, typename Executors>
  393. class initiate_composed_op
  394. {
  395. public:
  396. typedef typename composed_io_executors<Executors>::head_type executor_type;
  397. template <typename T>
  398. explicit initiate_composed_op(int, BOOST_ASIO_MOVE_ARG(T) executors)
  399. : executors_(BOOST_ASIO_MOVE_CAST(T)(executors))
  400. {
  401. }
  402. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  403. {
  404. return executors_.head_;
  405. }
  406. template <typename Handler, typename Impl>
  407. void operator()(BOOST_ASIO_MOVE_ARG(Handler) handler,
  408. BOOST_ASIO_MOVE_ARG(Impl) impl) const
  409. {
  410. composed_op<typename decay<Impl>::type, composed_work<Executors>,
  411. typename decay<Handler>::type, Signature>(
  412. BOOST_ASIO_MOVE_CAST(Impl)(impl),
  413. composed_work<Executors>(executors_),
  414. BOOST_ASIO_MOVE_CAST(Handler)(handler))();
  415. }
  416. private:
  417. composed_io_executors<Executors> executors_;
  418. };
  419. template <typename Signature, typename Executors>
  420. inline initiate_composed_op<Signature, Executors> make_initiate_composed_op(
  421. BOOST_ASIO_MOVE_ARG(composed_io_executors<Executors>) executors)
  422. {
  423. return initiate_composed_op<Signature, Executors>(0,
  424. BOOST_ASIO_MOVE_CAST(composed_io_executors<Executors>)(executors));
  425. }
  426. template <typename IoObject>
  427. inline typename IoObject::executor_type
  428. get_composed_io_executor(IoObject& io_object,
  429. typename enable_if<
  430. !is_executor<IoObject>::value
  431. >::type* = 0,
  432. typename enable_if<
  433. !execution::is_executor<IoObject>::value
  434. >::type* = 0)
  435. {
  436. return io_object.get_executor();
  437. }
  438. template <typename Executor>
  439. inline const Executor& get_composed_io_executor(const Executor& ex,
  440. typename enable_if<
  441. is_executor<Executor>::value
  442. || execution::is_executor<Executor>::value
  443. >::type* = 0)
  444. {
  445. return ex;
  446. }
  447. } // namespace detail
  448. #if !defined(GENERATING_DOCUMENTATION)
  449. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  450. template <typename CompletionToken, typename Signature,
  451. typename Implementation, typename... IoObjectsOrExecutors>
  452. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature)
  453. async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
  454. BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
  455. BOOST_ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors)
  456. {
  457. return async_initiate<CompletionToken, Signature>(
  458. detail::make_initiate_composed_op<Signature>(
  459. detail::make_composed_io_executors(
  460. detail::get_composed_io_executor(
  461. BOOST_ASIO_MOVE_CAST(IoObjectsOrExecutors)(
  462. io_objects_or_executors))...)),
  463. token, BOOST_ASIO_MOVE_CAST(Implementation)(implementation));
  464. }
  465. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  466. template <typename CompletionToken, typename Signature, typename Implementation>
  467. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature)
  468. async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
  469. BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
  470. {
  471. return async_initiate<CompletionToken, Signature>(
  472. detail::make_initiate_composed_op<Signature>(
  473. detail::make_composed_io_executors()),
  474. token, BOOST_ASIO_MOVE_CAST(Implementation)(implementation));
  475. }
  476. # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n) \
  477. BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_##n
  478. # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_1 \
  479. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1))
  480. # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_2 \
  481. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
  482. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2))
  483. # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_3 \
  484. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
  485. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
  486. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3))
  487. # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_4 \
  488. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
  489. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
  490. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3)), \
  491. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T4)(x4))
  492. # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_5 \
  493. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
  494. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
  495. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3)), \
  496. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T4)(x4)), \
  497. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T5)(x5))
  498. # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_6 \
  499. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
  500. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
  501. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3)), \
  502. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T4)(x4)), \
  503. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T5)(x5)), \
  504. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T6)(x6))
  505. # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_7 \
  506. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
  507. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
  508. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3)), \
  509. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T4)(x4)), \
  510. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T5)(x5)), \
  511. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T6)(x6)), \
  512. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T7)(x7))
  513. # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_8 \
  514. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
  515. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
  516. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3)), \
  517. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T4)(x4)), \
  518. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T5)(x5)), \
  519. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T6)(x6)), \
  520. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T7)(x7)), \
  521. detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T8)(x8))
  522. #define BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \
  523. template <typename CompletionToken, typename Signature, \
  524. typename Implementation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  525. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature) \
  526. async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation, \
  527. BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
  528. BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
  529. { \
  530. return async_initiate<CompletionToken, Signature>( \
  531. detail::make_initiate_composed_op<Signature>( \
  532. detail::make_composed_io_executors( \
  533. BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n))), \
  534. token, BOOST_ASIO_MOVE_CAST(Implementation)(implementation)); \
  535. } \
  536. /**/
  537. BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF)
  538. #undef BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF
  539. #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR
  540. #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_1
  541. #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_2
  542. #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_3
  543. #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_4
  544. #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_5
  545. #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_6
  546. #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_7
  547. #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_8
  548. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  549. #endif // !defined(GENERATING_DOCUMENTATION)
  550. } // namespace asio
  551. } // namespace boost
  552. #include <boost/asio/detail/pop_options.hpp>
  553. #endif // BOOST_ASIO_IMPL_COMPOSE_HPP