async_result.hpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  1. //
  2. // async_result.hpp
  3. // ~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_ASYNC_RESULT_HPP
  11. #define BOOST_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 <boost/asio/detail/config.hpp>
  16. #include <boost/asio/detail/type_traits.hpp>
  17. #include <boost/asio/detail/push_options.hpp>
  18. namespace boost {
  19. namespace asio {
  20. #if defined(BOOST_ASIO_HAS_CONCEPTS)
  21. namespace detail {
  22. template <typename T>
  23. struct is_completion_signature : false_type
  24. {
  25. };
  26. template <typename R, typename... Args>
  27. struct is_completion_signature<R(Args...)> : true_type
  28. {
  29. };
  30. template <typename R, typename... Args>
  31. struct is_completion_signature<R(Args...) &> : true_type
  32. {
  33. };
  34. template <typename R, typename... Args>
  35. struct is_completion_signature<R(Args...) &&> : true_type
  36. {
  37. };
  38. # if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  39. template <typename R, typename... Args>
  40. struct is_completion_signature<R(Args...) noexcept> : true_type
  41. {
  42. };
  43. template <typename R, typename... Args>
  44. struct is_completion_signature<R(Args...) & noexcept> : true_type
  45. {
  46. };
  47. template <typename R, typename... Args>
  48. struct is_completion_signature<R(Args...) && noexcept> : true_type
  49. {
  50. };
  51. # endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  52. template <typename... T>
  53. struct are_completion_signatures : false_type
  54. {
  55. };
  56. template <typename T0>
  57. struct are_completion_signatures<T0>
  58. : is_completion_signature<T0>
  59. {
  60. };
  61. template <typename T0, typename... TN>
  62. struct are_completion_signatures<T0, TN...>
  63. : integral_constant<bool, (
  64. is_completion_signature<T0>::value
  65. && are_completion_signatures<TN...>::value)>
  66. {
  67. };
  68. template <typename T, typename... Args>
  69. BOOST_ASIO_CONCEPT callable_with = requires(T&& t, Args&&... args)
  70. {
  71. static_cast<T&&>(t)(static_cast<Args&&>(args)...);
  72. };
  73. template <typename T, typename... Signatures>
  74. struct is_completion_handler_for : false_type
  75. {
  76. };
  77. template <typename T, typename R, typename... Args>
  78. struct is_completion_handler_for<T, R(Args...)>
  79. : integral_constant<bool, (callable_with<T, Args...>)>
  80. {
  81. };
  82. template <typename T, typename R, typename... Args>
  83. struct is_completion_handler_for<T, R(Args...) &>
  84. : integral_constant<bool, (callable_with<T&, Args...>)>
  85. {
  86. };
  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. # if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  93. template <typename T, typename R, typename... Args>
  94. struct is_completion_handler_for<T, R(Args...) noexcept>
  95. : integral_constant<bool, (callable_with<T, Args...>)>
  96. {
  97. };
  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. # endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  109. template <typename T, typename Signature0, typename... SignatureN>
  110. struct is_completion_handler_for<T, Signature0, SignatureN...>
  111. : integral_constant<bool, (
  112. is_completion_handler_for<T, Signature0>::value
  113. && is_completion_handler_for<T, SignatureN...>::value)>
  114. {
  115. };
  116. } // namespace detail
  117. template <typename T>
  118. BOOST_ASIO_CONCEPT completion_signature =
  119. detail::is_completion_signature<T>::value;
  120. #define BOOST_ASIO_COMPLETION_SIGNATURE \
  121. ::boost::asio::completion_signature
  122. template <typename T, typename... Signatures>
  123. BOOST_ASIO_CONCEPT completion_handler_for =
  124. detail::are_completion_signatures<Signatures...>::value
  125. && detail::is_completion_handler_for<T, Signatures...>::value;
  126. #define BOOST_ASIO_COMPLETION_HANDLER_FOR(sig) \
  127. ::boost::asio::completion_handler_for<sig>
  128. #define BOOST_ASIO_COMPLETION_HANDLER_FOR2(sig0, sig1) \
  129. ::boost::asio::completion_handler_for<sig0, sig1>
  130. #define BOOST_ASIO_COMPLETION_HANDLER_FOR3(sig0, sig1, sig2) \
  131. ::boost::asio::completion_handler_for<sig0, sig1, sig2>
  132. #else // defined(BOOST_ASIO_HAS_CONCEPTS)
  133. #define BOOST_ASIO_COMPLETION_SIGNATURE typename
  134. #define BOOST_ASIO_COMPLETION_HANDLER_FOR(sig) typename
  135. #define BOOST_ASIO_COMPLETION_HANDLER_FOR2(sig0, sig1) typename
  136. #define BOOST_ASIO_COMPLETION_HANDLER_FOR3(sig0, sig1, sig2) typename
  137. #endif // defined(BOOST_ASIO_HAS_CONCEPTS)
  138. namespace detail {
  139. template <typename T>
  140. struct is_simple_completion_signature : false_type
  141. {
  142. };
  143. template <typename T>
  144. struct simple_completion_signature;
  145. template <typename R, typename... Args>
  146. struct is_simple_completion_signature<R(Args...)> : true_type
  147. {
  148. };
  149. template <typename... Signatures>
  150. struct are_simple_completion_signatures : false_type
  151. {
  152. };
  153. template <typename Sig0>
  154. struct are_simple_completion_signatures<Sig0>
  155. : is_simple_completion_signature<Sig0>
  156. {
  157. };
  158. template <typename Sig0, typename... SigN>
  159. struct are_simple_completion_signatures<Sig0, SigN...>
  160. : integral_constant<bool, (
  161. is_simple_completion_signature<Sig0>::value
  162. && are_simple_completion_signatures<SigN...>::value)>
  163. {
  164. };
  165. template <typename R, typename... Args>
  166. struct simple_completion_signature<R(Args...)>
  167. {
  168. typedef R type(Args...);
  169. };
  170. template <typename R, typename... Args>
  171. struct simple_completion_signature<R(Args...) &>
  172. {
  173. typedef R type(Args...);
  174. };
  175. template <typename R, typename... Args>
  176. struct simple_completion_signature<R(Args...) &&>
  177. {
  178. typedef R type(Args...);
  179. };
  180. # if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  181. template <typename R, typename... Args>
  182. struct simple_completion_signature<R(Args...) noexcept>
  183. {
  184. typedef R type(Args...);
  185. };
  186. template <typename R, typename... Args>
  187. struct simple_completion_signature<R(Args...) & noexcept>
  188. {
  189. typedef R type(Args...);
  190. };
  191. template <typename R, typename... Args>
  192. struct simple_completion_signature<R(Args...) && noexcept>
  193. {
  194. typedef R type(Args...);
  195. };
  196. # endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  197. template <typename CompletionToken,
  198. BOOST_ASIO_COMPLETION_SIGNATURE... Signatures>
  199. class completion_handler_async_result
  200. {
  201. public:
  202. typedef CompletionToken completion_handler_type;
  203. typedef void return_type;
  204. explicit completion_handler_async_result(completion_handler_type&)
  205. {
  206. }
  207. return_type get()
  208. {
  209. }
  210. template <typename Initiation,
  211. BOOST_ASIO_COMPLETION_HANDLER_FOR(Signatures...) RawCompletionToken,
  212. typename... Args>
  213. static return_type initiate(Initiation&& initiation,
  214. RawCompletionToken&& token, Args&&... args)
  215. {
  216. static_cast<Initiation&&>(initiation)(
  217. static_cast<RawCompletionToken&&>(token),
  218. static_cast<Args&&>(args)...);
  219. }
  220. private:
  221. completion_handler_async_result(
  222. const completion_handler_async_result&) = delete;
  223. completion_handler_async_result& operator=(
  224. const completion_handler_async_result&) = delete;
  225. };
  226. } // namespace detail
  227. #if defined(GENERATING_DOCUMENTATION)
  228. /// An interface for customising the behaviour of an initiating function.
  229. /**
  230. * The async_result traits class is used for determining:
  231. *
  232. * @li the concrete completion handler type to be called at the end of the
  233. * asynchronous operation;
  234. *
  235. * @li the initiating function return type; and
  236. *
  237. * @li how the return value of the initiating function is obtained.
  238. *
  239. * The trait allows the handler and return types to be determined at the point
  240. * where the specific completion handler signature is known.
  241. *
  242. * This template may be specialised for user-defined completion token types.
  243. * The primary template assumes that the CompletionToken is the completion
  244. * handler.
  245. */
  246. template <typename CompletionToken,
  247. BOOST_ASIO_COMPLETION_SIGNATURE... Signatures>
  248. class async_result
  249. {
  250. public:
  251. /// The concrete completion handler type for the specific signature.
  252. typedef CompletionToken completion_handler_type;
  253. /// The return type of the initiating function.
  254. typedef void return_type;
  255. /// Construct an async result from a given handler.
  256. /**
  257. * When using a specalised async_result, the constructor has an opportunity
  258. * to initialise some state associated with the completion handler, which is
  259. * then returned from the initiating function.
  260. */
  261. explicit async_result(completion_handler_type& h);
  262. /// Obtain the value to be returned from the initiating function.
  263. return_type get();
  264. /// Initiate the asynchronous operation that will produce the result, and
  265. /// obtain the value to be returned from the initiating function.
  266. template <typename Initiation, typename RawCompletionToken, typename... Args>
  267. static return_type initiate(
  268. Initiation&& initiation,
  269. RawCompletionToken&& token,
  270. Args&&... args);
  271. private:
  272. async_result(const async_result&) = delete;
  273. async_result& operator=(const async_result&) = delete;
  274. };
  275. #else // defined(GENERATING_DOCUMENTATION)
  276. template <typename CompletionToken,
  277. BOOST_ASIO_COMPLETION_SIGNATURE... Signatures>
  278. class async_result :
  279. public conditional_t<
  280. detail::are_simple_completion_signatures<Signatures...>::value,
  281. detail::completion_handler_async_result<CompletionToken, Signatures...>,
  282. async_result<CompletionToken,
  283. typename detail::simple_completion_signature<Signatures>::type...>
  284. >
  285. {
  286. public:
  287. typedef conditional_t<
  288. detail::are_simple_completion_signatures<Signatures...>::value,
  289. detail::completion_handler_async_result<CompletionToken, Signatures...>,
  290. async_result<CompletionToken,
  291. typename detail::simple_completion_signature<Signatures>::type...>
  292. > base_type;
  293. using base_type::base_type;
  294. private:
  295. async_result(const async_result&) = delete;
  296. async_result& operator=(const async_result&) = delete;
  297. };
  298. template <BOOST_ASIO_COMPLETION_SIGNATURE... Signatures>
  299. class async_result<void, Signatures...>
  300. {
  301. // Empty.
  302. };
  303. #endif // defined(GENERATING_DOCUMENTATION)
  304. /// Helper template to deduce the handler type from a CompletionToken, capture
  305. /// a local copy of the handler, and then create an async_result for the
  306. /// handler.
  307. template <typename CompletionToken,
  308. BOOST_ASIO_COMPLETION_SIGNATURE... Signatures>
  309. struct async_completion
  310. {
  311. /// The real handler type to be used for the asynchronous operation.
  312. typedef typename boost::asio::async_result<
  313. decay_t<CompletionToken>, Signatures...>::completion_handler_type
  314. completion_handler_type;
  315. /// Constructor.
  316. /**
  317. * The constructor creates the concrete completion handler and makes the link
  318. * between the handler and the asynchronous result.
  319. */
  320. explicit async_completion(CompletionToken& token)
  321. : completion_handler(static_cast<conditional_t<
  322. is_same<CompletionToken, completion_handler_type>::value,
  323. completion_handler_type&, CompletionToken&&>>(token)),
  324. result(completion_handler)
  325. {
  326. }
  327. /// A copy of, or reference to, a real handler object.
  328. conditional_t<
  329. is_same<CompletionToken, completion_handler_type>::value,
  330. completion_handler_type&, completion_handler_type> completion_handler;
  331. /// The result of the asynchronous operation's initiating function.
  332. async_result<decay_t<CompletionToken>, Signatures...> result;
  333. };
  334. namespace detail {
  335. struct async_result_memfns_base
  336. {
  337. void initiate();
  338. };
  339. template <typename T>
  340. struct async_result_memfns_derived
  341. : T, async_result_memfns_base
  342. {
  343. };
  344. template <typename T, T>
  345. struct async_result_memfns_check
  346. {
  347. };
  348. template <typename>
  349. char (&async_result_initiate_memfn_helper(...))[2];
  350. template <typename T>
  351. char async_result_initiate_memfn_helper(
  352. async_result_memfns_check<
  353. void (async_result_memfns_base::*)(),
  354. &async_result_memfns_derived<T>::initiate>*);
  355. template <typename CompletionToken,
  356. BOOST_ASIO_COMPLETION_SIGNATURE... Signatures>
  357. struct async_result_has_initiate_memfn
  358. : integral_constant<bool, sizeof(async_result_initiate_memfn_helper<
  359. async_result<decay_t<CompletionToken>, Signatures...>
  360. >(0)) != 1>
  361. {
  362. };
  363. } // namespace detail
  364. #if defined(GENERATING_DOCUMENTATION)
  365. # define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
  366. void_or_deduced
  367. # define BOOST_ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \
  368. void_or_deduced
  369. # define BOOST_ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \
  370. void_or_deduced
  371. #else
  372. # define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
  373. typename ::boost::asio::async_result< \
  374. typename ::boost::asio::decay<ct>::type, sig>::return_type
  375. # define BOOST_ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \
  376. typename ::boost::asio::async_result< \
  377. typename ::boost::asio::decay<ct>::type, sig0, sig1>::return_type
  378. # define BOOST_ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \
  379. typename ::boost::asio::async_result< \
  380. typename ::boost::asio::decay<ct>::type, sig0, sig1, sig2>::return_type
  381. #define BOOST_ASIO_HANDLER_TYPE(ct, sig) \
  382. typename ::boost::asio::async_result< \
  383. typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type
  384. #define BOOST_ASIO_HANDLER_TYPE2(ct, sig0, sig1) \
  385. typename ::boost::asio::async_result< \
  386. typename ::boost::asio::decay<ct>::type, \
  387. sig0, sig1>::completion_handler_type
  388. #define BOOST_ASIO_HANDLER_TYPE3(ct, sig0, sig1, sig2) \
  389. typename ::boost::asio::async_result< \
  390. typename ::boost::asio::decay<ct>::type, \
  391. sig0, sig1, sig2>::completion_handler_type
  392. #endif
  393. #if defined(GENERATING_DOCUMENTATION)
  394. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
  395. auto
  396. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \
  397. auto
  398. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \
  399. auto
  400. #elif defined(BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION)
  401. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
  402. auto
  403. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \
  404. auto
  405. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \
  406. auto
  407. #else
  408. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
  409. BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig)
  410. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \
  411. BOOST_ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1)
  412. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \
  413. BOOST_ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2)
  414. #endif
  415. #if defined(GENERATING_DOCUMENTATION)
  416. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \
  417. auto
  418. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \
  419. auto
  420. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \
  421. auto
  422. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)
  423. #elif defined(BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION)
  424. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \
  425. auto
  426. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \
  427. auto
  428. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \
  429. auto
  430. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)
  431. #else
  432. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \
  433. auto
  434. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \
  435. auto
  436. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \
  437. auto
  438. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr) -> decltype expr
  439. #endif
  440. #if defined(GENERATING_DOCUMENTATION)
  441. # define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
  442. void_or_deduced
  443. # define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \
  444. void_or_deduced
  445. # define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \
  446. void_or_deduced
  447. #else
  448. # define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
  449. decltype expr
  450. # define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \
  451. decltype expr
  452. # define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \
  453. decltype expr
  454. #endif
  455. #if defined(GENERATING_DOCUMENTATION)
  456. template <typename CompletionToken,
  457. completion_signature... Signatures,
  458. typename Initiation, typename... Args>
  459. void_or_deduced async_initiate(
  460. Initiation&& initiation,
  461. type_identity_t<CompletionToken>& token,
  462. Args&&... args);
  463. #else // defined(GENERATING_DOCUMENTATION)
  464. template <typename CompletionToken,
  465. BOOST_ASIO_COMPLETION_SIGNATURE... Signatures,
  466. typename Initiation, typename... Args>
  467. inline auto async_initiate(Initiation&& initiation,
  468. type_identity_t<CompletionToken>& token, Args&&... args)
  469. -> constraint_t<
  470. detail::async_result_has_initiate_memfn<
  471. CompletionToken, Signatures...>::value,
  472. decltype(
  473. async_result<decay_t<CompletionToken>, Signatures...>::initiate(
  474. static_cast<Initiation&&>(initiation),
  475. static_cast<CompletionToken&&>(token),
  476. static_cast<Args&&>(args)...))>
  477. {
  478. return async_result<decay_t<CompletionToken>, Signatures...>::initiate(
  479. static_cast<Initiation&&>(initiation),
  480. static_cast<CompletionToken&&>(token),
  481. static_cast<Args&&>(args)...);
  482. }
  483. template <typename CompletionToken,
  484. BOOST_ASIO_COMPLETION_SIGNATURE... Signatures,
  485. typename Initiation, typename... Args>
  486. inline constraint_t<
  487. !detail::async_result_has_initiate_memfn<
  488. CompletionToken, Signatures...>::value,
  489. typename async_result<decay_t<CompletionToken>, Signatures...>::return_type>
  490. async_initiate(Initiation&& initiation,
  491. type_identity_t<CompletionToken>& token, Args&&... args)
  492. {
  493. async_completion<CompletionToken, Signatures...> completion(token);
  494. static_cast<Initiation&&>(initiation)(
  495. static_cast<
  496. typename async_result<decay_t<CompletionToken>,
  497. Signatures...>::completion_handler_type&&>(
  498. completion.completion_handler),
  499. static_cast<Args&&>(args)...);
  500. return completion.result.get();
  501. }
  502. #endif // defined(GENERATING_DOCUMENTATION)
  503. #if defined(BOOST_ASIO_HAS_CONCEPTS)
  504. namespace detail {
  505. template <typename... Signatures>
  506. struct initiation_archetype
  507. {
  508. template <completion_handler_for<Signatures...> CompletionHandler>
  509. void operator()(CompletionHandler&&) const
  510. {
  511. }
  512. };
  513. } // namespace detail
  514. template <typename T, typename... Signatures>
  515. BOOST_ASIO_CONCEPT completion_token_for =
  516. detail::are_completion_signatures<Signatures...>::value
  517. &&
  518. requires(T&& t)
  519. {
  520. async_initiate<T, Signatures...>(
  521. detail::initiation_archetype<Signatures...>{}, t);
  522. };
  523. #define BOOST_ASIO_COMPLETION_TOKEN_FOR(sig) \
  524. ::boost::asio::completion_token_for<sig>
  525. #define BOOST_ASIO_COMPLETION_TOKEN_FOR2(sig0, sig1) \
  526. ::boost::asio::completion_token_for<sig0, sig1>
  527. #define BOOST_ASIO_COMPLETION_TOKEN_FOR3(sig0, sig1, sig2) \
  528. ::boost::asio::completion_token_for<sig0, sig1, sig2>
  529. #else // defined(BOOST_ASIO_HAS_CONCEPTS)
  530. #define BOOST_ASIO_COMPLETION_TOKEN_FOR(sig) typename
  531. #define BOOST_ASIO_COMPLETION_TOKEN_FOR2(sig0, sig1) typename
  532. #define BOOST_ASIO_COMPLETION_TOKEN_FOR3(sig0, sig1, sig2) typename
  533. #endif // defined(BOOST_ASIO_HAS_CONCEPTS)
  534. namespace detail {
  535. struct async_operation_probe {};
  536. struct async_operation_probe_result {};
  537. template <typename Call, typename = void>
  538. struct is_async_operation_call : false_type
  539. {
  540. };
  541. template <typename Call>
  542. struct is_async_operation_call<Call,
  543. void_t<
  544. enable_if_t<
  545. is_same<
  546. result_of_t<Call>,
  547. async_operation_probe_result
  548. >::value
  549. >
  550. >
  551. > : true_type
  552. {
  553. };
  554. } // namespace detail
  555. #if !defined(GENERATING_DOCUMENTATION)
  556. template <typename... Signatures>
  557. class async_result<detail::async_operation_probe, Signatures...>
  558. {
  559. public:
  560. typedef detail::async_operation_probe_result return_type;
  561. template <typename Initiation, typename... InitArgs>
  562. static return_type initiate(Initiation&&,
  563. detail::async_operation_probe, InitArgs&&...)
  564. {
  565. return return_type();
  566. }
  567. };
  568. #endif // !defined(GENERATING_DOCUMENTATION)
  569. #if defined(GENERATING_DOCUMENTATION)
  570. /// The is_async_operation trait detects whether a type @c T and arguments
  571. /// @c Args... may be used to initiate an asynchronous operation.
  572. /**
  573. * Class template @c is_async_operation is a trait is derived from @c true_type
  574. * if the expression <tt>T(Args..., token)</tt> initiates an asynchronous
  575. * operation, where @c token is an unspecified completion token type. Otherwise,
  576. * @c is_async_operation is derived from @c false_type.
  577. */
  578. template <typename T, typename... Args>
  579. struct is_async_operation : integral_constant<bool, automatically_determined>
  580. {
  581. };
  582. #else // defined(GENERATING_DOCUMENTATION)
  583. template <typename T, typename... Args>
  584. struct is_async_operation :
  585. detail::is_async_operation_call<
  586. T(Args..., detail::async_operation_probe)>
  587. {
  588. };
  589. #endif // defined(GENERATING_DOCUMENTATION)
  590. #if defined(BOOST_ASIO_HAS_CONCEPTS)
  591. template <typename T, typename... Args>
  592. BOOST_ASIO_CONCEPT async_operation = is_async_operation<T, Args...>::value;
  593. #define BOOST_ASIO_ASYNC_OPERATION(t) \
  594. ::boost::asio::async_operation<t>
  595. #define BOOST_ASIO_ASYNC_OPERATION1(t, a0) \
  596. ::boost::asio::async_operation<t, a0>
  597. #define BOOST_ASIO_ASYNC_OPERATION2(t, a0, a1) \
  598. ::boost::asio::async_operation<t, a0, a1>
  599. #define BOOST_ASIO_ASYNC_OPERATION3(t, a0, a1, a2) \
  600. ::boost::asio::async_operation<t, a0, a1, a2>
  601. #else // defined(BOOST_ASIO_HAS_CONCEPTS)
  602. #define BOOST_ASIO_ASYNC_OPERATION(t) typename
  603. #define BOOST_ASIO_ASYNC_OPERATION1(t, a0) typename
  604. #define BOOST_ASIO_ASYNC_OPERATION2(t, a0, a1) typename
  605. #define BOOST_ASIO_ASYNC_OPERATION3(t, a0, a1, a2) typename
  606. #endif // defined(BOOST_ASIO_HAS_CONCEPTS)
  607. namespace detail {
  608. struct completion_signature_probe {};
  609. template <typename... T>
  610. struct completion_signature_probe_result
  611. {
  612. template <template <typename...> class Op>
  613. struct apply
  614. {
  615. typedef Op<T...> type;
  616. };
  617. };
  618. template <typename T>
  619. struct completion_signature_probe_result<T>
  620. {
  621. typedef T type;
  622. template <template <typename...> class Op>
  623. struct apply
  624. {
  625. typedef Op<T> type;
  626. };
  627. };
  628. template <>
  629. struct completion_signature_probe_result<void>
  630. {
  631. template <template <typename...> class Op>
  632. struct apply
  633. {
  634. typedef Op<> type;
  635. };
  636. };
  637. } // namespace detail
  638. #if !defined(GENERATING_DOCUMENTATION)
  639. template <typename... Signatures>
  640. class async_result<detail::completion_signature_probe, Signatures...>
  641. {
  642. public:
  643. typedef detail::completion_signature_probe_result<Signatures...> return_type;
  644. template <typename Initiation, typename... InitArgs>
  645. static return_type initiate(Initiation&&,
  646. detail::completion_signature_probe, InitArgs&&...)
  647. {
  648. return return_type();
  649. }
  650. };
  651. template <typename Signature>
  652. class async_result<detail::completion_signature_probe, Signature>
  653. {
  654. public:
  655. typedef detail::completion_signature_probe_result<Signature> return_type;
  656. template <typename Initiation, typename... InitArgs>
  657. static return_type initiate(Initiation&&,
  658. detail::completion_signature_probe, InitArgs&&...)
  659. {
  660. return return_type();
  661. }
  662. };
  663. #endif // !defined(GENERATING_DOCUMENTATION)
  664. #if defined(GENERATING_DOCUMENTATION)
  665. /// The completion_signature_of trait determines the completion signature
  666. /// of an asynchronous operation.
  667. /**
  668. * Class template @c completion_signature_of is a trait with a member type
  669. * alias @c type that denotes the completion signature of the asynchronous
  670. * operation initiated by the expression <tt>T(Args..., token)</tt> operation,
  671. * where @c token is an unspecified completion token type. If the asynchronous
  672. * operation does not have exactly one completion signature, the instantion of
  673. * the trait is well-formed but the member type alias @c type is omitted. If
  674. * the expression <tt>T(Args..., token)</tt> is not an asynchronous operation
  675. * then use of the trait is ill-formed.
  676. */
  677. template <typename T, typename... Args>
  678. struct completion_signature_of
  679. {
  680. typedef automatically_determined type;
  681. };
  682. #else // defined(GENERATING_DOCUMENTATION)
  683. template <typename T, typename... Args>
  684. struct completion_signature_of :
  685. result_of_t<T(Args..., detail::completion_signature_probe)>
  686. {
  687. };
  688. #endif // defined(GENERATING_DOCUMENTATION)
  689. template <typename T, typename... Args>
  690. using completion_signature_of_t =
  691. typename completion_signature_of<T, Args...>::type;
  692. namespace detail {
  693. template <typename T, typename = void>
  694. struct default_completion_token_impl
  695. {
  696. typedef void type;
  697. };
  698. template <typename T>
  699. struct default_completion_token_impl<T,
  700. void_t<typename T::default_completion_token_type>
  701. >
  702. {
  703. typedef typename T::default_completion_token_type type;
  704. };
  705. } // namespace detail
  706. #if defined(GENERATING_DOCUMENTATION)
  707. /// Traits type used to determine the default completion token type associated
  708. /// with a type (such as an executor).
  709. /**
  710. * A program may specialise this traits type if the @c T template parameter in
  711. * the specialisation is a user-defined type.
  712. *
  713. * Specialisations of this trait may provide a nested typedef @c type, which is
  714. * a default-constructible completion token type.
  715. */
  716. template <typename T>
  717. struct default_completion_token
  718. {
  719. /// If @c T has a nested type @c default_completion_token_type,
  720. /// <tt>T::default_completion_token_type</tt>. Otherwise the typedef @c type
  721. /// is not defined.
  722. typedef see_below type;
  723. };
  724. #else
  725. template <typename T>
  726. struct default_completion_token
  727. : detail::default_completion_token_impl<T>
  728. {
  729. };
  730. #endif
  731. template <typename T>
  732. using default_completion_token_t = typename default_completion_token<T>::type;
  733. #define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) \
  734. = typename ::boost::asio::default_completion_token<e>::type
  735. #define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(e) \
  736. = typename ::boost::asio::default_completion_token<e>::type()
  737. } // namespace asio
  738. } // namespace boost
  739. #include <boost/asio/detail/pop_options.hpp>
  740. #endif // BOOST_ASIO_ASYNC_RESULT_HPP