async_result.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. //
  2. // async_result.hpp
  3. // ~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_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/variadic_templates.hpp>
  18. #include <boost/asio/detail/push_options.hpp>
  19. namespace boost {
  20. namespace asio {
  21. #if defined(BOOST_ASIO_HAS_CONCEPTS) \
  22. && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
  23. && defined(BOOST_ASIO_HAS_DECLTYPE)
  24. namespace detail {
  25. template <typename T>
  26. struct is_completion_signature : false_type
  27. {
  28. };
  29. template <typename R, typename... Args>
  30. struct is_completion_signature<R(Args...)> : true_type
  31. {
  32. };
  33. template <typename T, typename... Args>
  34. BOOST_ASIO_CONCEPT callable_with = requires(T t, Args&&... args)
  35. {
  36. t(static_cast<Args&&>(args)...);
  37. };
  38. template <typename T, typename Signature>
  39. struct is_completion_handler_for : false_type
  40. {
  41. };
  42. template <typename T, typename R, typename... Args>
  43. struct is_completion_handler_for<T, R(Args...)>
  44. : integral_constant<bool, (callable_with<T, Args...>)>
  45. {
  46. };
  47. } // namespace detail
  48. template <typename T>
  49. BOOST_ASIO_CONCEPT completion_signature =
  50. detail::is_completion_signature<T>::value;
  51. #define BOOST_ASIO_COMPLETION_SIGNATURE \
  52. ::boost::asio::completion_signature
  53. template <typename T, typename Signature>
  54. BOOST_ASIO_CONCEPT completion_handler_for =
  55. detail::is_completion_signature<Signature>::value
  56. && detail::is_completion_handler_for<T, Signature>::value;
  57. #define BOOST_ASIO_COMPLETION_HANDLER_FOR(s) \
  58. ::boost::asio::completion_handler_for<s>
  59. #else // defined(BOOST_ASIO_HAS_CONCEPTS)
  60. // && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  61. // && defined(BOOST_ASIO_HAS_DECLTYPE)
  62. #define BOOST_ASIO_COMPLETION_SIGNATURE typename
  63. #define BOOST_ASIO_COMPLETION_HANDLER_FOR(s) typename
  64. #endif // defined(BOOST_ASIO_HAS_CONCEPTS)
  65. // && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  66. // && defined(BOOST_ASIO_HAS_DECLTYPE)
  67. /// An interface for customising the behaviour of an initiating function.
  68. /**
  69. * The async_result traits class is used for determining:
  70. *
  71. * @li the concrete completion handler type to be called at the end of the
  72. * asynchronous operation;
  73. *
  74. * @li the initiating function return type; and
  75. *
  76. * @li how the return value of the initiating function is obtained.
  77. *
  78. * The trait allows the handler and return types to be determined at the point
  79. * where the specific completion handler signature is known.
  80. *
  81. * This template may be specialised for user-defined completion token types.
  82. * The primary template assumes that the CompletionToken is the completion
  83. * handler.
  84. */
  85. template <typename CompletionToken, BOOST_ASIO_COMPLETION_SIGNATURE Signature>
  86. class async_result
  87. {
  88. public:
  89. /// The concrete completion handler type for the specific signature.
  90. typedef CompletionToken completion_handler_type;
  91. /// The return type of the initiating function.
  92. typedef void return_type;
  93. /// Construct an async result from a given handler.
  94. /**
  95. * When using a specalised async_result, the constructor has an opportunity
  96. * to initialise some state associated with the completion handler, which is
  97. * then returned from the initiating function.
  98. */
  99. explicit async_result(completion_handler_type& h)
  100. {
  101. (void)h;
  102. }
  103. /// Obtain the value to be returned from the initiating function.
  104. return_type get()
  105. {
  106. }
  107. #if defined(GENERATING_DOCUMENTATION)
  108. /// Initiate the asynchronous operation that will produce the result, and
  109. /// obtain the value to be returned from the initiating function.
  110. template <typename Initiation, typename RawCompletionToken, typename... Args>
  111. static return_type initiate(
  112. BOOST_ASIO_MOVE_ARG(Initiation) initiation,
  113. BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
  114. BOOST_ASIO_MOVE_ARG(Args)... args);
  115. #elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  116. template <typename Initiation,
  117. BOOST_ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken,
  118. typename... Args>
  119. static return_type initiate(
  120. BOOST_ASIO_MOVE_ARG(Initiation) initiation,
  121. BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
  122. BOOST_ASIO_MOVE_ARG(Args)... args)
  123. {
  124. BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
  125. BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token),
  126. BOOST_ASIO_MOVE_CAST(Args)(args)...);
  127. }
  128. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  129. template <typename Initiation,
  130. BOOST_ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken>
  131. static return_type initiate(
  132. BOOST_ASIO_MOVE_ARG(Initiation) initiation,
  133. BOOST_ASIO_MOVE_ARG(RawCompletionToken) token)
  134. {
  135. BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
  136. BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token));
  137. }
  138. #define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
  139. template <typename Initiation, \
  140. BOOST_ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken, \
  141. BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  142. static return_type initiate( \
  143. BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
  144. BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, \
  145. BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
  146. { \
  147. BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( \
  148. BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token), \
  149. BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
  150. } \
  151. /**/
  152. BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
  153. #undef BOOST_ASIO_PRIVATE_INITIATE_DEF
  154. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  155. private:
  156. async_result(const async_result&) BOOST_ASIO_DELETED;
  157. async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
  158. };
  159. #if !defined(GENERATING_DOCUMENTATION)
  160. template <BOOST_ASIO_COMPLETION_SIGNATURE Signature>
  161. class async_result<void, Signature>
  162. {
  163. // Empty.
  164. };
  165. #endif // !defined(GENERATING_DOCUMENTATION)
  166. /// Helper template to deduce the handler type from a CompletionToken, capture
  167. /// a local copy of the handler, and then create an async_result for the
  168. /// handler.
  169. template <typename CompletionToken, BOOST_ASIO_COMPLETION_SIGNATURE Signature>
  170. struct async_completion
  171. {
  172. /// The real handler type to be used for the asynchronous operation.
  173. typedef typename boost::asio::async_result<
  174. typename decay<CompletionToken>::type,
  175. Signature>::completion_handler_type completion_handler_type;
  176. #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  177. /// Constructor.
  178. /**
  179. * The constructor creates the concrete completion handler and makes the link
  180. * between the handler and the asynchronous result.
  181. */
  182. explicit async_completion(CompletionToken& token)
  183. : completion_handler(static_cast<typename conditional<
  184. is_same<CompletionToken, completion_handler_type>::value,
  185. completion_handler_type&, CompletionToken&&>::type>(token)),
  186. result(completion_handler)
  187. {
  188. }
  189. #else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  190. explicit async_completion(typename decay<CompletionToken>::type& token)
  191. : completion_handler(token),
  192. result(completion_handler)
  193. {
  194. }
  195. explicit async_completion(const typename decay<CompletionToken>::type& token)
  196. : completion_handler(token),
  197. result(completion_handler)
  198. {
  199. }
  200. #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  201. /// A copy of, or reference to, a real handler object.
  202. #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  203. typename conditional<
  204. is_same<CompletionToken, completion_handler_type>::value,
  205. completion_handler_type&, completion_handler_type>::type completion_handler;
  206. #else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  207. completion_handler_type completion_handler;
  208. #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  209. /// The result of the asynchronous operation's initiating function.
  210. async_result<typename decay<CompletionToken>::type, Signature> result;
  211. };
  212. namespace detail {
  213. template <typename CompletionToken, typename Signature>
  214. struct async_result_helper
  215. : async_result<typename decay<CompletionToken>::type, Signature>
  216. {
  217. };
  218. struct async_result_memfns_base
  219. {
  220. void initiate();
  221. };
  222. template <typename T>
  223. struct async_result_memfns_derived
  224. : T, async_result_memfns_base
  225. {
  226. };
  227. template <typename T, T>
  228. struct async_result_memfns_check
  229. {
  230. };
  231. template <typename>
  232. char (&async_result_initiate_memfn_helper(...))[2];
  233. template <typename T>
  234. char async_result_initiate_memfn_helper(
  235. async_result_memfns_check<
  236. void (async_result_memfns_base::*)(),
  237. &async_result_memfns_derived<T>::initiate>*);
  238. template <typename CompletionToken, typename Signature>
  239. struct async_result_has_initiate_memfn
  240. : integral_constant<bool, sizeof(async_result_initiate_memfn_helper<
  241. async_result<typename decay<CompletionToken>::type, Signature>
  242. >(0)) != 1>
  243. {
  244. };
  245. } // namespace detail
  246. #if defined(GENERATING_DOCUMENTATION)
  247. # define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
  248. void_or_deduced
  249. #elif defined(_MSC_VER) && (_MSC_VER < 1500)
  250. # define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
  251. typename ::boost::asio::detail::async_result_helper< \
  252. ct, sig>::return_type
  253. #define BOOST_ASIO_HANDLER_TYPE(ct, sig) \
  254. typename ::boost::asio::detail::async_result_helper< \
  255. ct, sig>::completion_handler_type
  256. #else
  257. # define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
  258. typename ::boost::asio::async_result< \
  259. typename ::boost::asio::decay<ct>::type, sig>::return_type
  260. #define BOOST_ASIO_HANDLER_TYPE(ct, sig) \
  261. typename ::boost::asio::async_result< \
  262. typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type
  263. #endif
  264. #if defined(GENERATING_DOCUMENTATION)
  265. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
  266. auto
  267. #elif defined(BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION)
  268. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
  269. auto
  270. #else
  271. # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
  272. BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig)
  273. #endif
  274. #if defined(GENERATING_DOCUMENTATION)
  275. # define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
  276. void_or_deduced
  277. #elif defined(BOOST_ASIO_HAS_DECLTYPE)
  278. # define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
  279. decltype expr
  280. #else
  281. # define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
  282. BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig)
  283. #endif
  284. #if defined(GENERATING_DOCUMENTATION)
  285. template <typename CompletionToken,
  286. completion_signature Signature,
  287. typename Initiation, typename... Args>
  288. void_or_deduced async_initiate(
  289. BOOST_ASIO_MOVE_ARG(Initiation) initiation,
  290. BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken),
  291. BOOST_ASIO_MOVE_ARG(Args)... args);
  292. #elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  293. template <typename CompletionToken,
  294. BOOST_ASIO_COMPLETION_SIGNATURE Signature,
  295. typename Initiation, typename... Args>
  296. inline typename constraint<
  297. detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
  298. BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature,
  299. (async_result<typename decay<CompletionToken>::type,
  300. Signature>::initiate(declval<BOOST_ASIO_MOVE_ARG(Initiation)>(),
  301. declval<BOOST_ASIO_MOVE_ARG(CompletionToken)>(),
  302. declval<BOOST_ASIO_MOVE_ARG(Args)>()...)))>::type
  303. async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
  304. BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
  305. BOOST_ASIO_MOVE_ARG(Args)... args)
  306. {
  307. return async_result<typename decay<CompletionToken>::type,
  308. Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
  309. BOOST_ASIO_MOVE_CAST(CompletionToken)(token),
  310. BOOST_ASIO_MOVE_CAST(Args)(args)...);
  311. }
  312. template <typename CompletionToken,
  313. BOOST_ASIO_COMPLETION_SIGNATURE Signature,
  314. typename Initiation, typename... Args>
  315. inline typename constraint<
  316. !detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
  317. BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
  318. async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
  319. BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
  320. BOOST_ASIO_MOVE_ARG(Args)... args)
  321. {
  322. async_completion<CompletionToken, Signature> completion(token);
  323. BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
  324. BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken,
  325. Signature))(completion.completion_handler),
  326. BOOST_ASIO_MOVE_CAST(Args)(args)...);
  327. return completion.result.get();
  328. }
  329. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  330. template <typename CompletionToken,
  331. BOOST_ASIO_COMPLETION_SIGNATURE Signature,
  332. typename Initiation>
  333. inline typename constraint<
  334. detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
  335. BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature,
  336. (async_result<typename decay<CompletionToken>::type,
  337. Signature>::initiate(declval<BOOST_ASIO_MOVE_ARG(Initiation)>(),
  338. declval<BOOST_ASIO_MOVE_ARG(CompletionToken)>())))>::type
  339. async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
  340. BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
  341. {
  342. return async_result<typename decay<CompletionToken>::type,
  343. Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
  344. BOOST_ASIO_MOVE_CAST(CompletionToken)(token));
  345. }
  346. template <typename CompletionToken,
  347. BOOST_ASIO_COMPLETION_SIGNATURE Signature,
  348. typename Initiation>
  349. inline typename constraint<
  350. !detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
  351. BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
  352. async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
  353. BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
  354. {
  355. async_completion<CompletionToken, Signature> completion(token);
  356. BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
  357. BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken,
  358. Signature))(completion.completion_handler));
  359. return completion.result.get();
  360. }
  361. #define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
  362. template <typename CompletionToken, \
  363. BOOST_ASIO_COMPLETION_SIGNATURE Signature, \
  364. typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  365. inline typename constraint< \
  366. detail::async_result_has_initiate_memfn< \
  367. CompletionToken, Signature>::value, \
  368. BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature, \
  369. (async_result<typename decay<CompletionToken>::type, \
  370. Signature>::initiate(declval<BOOST_ASIO_MOVE_ARG(Initiation)>(), \
  371. declval<BOOST_ASIO_MOVE_ARG(CompletionToken)>(), \
  372. BOOST_ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \
  373. async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
  374. BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
  375. BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
  376. { \
  377. return async_result<typename decay<CompletionToken>::type, \
  378. Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation), \
  379. BOOST_ASIO_MOVE_CAST(CompletionToken)(token), \
  380. BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
  381. } \
  382. \
  383. template <typename CompletionToken, \
  384. BOOST_ASIO_COMPLETION_SIGNATURE Signature, \
  385. typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  386. inline typename constraint< \
  387. !detail::async_result_has_initiate_memfn< \
  388. CompletionToken, Signature>::value, \
  389. BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \
  390. async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
  391. BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
  392. BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
  393. { \
  394. async_completion<CompletionToken, Signature> completion(token); \
  395. \
  396. BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( \
  397. BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken, \
  398. Signature))(completion.completion_handler), \
  399. BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
  400. \
  401. return completion.result.get(); \
  402. } \
  403. /**/
  404. BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
  405. #undef BOOST_ASIO_PRIVATE_INITIATE_DEF
  406. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  407. #if defined(BOOST_ASIO_HAS_CONCEPTS) \
  408. && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
  409. && defined(BOOST_ASIO_HAS_DECLTYPE)
  410. namespace detail {
  411. template <typename Signature>
  412. struct initiation_archetype
  413. {
  414. template <completion_handler_for<Signature> CompletionHandler>
  415. void operator()(CompletionHandler&&) const
  416. {
  417. }
  418. };
  419. } // namespace detail
  420. template <typename T, typename Signature>
  421. BOOST_ASIO_CONCEPT completion_token_for =
  422. detail::is_completion_signature<Signature>::value
  423. &&
  424. requires(T&& t)
  425. {
  426. async_initiate<T, Signature>(detail::initiation_archetype<Signature>{}, t);
  427. };
  428. #define BOOST_ASIO_COMPLETION_TOKEN_FOR(s) \
  429. ::boost::asio::completion_token_for<s>
  430. #else // defined(BOOST_ASIO_HAS_CONCEPTS)
  431. // && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  432. // && defined(BOOST_ASIO_HAS_DECLTYPE)
  433. #define BOOST_ASIO_COMPLETION_TOKEN_FOR(s) typename
  434. #endif // defined(BOOST_ASIO_HAS_CONCEPTS)
  435. // && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  436. // && defined(BOOST_ASIO_HAS_DECLTYPE)
  437. namespace detail {
  438. template <typename T, typename = void>
  439. struct default_completion_token_impl
  440. {
  441. typedef void type;
  442. };
  443. template <typename T>
  444. struct default_completion_token_impl<T,
  445. typename void_type<typename T::default_completion_token_type>::type>
  446. {
  447. typedef typename T::default_completion_token_type type;
  448. };
  449. } // namespace detail
  450. #if defined(GENERATING_DOCUMENTATION)
  451. /// Traits type used to determine the default completion token type associated
  452. /// with a type (such as an executor).
  453. /**
  454. * A program may specialise this traits type if the @c T template parameter in
  455. * the specialisation is a user-defined type.
  456. *
  457. * Specialisations of this trait may provide a nested typedef @c type, which is
  458. * a default-constructible completion token type.
  459. */
  460. template <typename T>
  461. struct default_completion_token
  462. {
  463. /// If @c T has a nested type @c default_completion_token_type,
  464. /// <tt>T::default_completion_token_type</tt>. Otherwise the typedef @c type
  465. /// is not defined.
  466. typedef see_below type;
  467. };
  468. #else
  469. template <typename T>
  470. struct default_completion_token
  471. : detail::default_completion_token_impl<T>
  472. {
  473. };
  474. #endif
  475. #if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
  476. template <typename T>
  477. using default_completion_token_t = typename default_completion_token<T>::type;
  478. #endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
  479. #if defined(BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
  480. #define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) \
  481. = typename ::boost::asio::default_completion_token<e>::type
  482. #define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(e) \
  483. = typename ::boost::asio::default_completion_token<e>::type()
  484. #else // defined(BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
  485. #define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e)
  486. #define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(e)
  487. #endif // defined(BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
  488. } // namespace asio
  489. } // namespace boost
  490. #include <boost/asio/detail/pop_options.hpp>
  491. #endif // BOOST_ASIO_ASYNC_RESULT_HPP