async_result.hpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272
  1. //
  2. // async_result.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 ASIO_ASYNC_RESULT_HPP
  11. #define ASIO_ASYNC_RESULT_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include "asio/detail/type_traits.hpp"
  17. #include "asio/detail/variadic_templates.hpp"
  18. #include "asio/detail/push_options.hpp"
  19. namespace asio {
  20. #if defined(ASIO_HAS_CONCEPTS) \
  21. && defined(ASIO_HAS_VARIADIC_TEMPLATES) \
  22. && defined(ASIO_HAS_DECLTYPE)
  23. namespace detail {
  24. template <typename T>
  25. struct is_completion_signature : false_type
  26. {
  27. };
  28. template <typename R, typename... Args>
  29. struct is_completion_signature<R(Args...)> : true_type
  30. {
  31. };
  32. #if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
  33. template <typename R, typename... Args>
  34. struct is_completion_signature<R(Args...) &> : true_type
  35. {
  36. };
  37. template <typename R, typename... Args>
  38. struct is_completion_signature<R(Args...) &&> : true_type
  39. {
  40. };
  41. # if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  42. template <typename R, typename... Args>
  43. struct is_completion_signature<R(Args...) noexcept> : true_type
  44. {
  45. };
  46. template <typename R, typename... Args>
  47. struct is_completion_signature<R(Args...) & noexcept> : true_type
  48. {
  49. };
  50. template <typename R, typename... Args>
  51. struct is_completion_signature<R(Args...) && noexcept> : true_type
  52. {
  53. };
  54. # endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  55. #endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
  56. template <typename... T>
  57. struct are_completion_signatures : false_type
  58. {
  59. };
  60. template <typename T0>
  61. struct are_completion_signatures<T0>
  62. : is_completion_signature<T0>
  63. {
  64. };
  65. template <typename T0, typename... TN>
  66. struct are_completion_signatures<T0, TN...>
  67. : integral_constant<bool, (
  68. is_completion_signature<T0>::value
  69. && are_completion_signatures<TN...>::value)>
  70. {
  71. };
  72. template <typename T, typename... Args>
  73. ASIO_CONCEPT callable_with = requires(T&& t, Args&&... args)
  74. {
  75. static_cast<T&&>(t)(static_cast<Args&&>(args)...);
  76. };
  77. template <typename T, typename... Signatures>
  78. struct is_completion_handler_for : false_type
  79. {
  80. };
  81. template <typename T, typename R, typename... Args>
  82. struct is_completion_handler_for<T, R(Args...)>
  83. : integral_constant<bool, (callable_with<T, Args...>)>
  84. {
  85. };
  86. #if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
  87. template <typename T, typename R, typename... Args>
  88. struct is_completion_handler_for<T, R(Args...) &>
  89. : integral_constant<bool, (callable_with<T&, Args...>)>
  90. {
  91. };
  92. template <typename T, typename R, typename... Args>
  93. struct is_completion_handler_for<T, R(Args...) &&>
  94. : integral_constant<bool, (callable_with<T&&, Args...>)>
  95. {
  96. };
  97. # if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  98. template <typename T, typename R, typename... Args>
  99. struct is_completion_handler_for<T, R(Args...) noexcept>
  100. : integral_constant<bool, (callable_with<T, Args...>)>
  101. {
  102. };
  103. template <typename T, typename R, typename... Args>
  104. struct is_completion_handler_for<T, R(Args...) & noexcept>
  105. : integral_constant<bool, (callable_with<T&, Args...>)>
  106. {
  107. };
  108. template <typename T, typename R, typename... Args>
  109. struct is_completion_handler_for<T, R(Args...) && noexcept>
  110. : integral_constant<bool, (callable_with<T&&, Args...>)>
  111. {
  112. };
  113. # endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  114. #endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
  115. template <typename T, typename Signature0, typename... SignatureN>
  116. struct is_completion_handler_for<T, Signature0, SignatureN...>
  117. : integral_constant<bool, (
  118. is_completion_handler_for<T, Signature0>::value
  119. && is_completion_handler_for<T, SignatureN...>::value)>
  120. {
  121. };
  122. } // namespace detail
  123. template <typename T>
  124. ASIO_CONCEPT completion_signature =
  125. detail::is_completion_signature<T>::value;
  126. #define ASIO_COMPLETION_SIGNATURE \
  127. ::asio::completion_signature
  128. template <typename T, typename... Signatures>
  129. ASIO_CONCEPT completion_handler_for =
  130. detail::are_completion_signatures<Signatures...>::value
  131. && detail::is_completion_handler_for<T, Signatures...>::value;
  132. #define ASIO_COMPLETION_HANDLER_FOR(sig) \
  133. ::asio::completion_handler_for<sig>
  134. #define ASIO_COMPLETION_HANDLER_FOR2(sig0, sig1) \
  135. ::asio::completion_handler_for<sig0, sig1>
  136. #define ASIO_COMPLETION_HANDLER_FOR3(sig0, sig1, sig2) \
  137. ::asio::completion_handler_for<sig0, sig1, sig2>
  138. #else // defined(ASIO_HAS_CONCEPTS)
  139. // && defined(ASIO_HAS_VARIADIC_TEMPLATES)
  140. // && defined(ASIO_HAS_DECLTYPE)
  141. #define ASIO_COMPLETION_SIGNATURE typename
  142. #define ASIO_COMPLETION_HANDLER_FOR(sig) typename
  143. #define ASIO_COMPLETION_HANDLER_FOR2(sig0, sig1) typename
  144. #define ASIO_COMPLETION_HANDLER_FOR3(sig0, sig1, sig2) typename
  145. #endif // defined(ASIO_HAS_CONCEPTS)
  146. // && defined(ASIO_HAS_VARIADIC_TEMPLATES)
  147. // && defined(ASIO_HAS_DECLTYPE)
  148. namespace detail {
  149. template <typename T>
  150. struct is_simple_completion_signature : false_type
  151. {
  152. };
  153. template <typename T>
  154. struct simple_completion_signature;
  155. #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
  156. template <typename R, typename... Args>
  157. struct is_simple_completion_signature<R(Args...)> : true_type
  158. {
  159. };
  160. template <typename... Signatures>
  161. struct are_simple_completion_signatures : false_type
  162. {
  163. };
  164. template <typename Sig0>
  165. struct are_simple_completion_signatures<Sig0>
  166. : is_simple_completion_signature<Sig0>
  167. {
  168. };
  169. template <typename Sig0, typename... SigN>
  170. struct are_simple_completion_signatures<Sig0, SigN...>
  171. : integral_constant<bool, (
  172. is_simple_completion_signature<Sig0>::value
  173. && are_simple_completion_signatures<SigN...>::value)>
  174. {
  175. };
  176. template <typename R, typename... Args>
  177. struct simple_completion_signature<R(Args...)>
  178. {
  179. typedef R type(Args...);
  180. };
  181. #if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
  182. template <typename R, typename... Args>
  183. struct simple_completion_signature<R(Args...) &>
  184. {
  185. typedef R type(Args...);
  186. };
  187. template <typename R, typename... Args>
  188. struct simple_completion_signature<R(Args...) &&>
  189. {
  190. typedef R type(Args...);
  191. };
  192. # if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  193. template <typename R, typename... Args>
  194. struct simple_completion_signature<R(Args...) noexcept>
  195. {
  196. typedef R type(Args...);
  197. };
  198. template <typename R, typename... Args>
  199. struct simple_completion_signature<R(Args...) & noexcept>
  200. {
  201. typedef R type(Args...);
  202. };
  203. template <typename R, typename... Args>
  204. struct simple_completion_signature<R(Args...) && noexcept>
  205. {
  206. typedef R type(Args...);
  207. };
  208. # endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  209. #endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
  210. #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  211. template <typename R>
  212. struct is_simple_completion_signature<R()> : true_type
  213. {
  214. };
  215. #define ASIO_PRIVATE_SIMPLE_SIG_DEF(n) \
  216. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  217. struct is_simple_completion_signature<R(ASIO_VARIADIC_TARGS(n))> \
  218. : true_type \
  219. { \
  220. }; \
  221. /**/
  222. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SIMPLE_SIG_DEF)
  223. #undef ASIO_PRIVATE_SIMPLE_SIG_DEF
  224. template <typename Sig0 = void, typename Sig1 = void,
  225. typename Sig2 = void, typename = void>
  226. struct are_simple_completion_signatures : false_type
  227. {
  228. };
  229. template <typename Sig0>
  230. struct are_simple_completion_signatures<Sig0>
  231. : is_simple_completion_signature<Sig0>
  232. {
  233. };
  234. template <typename Sig0, typename Sig1>
  235. struct are_simple_completion_signatures<Sig0, Sig1>
  236. : integral_constant<bool,
  237. (is_simple_completion_signature<Sig0>::value
  238. && is_simple_completion_signature<Sig1>::value)>
  239. {
  240. };
  241. template <typename Sig0, typename Sig1, typename Sig2>
  242. struct are_simple_completion_signatures<Sig0, Sig1, Sig2>
  243. : integral_constant<bool,
  244. (is_simple_completion_signature<Sig0>::value
  245. && is_simple_completion_signature<Sig1>::value
  246. && is_simple_completion_signature<Sig2>::value)>
  247. {
  248. };
  249. template <>
  250. struct simple_completion_signature<void>
  251. {
  252. typedef void type;
  253. };
  254. template <typename R>
  255. struct simple_completion_signature<R()>
  256. {
  257. typedef R type();
  258. };
  259. #define ASIO_PRIVATE_SIMPLE_SIG_DEF(n) \
  260. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  261. struct simple_completion_signature<R(ASIO_VARIADIC_TARGS(n))> \
  262. { \
  263. typedef R type(ASIO_VARIADIC_TARGS(n)); \
  264. }; \
  265. /**/
  266. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SIMPLE_SIG_DEF)
  267. #undef ASIO_PRIVATE_SIMPLE_SIG_DEF
  268. #if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
  269. template <typename R>
  270. struct simple_completion_signature<R() &>
  271. {
  272. typedef R type();
  273. };
  274. template <typename R>
  275. struct simple_completion_signature<R() &&>
  276. {
  277. typedef R type();
  278. };
  279. #define ASIO_PRIVATE_SIMPLE_SIG_DEF(n) \
  280. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  281. struct simple_completion_signature< \
  282. R(ASIO_VARIADIC_TARGS(n)) &> \
  283. { \
  284. typedef R type(ASIO_VARIADIC_TARGS(n)); \
  285. }; \
  286. \
  287. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  288. struct simple_completion_signature< \
  289. R(ASIO_VARIADIC_TARGS(n)) &&> \
  290. { \
  291. typedef R type(ASIO_VARIADIC_TARGS(n)); \
  292. }; \
  293. /**/
  294. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SIMPLE_SIG_DEF)
  295. #undef ASIO_PRIVATE_SIMPLE_SIG_DEF
  296. # if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  297. template <typename R>
  298. struct simple_completion_signature<R() noexcept>
  299. {
  300. typedef R type();
  301. };
  302. template <typename R>
  303. struct simple_completion_signature<R() & noexcept>
  304. {
  305. typedef R type();
  306. };
  307. template <typename R>
  308. struct simple_completion_signature<R() && noexcept>
  309. {
  310. typedef R type();
  311. };
  312. #define ASIO_PRIVATE_SIMPLE_SIG_DEF(n) \
  313. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  314. struct simple_completion_signature< \
  315. R(ASIO_VARIADIC_TARGS(n)) noexcept> \
  316. { \
  317. typedef R type(ASIO_VARIADIC_TARGS(n)); \
  318. }; \
  319. \
  320. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  321. struct simple_completion_signature< \
  322. R(ASIO_VARIADIC_TARGS(n)) & noexcept> \
  323. { \
  324. typedef R type(ASIO_VARIADIC_TARGS(n)); \
  325. }; \
  326. \
  327. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  328. struct simple_completion_signature< \
  329. R(ASIO_VARIADIC_TARGS(n)) && noexcept> \
  330. { \
  331. typedef R type(ASIO_VARIADIC_TARGS(n)); \
  332. }; \
  333. /**/
  334. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SIMPLE_SIG_DEF)
  335. #undef ASIO_PRIVATE_SIMPLE_SIG_DEF
  336. # endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  337. #endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
  338. #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  339. #if defined(ASIO_HAS_VARIADIC_TEMPLATES) \
  340. || defined(GENERATING_DOCUMENTATION)
  341. # define ASIO_COMPLETION_SIGNATURES_TPARAMS \
  342. ASIO_COMPLETION_SIGNATURE... Signatures
  343. # define ASIO_COMPLETION_SIGNATURES_TSPECPARAMS \
  344. ASIO_COMPLETION_SIGNATURE... Signatures
  345. # define ASIO_COMPLETION_SIGNATURES_TARGS Signatures...
  346. # define ASIO_COMPLETION_SIGNATURES_TSIMPLEARGS \
  347. typename asio::detail::simple_completion_signature< \
  348. Signatures>::type...
  349. #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  350. // || defined(GENERATING_DOCUMENTATION)
  351. # define ASIO_COMPLETION_SIGNATURES_TPARAMS \
  352. typename Sig0 = void, \
  353. typename Sig1 = void, \
  354. typename Sig2 = void
  355. # define ASIO_COMPLETION_SIGNATURES_TSPECPARAMS \
  356. typename Sig0, \
  357. typename Sig1, \
  358. typename Sig2
  359. # define ASIO_COMPLETION_SIGNATURES_TARGS Sig0, Sig1, Sig2
  360. # define ASIO_COMPLETION_SIGNATURES_TSIMPLEARGS \
  361. typename ::asio::detail::simple_completion_signature<Sig0>::type, \
  362. typename ::asio::detail::simple_completion_signature<Sig1>::type, \
  363. typename ::asio::detail::simple_completion_signature<Sig2>::type
  364. #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  365. // || defined(GENERATING_DOCUMENTATION)
  366. template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>
  367. class completion_handler_async_result
  368. {
  369. public:
  370. typedef CompletionToken completion_handler_type;
  371. typedef void return_type;
  372. explicit completion_handler_async_result(completion_handler_type&)
  373. {
  374. }
  375. return_type get()
  376. {
  377. }
  378. #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
  379. template <typename Initiation,
  380. ASIO_COMPLETION_HANDLER_FOR(Signatures...) RawCompletionToken,
  381. typename... Args>
  382. static return_type initiate(
  383. ASIO_MOVE_ARG(Initiation) initiation,
  384. ASIO_MOVE_ARG(RawCompletionToken) token,
  385. ASIO_MOVE_ARG(Args)... args)
  386. {
  387. ASIO_MOVE_CAST(Initiation)(initiation)(
  388. ASIO_MOVE_CAST(RawCompletionToken)(token),
  389. ASIO_MOVE_CAST(Args)(args)...);
  390. }
  391. #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  392. template <typename Initiation, typename RawCompletionToken>
  393. static return_type initiate(
  394. ASIO_MOVE_ARG(Initiation) initiation,
  395. ASIO_MOVE_ARG(RawCompletionToken) token)
  396. {
  397. ASIO_MOVE_CAST(Initiation)(initiation)(
  398. ASIO_MOVE_CAST(RawCompletionToken)(token));
  399. }
  400. #define ASIO_PRIVATE_INITIATE_DEF(n) \
  401. template <typename Initiation, \
  402. typename RawCompletionToken, \
  403. ASIO_VARIADIC_TPARAMS(n)> \
  404. static return_type initiate( \
  405. ASIO_MOVE_ARG(Initiation) initiation, \
  406. ASIO_MOVE_ARG(RawCompletionToken) token, \
  407. ASIO_VARIADIC_MOVE_PARAMS(n)) \
  408. { \
  409. ASIO_MOVE_CAST(Initiation)(initiation)( \
  410. ASIO_MOVE_CAST(RawCompletionToken)(token), \
  411. ASIO_VARIADIC_MOVE_ARGS(n)); \
  412. } \
  413. /**/
  414. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)
  415. #undef ASIO_PRIVATE_INITIATE_DEF
  416. #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  417. private:
  418. completion_handler_async_result(
  419. const completion_handler_async_result&) ASIO_DELETED;
  420. completion_handler_async_result& operator=(
  421. const completion_handler_async_result&) ASIO_DELETED;
  422. };
  423. } // namespace detail
  424. #if defined(GENERATING_DOCUMENTATION)
  425. /// An interface for customising the behaviour of an initiating function.
  426. /**
  427. * The async_result traits class is used for determining:
  428. *
  429. * @li the concrete completion handler type to be called at the end of the
  430. * asynchronous operation;
  431. *
  432. * @li the initiating function return type; and
  433. *
  434. * @li how the return value of the initiating function is obtained.
  435. *
  436. * The trait allows the handler and return types to be determined at the point
  437. * where the specific completion handler signature is known.
  438. *
  439. * This template may be specialised for user-defined completion token types.
  440. * The primary template assumes that the CompletionToken is the completion
  441. * handler.
  442. */
  443. template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>
  444. class async_result
  445. {
  446. public:
  447. /// The concrete completion handler type for the specific signature.
  448. typedef CompletionToken completion_handler_type;
  449. /// The return type of the initiating function.
  450. typedef void return_type;
  451. /// Construct an async result from a given handler.
  452. /**
  453. * When using a specalised async_result, the constructor has an opportunity
  454. * to initialise some state associated with the completion handler, which is
  455. * then returned from the initiating function.
  456. */
  457. explicit async_result(completion_handler_type& h);
  458. /// Obtain the value to be returned from the initiating function.
  459. return_type get();
  460. /// Initiate the asynchronous operation that will produce the result, and
  461. /// obtain the value to be returned from the initiating function.
  462. template <typename Initiation, typename RawCompletionToken, typename... Args>
  463. static return_type initiate(
  464. ASIO_MOVE_ARG(Initiation) initiation,
  465. ASIO_MOVE_ARG(RawCompletionToken) token,
  466. ASIO_MOVE_ARG(Args)... args);
  467. private:
  468. async_result(const async_result&) ASIO_DELETED;
  469. async_result& operator=(const async_result&) ASIO_DELETED;
  470. };
  471. #else // defined(GENERATING_DOCUMENTATION)
  472. #if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
  473. template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>
  474. class async_result :
  475. public conditional<
  476. detail::are_simple_completion_signatures<
  477. ASIO_COMPLETION_SIGNATURES_TARGS>::value,
  478. detail::completion_handler_async_result<
  479. CompletionToken, ASIO_COMPLETION_SIGNATURES_TARGS>,
  480. async_result<CompletionToken,
  481. ASIO_COMPLETION_SIGNATURES_TSIMPLEARGS>
  482. >::type
  483. {
  484. public:
  485. typedef typename conditional<
  486. detail::are_simple_completion_signatures<
  487. ASIO_COMPLETION_SIGNATURES_TARGS>::value,
  488. detail::completion_handler_async_result<
  489. CompletionToken, ASIO_COMPLETION_SIGNATURES_TARGS>,
  490. async_result<CompletionToken,
  491. ASIO_COMPLETION_SIGNATURES_TSIMPLEARGS>
  492. >::type base_type;
  493. using base_type::base_type;
  494. private:
  495. async_result(const async_result&) ASIO_DELETED;
  496. async_result& operator=(const async_result&) ASIO_DELETED;
  497. };
  498. #else // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
  499. template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>
  500. class async_result :
  501. public detail::completion_handler_async_result<
  502. CompletionToken, ASIO_COMPLETION_SIGNATURES_TARGS>
  503. {
  504. public:
  505. explicit async_result(CompletionToken& h)
  506. : detail::completion_handler_async_result<
  507. CompletionToken, ASIO_COMPLETION_SIGNATURES_TARGS>(h)
  508. {
  509. }
  510. private:
  511. async_result(const async_result&) ASIO_DELETED;
  512. async_result& operator=(const async_result&) ASIO_DELETED;
  513. };
  514. #endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
  515. template <ASIO_COMPLETION_SIGNATURES_TSPECPARAMS>
  516. class async_result<void, ASIO_COMPLETION_SIGNATURES_TARGS>
  517. {
  518. // Empty.
  519. };
  520. #endif // defined(GENERATING_DOCUMENTATION)
  521. /// Helper template to deduce the handler type from a CompletionToken, capture
  522. /// a local copy of the handler, and then create an async_result for the
  523. /// handler.
  524. template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>
  525. struct async_completion
  526. {
  527. /// The real handler type to be used for the asynchronous operation.
  528. typedef typename asio::async_result<
  529. typename decay<CompletionToken>::type,
  530. ASIO_COMPLETION_SIGNATURES_TARGS>::completion_handler_type
  531. completion_handler_type;
  532. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  533. /// Constructor.
  534. /**
  535. * The constructor creates the concrete completion handler and makes the link
  536. * between the handler and the asynchronous result.
  537. */
  538. explicit async_completion(CompletionToken& token)
  539. : completion_handler(static_cast<typename conditional<
  540. is_same<CompletionToken, completion_handler_type>::value,
  541. completion_handler_type&, CompletionToken&&>::type>(token)),
  542. result(completion_handler)
  543. {
  544. }
  545. #else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  546. explicit async_completion(typename decay<CompletionToken>::type& token)
  547. : completion_handler(token),
  548. result(completion_handler)
  549. {
  550. }
  551. explicit async_completion(const typename decay<CompletionToken>::type& token)
  552. : completion_handler(token),
  553. result(completion_handler)
  554. {
  555. }
  556. #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  557. /// A copy of, or reference to, a real handler object.
  558. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  559. typename conditional<
  560. is_same<CompletionToken, completion_handler_type>::value,
  561. completion_handler_type&, completion_handler_type>::type completion_handler;
  562. #else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  563. completion_handler_type completion_handler;
  564. #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  565. /// The result of the asynchronous operation's initiating function.
  566. async_result<typename decay<CompletionToken>::type,
  567. ASIO_COMPLETION_SIGNATURES_TARGS> result;
  568. };
  569. namespace detail {
  570. template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>
  571. struct async_result_helper
  572. : async_result<typename decay<CompletionToken>::type,
  573. ASIO_COMPLETION_SIGNATURES_TARGS>
  574. {
  575. };
  576. struct async_result_memfns_base
  577. {
  578. void initiate();
  579. };
  580. template <typename T>
  581. struct async_result_memfns_derived
  582. : T, async_result_memfns_base
  583. {
  584. };
  585. template <typename T, T>
  586. struct async_result_memfns_check
  587. {
  588. };
  589. template <typename>
  590. char (&async_result_initiate_memfn_helper(...))[2];
  591. template <typename T>
  592. char async_result_initiate_memfn_helper(
  593. async_result_memfns_check<
  594. void (async_result_memfns_base::*)(),
  595. &async_result_memfns_derived<T>::initiate>*);
  596. template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>
  597. struct async_result_has_initiate_memfn
  598. : integral_constant<bool, sizeof(async_result_initiate_memfn_helper<
  599. async_result<typename decay<CompletionToken>::type,
  600. ASIO_COMPLETION_SIGNATURES_TARGS>
  601. >(0)) != 1>
  602. {
  603. };
  604. } // namespace detail
  605. #if defined(GENERATING_DOCUMENTATION)
  606. # define ASIO_INITFN_RESULT_TYPE(ct, sig) \
  607. void_or_deduced
  608. # define ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \
  609. void_or_deduced
  610. # define ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \
  611. void_or_deduced
  612. #elif defined(_MSC_VER) && (_MSC_VER < 1500)
  613. # define ASIO_INITFN_RESULT_TYPE(ct, sig) \
  614. typename ::asio::detail::async_result_helper< \
  615. ct, sig>::return_type
  616. # define ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \
  617. typename ::asio::detail::async_result_helper< \
  618. ct, sig0, sig1>::return_type
  619. # define ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \
  620. typename ::asio::detail::async_result_helper< \
  621. ct, sig0, sig1, sig2>::return_type
  622. #define ASIO_HANDLER_TYPE(ct, sig) \
  623. typename ::asio::detail::async_result_helper< \
  624. ct, sig>::completion_handler_type
  625. #define ASIO_HANDLER_TYPE2(ct, sig0, sig1) \
  626. typename ::asio::detail::async_result_helper< \
  627. ct, sig0, sig1>::completion_handler_type
  628. #define ASIO_HANDLER_TYPE3(ct, sig0, sig1, sig2) \
  629. typename ::asio::detail::async_result_helper< \
  630. ct, sig0, sig1, sig2>::completion_handler_type
  631. #else
  632. # define ASIO_INITFN_RESULT_TYPE(ct, sig) \
  633. typename ::asio::async_result< \
  634. typename ::asio::decay<ct>::type, sig>::return_type
  635. # define ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \
  636. typename ::asio::async_result< \
  637. typename ::asio::decay<ct>::type, sig0, sig1>::return_type
  638. # define ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \
  639. typename ::asio::async_result< \
  640. typename ::asio::decay<ct>::type, sig0, sig1, sig2>::return_type
  641. #define ASIO_HANDLER_TYPE(ct, sig) \
  642. typename ::asio::async_result< \
  643. typename ::asio::decay<ct>::type, sig>::completion_handler_type
  644. #define ASIO_HANDLER_TYPE2(ct, sig0, sig1) \
  645. typename ::asio::async_result< \
  646. typename ::asio::decay<ct>::type, \
  647. sig0, sig1>::completion_handler_type
  648. #define ASIO_HANDLER_TYPE3(ct, sig0, sig1, sig2) \
  649. typename ::asio::async_result< \
  650. typename ::asio::decay<ct>::type, \
  651. sig0, sig1, sig2>::completion_handler_type
  652. #endif
  653. #if defined(GENERATING_DOCUMENTATION)
  654. # define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
  655. auto
  656. # define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \
  657. auto
  658. # define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \
  659. auto
  660. #elif defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)
  661. # define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
  662. auto
  663. # define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \
  664. auto
  665. # define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \
  666. auto
  667. #else
  668. # define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
  669. ASIO_INITFN_RESULT_TYPE(ct, sig)
  670. # define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \
  671. ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1)
  672. # define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \
  673. ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2)
  674. #endif
  675. #if defined(GENERATING_DOCUMENTATION)
  676. # define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
  677. void_or_deduced
  678. # define ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \
  679. void_or_deduced
  680. # define ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \
  681. void_or_deduced
  682. #elif defined(ASIO_HAS_DECLTYPE)
  683. # define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
  684. decltype expr
  685. # define ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \
  686. decltype expr
  687. # define ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \
  688. decltype expr
  689. #else
  690. # define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
  691. ASIO_INITFN_RESULT_TYPE(ct, sig)
  692. # define ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \
  693. ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1)
  694. # define ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \
  695. ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2)
  696. #endif
  697. #if defined(GENERATING_DOCUMENTATION)
  698. template <typename CompletionToken,
  699. completion_signature... Signatures,
  700. typename Initiation, typename... Args>
  701. void_or_deduced async_initiate(
  702. ASIO_MOVE_ARG(Initiation) initiation,
  703. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken),
  704. ASIO_MOVE_ARG(Args)... args);
  705. #elif defined(ASIO_HAS_VARIADIC_TEMPLATES)
  706. template <typename CompletionToken,
  707. ASIO_COMPLETION_SIGNATURE... Signatures,
  708. typename Initiation, typename... Args>
  709. inline typename constraint<
  710. detail::async_result_has_initiate_memfn<
  711. CompletionToken, Signatures...>::value,
  712. ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signatures...,
  713. (async_result<typename decay<CompletionToken>::type,
  714. Signatures...>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(),
  715. declval<ASIO_MOVE_ARG(CompletionToken)>(),
  716. declval<ASIO_MOVE_ARG(Args)>()...)))>::type
  717. async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
  718. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
  719. ASIO_MOVE_ARG(Args)... args)
  720. {
  721. return async_result<typename decay<CompletionToken>::type,
  722. Signatures...>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),
  723. ASIO_MOVE_CAST(CompletionToken)(token),
  724. ASIO_MOVE_CAST(Args)(args)...);
  725. }
  726. template <typename CompletionToken,
  727. ASIO_COMPLETION_SIGNATURE... Signatures,
  728. typename Initiation, typename... Args>
  729. inline typename constraint<
  730. !detail::async_result_has_initiate_memfn<
  731. CompletionToken, Signatures...>::value,
  732. ASIO_INITFN_RESULT_TYPE(CompletionToken, Signatures...)>::type
  733. async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
  734. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
  735. ASIO_MOVE_ARG(Args)... args)
  736. {
  737. async_completion<CompletionToken, Signatures...> completion(token);
  738. ASIO_MOVE_CAST(Initiation)(initiation)(
  739. ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken,
  740. Signatures...))(completion.completion_handler),
  741. ASIO_MOVE_CAST(Args)(args)...);
  742. return completion.result.get();
  743. }
  744. #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  745. template <typename CompletionToken,
  746. ASIO_COMPLETION_SIGNATURE Sig0,
  747. typename Initiation>
  748. inline typename constraint<
  749. detail::async_result_has_initiate_memfn<
  750. CompletionToken, Sig0>::value,
  751. ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Sig0,
  752. (async_result<typename decay<CompletionToken>::type,
  753. Sig0>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(),
  754. declval<ASIO_MOVE_ARG(CompletionToken)>())))>::type
  755. async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
  756. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
  757. {
  758. return async_result<typename decay<CompletionToken>::type,
  759. Sig0>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),
  760. ASIO_MOVE_CAST(CompletionToken)(token));
  761. }
  762. template <typename CompletionToken,
  763. ASIO_COMPLETION_SIGNATURE Sig0,
  764. ASIO_COMPLETION_SIGNATURE Sig1,
  765. typename Initiation>
  766. inline typename constraint<
  767. detail::async_result_has_initiate_memfn<
  768. CompletionToken, Sig0, Sig1>::value,
  769. ASIO_INITFN_DEDUCED_RESULT_TYPE2(CompletionToken, Sig0, Sig1,
  770. (async_result<typename decay<CompletionToken>::type,
  771. Sig0, Sig1>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(),
  772. declval<ASIO_MOVE_ARG(CompletionToken)>())))>::type
  773. async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
  774. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
  775. {
  776. return async_result<typename decay<CompletionToken>::type,
  777. Sig0, Sig1>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),
  778. ASIO_MOVE_CAST(CompletionToken)(token));
  779. }
  780. template <typename CompletionToken,
  781. ASIO_COMPLETION_SIGNATURE Sig0,
  782. ASIO_COMPLETION_SIGNATURE Sig1,
  783. ASIO_COMPLETION_SIGNATURE Sig2,
  784. typename Initiation>
  785. inline typename constraint<
  786. detail::async_result_has_initiate_memfn<
  787. CompletionToken, Sig0, Sig1, Sig2>::value,
  788. ASIO_INITFN_DEDUCED_RESULT_TYPE3(CompletionToken, Sig0, Sig1, Sig2,
  789. (async_result<typename decay<CompletionToken>::type,
  790. Sig0, Sig1, Sig2>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(),
  791. declval<ASIO_MOVE_ARG(CompletionToken)>())))>::type
  792. async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
  793. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
  794. {
  795. return async_result<typename decay<CompletionToken>::type,
  796. Sig0, Sig1, Sig2>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),
  797. ASIO_MOVE_CAST(CompletionToken)(token));
  798. }
  799. template <typename CompletionToken,
  800. ASIO_COMPLETION_SIGNATURE Sig0,
  801. typename Initiation>
  802. inline typename constraint<
  803. !detail::async_result_has_initiate_memfn<
  804. CompletionToken, Sig0>::value,
  805. ASIO_INITFN_RESULT_TYPE(CompletionToken, Sig0)>::type
  806. async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
  807. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
  808. {
  809. async_completion<CompletionToken, Sig0> completion(token);
  810. ASIO_MOVE_CAST(Initiation)(initiation)(
  811. ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken,
  812. Sig0))(completion.completion_handler));
  813. return completion.result.get();
  814. }
  815. template <typename CompletionToken,
  816. ASIO_COMPLETION_SIGNATURE Sig0,
  817. ASIO_COMPLETION_SIGNATURE Sig1,
  818. typename Initiation>
  819. inline typename constraint<
  820. !detail::async_result_has_initiate_memfn<
  821. CompletionToken, Sig0, Sig1>::value,
  822. ASIO_INITFN_RESULT_TYPE2(CompletionToken, Sig0, Sig1)>::type
  823. async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
  824. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
  825. {
  826. async_completion<CompletionToken, Sig0, Sig1> completion(token);
  827. ASIO_MOVE_CAST(Initiation)(initiation)(
  828. ASIO_MOVE_CAST(ASIO_HANDLER_TYPE2(CompletionToken,
  829. Sig0, Sig1))(completion.completion_handler));
  830. return completion.result.get();
  831. }
  832. template <typename CompletionToken,
  833. ASIO_COMPLETION_SIGNATURE Sig0,
  834. ASIO_COMPLETION_SIGNATURE Sig1,
  835. ASIO_COMPLETION_SIGNATURE Sig2,
  836. typename Initiation>
  837. inline typename constraint<
  838. !detail::async_result_has_initiate_memfn<
  839. CompletionToken, Sig0, Sig1, Sig2>::value,
  840. ASIO_INITFN_RESULT_TYPE3(CompletionToken, Sig0, Sig1, Sig2)>::type
  841. async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
  842. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
  843. {
  844. async_completion<CompletionToken, Sig0, Sig1, Sig2> completion(token);
  845. ASIO_MOVE_CAST(Initiation)(initiation)(
  846. ASIO_MOVE_CAST(ASIO_HANDLER_TYPE3(CompletionToken,
  847. Sig0, Sig1, Sig2))(completion.completion_handler));
  848. return completion.result.get();
  849. }
  850. #define ASIO_PRIVATE_INITIATE_DEF(n) \
  851. template <typename CompletionToken, \
  852. ASIO_COMPLETION_SIGNATURE Sig0, \
  853. typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \
  854. inline typename constraint< \
  855. detail::async_result_has_initiate_memfn< \
  856. CompletionToken, Sig0>::value, \
  857. ASIO_INITFN_DEDUCED_RESULT_TYPE( \
  858. CompletionToken, Sig0, \
  859. (async_result<typename decay<CompletionToken>::type, \
  860. Sig0>::initiate( \
  861. declval<ASIO_MOVE_ARG(Initiation)>(), \
  862. declval<ASIO_MOVE_ARG(CompletionToken)>(), \
  863. ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \
  864. async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \
  865. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
  866. ASIO_VARIADIC_MOVE_PARAMS(n)) \
  867. { \
  868. return async_result<typename decay<CompletionToken>::type, \
  869. Sig0>::initiate( \
  870. ASIO_MOVE_CAST(Initiation)(initiation), \
  871. ASIO_MOVE_CAST(CompletionToken)(token), \
  872. ASIO_VARIADIC_MOVE_ARGS(n)); \
  873. } \
  874. \
  875. template <typename CompletionToken, \
  876. ASIO_COMPLETION_SIGNATURE Sig0, \
  877. ASIO_COMPLETION_SIGNATURE Sig1, \
  878. typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \
  879. inline typename constraint< \
  880. detail::async_result_has_initiate_memfn< \
  881. CompletionToken, Sig0, Sig1>::value, \
  882. ASIO_INITFN_DEDUCED_RESULT_TYPE2( \
  883. CompletionToken, Sig0, Sig1, \
  884. (async_result<typename decay<CompletionToken>::type, \
  885. Sig0, Sig1>::initiate( \
  886. declval<ASIO_MOVE_ARG(Initiation)>(), \
  887. declval<ASIO_MOVE_ARG(CompletionToken)>(), \
  888. ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \
  889. async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \
  890. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
  891. ASIO_VARIADIC_MOVE_PARAMS(n)) \
  892. { \
  893. return async_result<typename decay<CompletionToken>::type, \
  894. Sig0, Sig1>::initiate( \
  895. ASIO_MOVE_CAST(Initiation)(initiation), \
  896. ASIO_MOVE_CAST(CompletionToken)(token), \
  897. ASIO_VARIADIC_MOVE_ARGS(n)); \
  898. } \
  899. \
  900. template <typename CompletionToken, \
  901. ASIO_COMPLETION_SIGNATURE Sig0, \
  902. ASIO_COMPLETION_SIGNATURE Sig1, \
  903. ASIO_COMPLETION_SIGNATURE Sig2, \
  904. typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \
  905. inline typename constraint< \
  906. detail::async_result_has_initiate_memfn< \
  907. CompletionToken, Sig0, Sig1, Sig2>::value, \
  908. ASIO_INITFN_DEDUCED_RESULT_TYPE3( \
  909. CompletionToken, Sig0, Sig1, Sig2, \
  910. (async_result<typename decay<CompletionToken>::type, \
  911. Sig0, Sig1, Sig2>::initiate( \
  912. declval<ASIO_MOVE_ARG(Initiation)>(), \
  913. declval<ASIO_MOVE_ARG(CompletionToken)>(), \
  914. ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \
  915. async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \
  916. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
  917. ASIO_VARIADIC_MOVE_PARAMS(n)) \
  918. { \
  919. return async_result<typename decay<CompletionToken>::type, \
  920. Sig0, Sig1, Sig2>::initiate( \
  921. ASIO_MOVE_CAST(Initiation)(initiation), \
  922. ASIO_MOVE_CAST(CompletionToken)(token), \
  923. ASIO_VARIADIC_MOVE_ARGS(n)); \
  924. } \
  925. \
  926. template <typename CompletionToken, \
  927. ASIO_COMPLETION_SIGNATURE Sig0, \
  928. typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \
  929. inline typename constraint< \
  930. !detail::async_result_has_initiate_memfn< \
  931. CompletionToken, Sig0>::value, \
  932. ASIO_INITFN_RESULT_TYPE(CompletionToken, Sig0)>::type \
  933. async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \
  934. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
  935. ASIO_VARIADIC_MOVE_PARAMS(n)) \
  936. { \
  937. async_completion<CompletionToken, \
  938. Sig0> completion(token); \
  939. \
  940. ASIO_MOVE_CAST(Initiation)(initiation)( \
  941. ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken, \
  942. Sig0))(completion.completion_handler), \
  943. ASIO_VARIADIC_MOVE_ARGS(n)); \
  944. \
  945. return completion.result.get(); \
  946. } \
  947. \
  948. template <typename CompletionToken, \
  949. ASIO_COMPLETION_SIGNATURE Sig0, \
  950. ASIO_COMPLETION_SIGNATURE Sig1, \
  951. typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \
  952. inline typename constraint< \
  953. !detail::async_result_has_initiate_memfn< \
  954. CompletionToken, Sig0, Sig1>::value, \
  955. ASIO_INITFN_RESULT_TYPE2(CompletionToken, Sig0, Sig1)>::type \
  956. async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \
  957. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
  958. ASIO_VARIADIC_MOVE_PARAMS(n)) \
  959. { \
  960. async_completion<CompletionToken, \
  961. Sig0, Sig1> completion(token); \
  962. \
  963. ASIO_MOVE_CAST(Initiation)(initiation)( \
  964. ASIO_MOVE_CAST(ASIO_HANDLER_TYPE2(CompletionToken, \
  965. Sig0, Sig1))(completion.completion_handler), \
  966. ASIO_VARIADIC_MOVE_ARGS(n)); \
  967. \
  968. return completion.result.get(); \
  969. } \
  970. \
  971. template <typename CompletionToken, \
  972. ASIO_COMPLETION_SIGNATURE Sig0, \
  973. ASIO_COMPLETION_SIGNATURE Sig1, \
  974. ASIO_COMPLETION_SIGNATURE Sig2, \
  975. typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \
  976. inline typename constraint< \
  977. !detail::async_result_has_initiate_memfn< \
  978. CompletionToken, Sig0, Sig1, Sig2>::value, \
  979. ASIO_INITFN_RESULT_TYPE3(CompletionToken, Sig0, Sig1, Sig2)>::type \
  980. async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \
  981. ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
  982. ASIO_VARIADIC_MOVE_PARAMS(n)) \
  983. { \
  984. async_completion<CompletionToken, \
  985. Sig0, Sig1, Sig2> completion(token); \
  986. \
  987. ASIO_MOVE_CAST(Initiation)(initiation)( \
  988. ASIO_MOVE_CAST(ASIO_HANDLER_TYPE3(CompletionToken, \
  989. Sig0, Sig1, Sig2))(completion.completion_handler), \
  990. ASIO_VARIADIC_MOVE_ARGS(n)); \
  991. \
  992. return completion.result.get(); \
  993. } \
  994. /**/
  995. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)
  996. #undef ASIO_PRIVATE_INITIATE_DEF
  997. #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  998. #if defined(ASIO_HAS_CONCEPTS) \
  999. && defined(ASIO_HAS_VARIADIC_TEMPLATES) \
  1000. && defined(ASIO_HAS_DECLTYPE)
  1001. namespace detail {
  1002. template <typename... Signatures>
  1003. struct initiation_archetype
  1004. {
  1005. template <completion_handler_for<Signatures...> CompletionHandler>
  1006. void operator()(CompletionHandler&&) const
  1007. {
  1008. }
  1009. };
  1010. } // namespace detail
  1011. template <typename T, typename... Signatures>
  1012. ASIO_CONCEPT completion_token_for =
  1013. detail::are_completion_signatures<Signatures...>::value
  1014. &&
  1015. requires(T&& t)
  1016. {
  1017. async_initiate<T, Signatures...>(
  1018. detail::initiation_archetype<Signatures...>{}, t);
  1019. };
  1020. #define ASIO_COMPLETION_TOKEN_FOR(sig) \
  1021. ::asio::completion_token_for<sig>
  1022. #define ASIO_COMPLETION_TOKEN_FOR2(sig0, sig1) \
  1023. ::asio::completion_token_for<sig0, sig1>
  1024. #define ASIO_COMPLETION_TOKEN_FOR3(sig0, sig1, sig2) \
  1025. ::asio::completion_token_for<sig0, sig1, sig2>
  1026. #else // defined(ASIO_HAS_CONCEPTS)
  1027. // && defined(ASIO_HAS_VARIADIC_TEMPLATES)
  1028. // && defined(ASIO_HAS_DECLTYPE)
  1029. #define ASIO_COMPLETION_TOKEN_FOR(sig) typename
  1030. #define ASIO_COMPLETION_TOKEN_FOR2(sig0, sig1) typename
  1031. #define ASIO_COMPLETION_TOKEN_FOR3(sig0, sig1, sig2) typename
  1032. #endif // defined(ASIO_HAS_CONCEPTS)
  1033. // && defined(ASIO_HAS_VARIADIC_TEMPLATES)
  1034. // && defined(ASIO_HAS_DECLTYPE)
  1035. namespace detail {
  1036. template <typename T, typename = void>
  1037. struct default_completion_token_impl
  1038. {
  1039. typedef void type;
  1040. };
  1041. template <typename T>
  1042. struct default_completion_token_impl<T,
  1043. typename void_type<typename T::default_completion_token_type>::type>
  1044. {
  1045. typedef typename T::default_completion_token_type type;
  1046. };
  1047. } // namespace detail
  1048. #if defined(GENERATING_DOCUMENTATION)
  1049. /// Traits type used to determine the default completion token type associated
  1050. /// with a type (such as an executor).
  1051. /**
  1052. * A program may specialise this traits type if the @c T template parameter in
  1053. * the specialisation is a user-defined type.
  1054. *
  1055. * Specialisations of this trait may provide a nested typedef @c type, which is
  1056. * a default-constructible completion token type.
  1057. */
  1058. template <typename T>
  1059. struct default_completion_token
  1060. {
  1061. /// If @c T has a nested type @c default_completion_token_type,
  1062. /// <tt>T::default_completion_token_type</tt>. Otherwise the typedef @c type
  1063. /// is not defined.
  1064. typedef see_below type;
  1065. };
  1066. #else
  1067. template <typename T>
  1068. struct default_completion_token
  1069. : detail::default_completion_token_impl<T>
  1070. {
  1071. };
  1072. #endif
  1073. #if defined(ASIO_HAS_ALIAS_TEMPLATES)
  1074. template <typename T>
  1075. using default_completion_token_t = typename default_completion_token<T>::type;
  1076. #endif // defined(ASIO_HAS_ALIAS_TEMPLATES)
  1077. #if defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
  1078. #define ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) \
  1079. = typename ::asio::default_completion_token<e>::type
  1080. #define ASIO_DEFAULT_COMPLETION_TOKEN(e) \
  1081. = typename ::asio::default_completion_token<e>::type()
  1082. #else // defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
  1083. #define ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e)
  1084. #define ASIO_DEFAULT_COMPLETION_TOKEN(e)
  1085. #endif // defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
  1086. } // namespace asio
  1087. #include "asio/detail/pop_options.hpp"
  1088. #endif // ASIO_ASYNC_RESULT_HPP