async_result.hpp 19 KB

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