async_result.hpp 27 KB

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