compose.hpp 22 KB

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