as_tuple.hpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. //
  2. // impl/as_tuple.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_IMPL_AS_TUPLE_HPP
  11. #define BOOST_ASIO_IMPL_AS_TUPLE_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 <tuple>
  17. #include <boost/asio/associator.hpp>
  18. #include <boost/asio/async_result.hpp>
  19. #include <boost/asio/detail/handler_alloc_helpers.hpp>
  20. #include <boost/asio/detail/handler_cont_helpers.hpp>
  21. #include <boost/asio/detail/handler_invoke_helpers.hpp>
  22. #include <boost/asio/detail/type_traits.hpp>
  23. #include <boost/asio/detail/variadic_templates.hpp>
  24. #include <boost/asio/detail/push_options.hpp>
  25. namespace boost {
  26. namespace asio {
  27. namespace detail {
  28. // Class to adapt a as_tuple_t as a completion handler.
  29. template <typename Handler>
  30. class as_tuple_handler
  31. {
  32. public:
  33. typedef void result_type;
  34. template <typename CompletionToken>
  35. as_tuple_handler(as_tuple_t<CompletionToken> e)
  36. : handler_(BOOST_ASIO_MOVE_CAST(CompletionToken)(e.token_))
  37. {
  38. }
  39. template <typename RedirectedHandler>
  40. as_tuple_handler(BOOST_ASIO_MOVE_ARG(RedirectedHandler) h)
  41. : handler_(BOOST_ASIO_MOVE_CAST(RedirectedHandler)(h))
  42. {
  43. }
  44. template <typename... Args>
  45. void operator()(BOOST_ASIO_MOVE_ARG(Args)... args)
  46. {
  47. BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
  48. std::make_tuple(BOOST_ASIO_MOVE_CAST(Args)(args)...));
  49. }
  50. //private:
  51. Handler handler_;
  52. };
  53. template <typename Handler>
  54. inline asio_handler_allocate_is_deprecated
  55. asio_handler_allocate(std::size_t size,
  56. as_tuple_handler<Handler>* this_handler)
  57. {
  58. #if defined(BOOST_ASIO_NO_DEPRECATED)
  59. boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
  60. return asio_handler_allocate_is_no_longer_used();
  61. #else // defined(BOOST_ASIO_NO_DEPRECATED)
  62. return boost_asio_handler_alloc_helpers::allocate(
  63. size, this_handler->handler_);
  64. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  65. }
  66. template <typename Handler>
  67. inline asio_handler_deallocate_is_deprecated
  68. asio_handler_deallocate(void* pointer, std::size_t size,
  69. as_tuple_handler<Handler>* this_handler)
  70. {
  71. boost_asio_handler_alloc_helpers::deallocate(
  72. pointer, size, this_handler->handler_);
  73. #if defined(BOOST_ASIO_NO_DEPRECATED)
  74. return asio_handler_deallocate_is_no_longer_used();
  75. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  76. }
  77. template <typename Handler>
  78. inline bool asio_handler_is_continuation(
  79. as_tuple_handler<Handler>* this_handler)
  80. {
  81. return boost_asio_handler_cont_helpers::is_continuation(
  82. this_handler->handler_);
  83. }
  84. template <typename Function, typename Handler>
  85. inline asio_handler_invoke_is_deprecated
  86. asio_handler_invoke(Function& function,
  87. as_tuple_handler<Handler>* this_handler)
  88. {
  89. boost_asio_handler_invoke_helpers::invoke(
  90. function, this_handler->handler_);
  91. #if defined(BOOST_ASIO_NO_DEPRECATED)
  92. return asio_handler_invoke_is_no_longer_used();
  93. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  94. }
  95. template <typename Function, typename Handler>
  96. inline asio_handler_invoke_is_deprecated
  97. asio_handler_invoke(const Function& function,
  98. as_tuple_handler<Handler>* this_handler)
  99. {
  100. boost_asio_handler_invoke_helpers::invoke(
  101. function, this_handler->handler_);
  102. #if defined(BOOST_ASIO_NO_DEPRECATED)
  103. return asio_handler_invoke_is_no_longer_used();
  104. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  105. }
  106. template <typename Signature>
  107. struct as_tuple_signature;
  108. template <typename R, typename... Args>
  109. struct as_tuple_signature<R(Args...)>
  110. {
  111. typedef R type(std::tuple<typename decay<Args>::type...>);
  112. };
  113. #if defined(BOOST_ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
  114. template <typename R, typename... Args>
  115. struct as_tuple_signature<R(Args...) &>
  116. {
  117. typedef R type(std::tuple<typename decay<Args>::type...>) &;
  118. };
  119. template <typename R, typename... Args>
  120. struct as_tuple_signature<R(Args...) &&>
  121. {
  122. typedef R type(std::tuple<typename decay<Args>::type...>) &&;
  123. };
  124. # if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  125. template <typename R, typename... Args>
  126. struct as_tuple_signature<R(Args...) noexcept>
  127. {
  128. typedef R type(std::tuple<typename decay<Args>::type...>) noexcept;
  129. };
  130. template <typename R, typename... Args>
  131. struct as_tuple_signature<R(Args...) & noexcept>
  132. {
  133. typedef R type(std::tuple<typename decay<Args>::type...>) & noexcept;
  134. };
  135. template <typename R, typename... Args>
  136. struct as_tuple_signature<R(Args...) && noexcept>
  137. {
  138. typedef R type(std::tuple<typename decay<Args>::type...>) && noexcept;
  139. };
  140. # endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  141. #endif // defined(BOOST_ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
  142. } // namespace detail
  143. #if !defined(GENERATING_DOCUMENTATION)
  144. template <typename CompletionToken, typename... Signatures>
  145. struct async_result<as_tuple_t<CompletionToken>, Signatures...>
  146. : async_result<CompletionToken,
  147. typename detail::as_tuple_signature<Signatures>::type...>
  148. {
  149. template <typename Initiation>
  150. struct init_wrapper
  151. {
  152. init_wrapper(Initiation init)
  153. : initiation_(BOOST_ASIO_MOVE_CAST(Initiation)(init))
  154. {
  155. }
  156. template <typename Handler, typename... Args>
  157. void operator()(
  158. BOOST_ASIO_MOVE_ARG(Handler) handler,
  159. BOOST_ASIO_MOVE_ARG(Args)... args)
  160. {
  161. BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
  162. detail::as_tuple_handler<
  163. typename decay<Handler>::type>(
  164. BOOST_ASIO_MOVE_CAST(Handler)(handler)),
  165. BOOST_ASIO_MOVE_CAST(Args)(args)...);
  166. }
  167. Initiation initiation_;
  168. };
  169. template <typename Initiation, typename RawCompletionToken, typename... Args>
  170. static BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,
  171. typename detail::as_tuple_signature<Signatures>::type...)
  172. initiate(
  173. BOOST_ASIO_MOVE_ARG(Initiation) initiation,
  174. BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
  175. BOOST_ASIO_MOVE_ARG(Args)... args)
  176. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
  177. async_initiate<
  178. typename conditional<
  179. is_const<typename remove_reference<RawCompletionToken>::type>::value,
  180. const CompletionToken, CompletionToken>::type,
  181. typename detail::as_tuple_signature<Signatures>::type...>(
  182. init_wrapper<typename decay<Initiation>::type>(
  183. BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
  184. token.token_, BOOST_ASIO_MOVE_CAST(Args)(args)...)))
  185. {
  186. return async_initiate<
  187. typename conditional<
  188. is_const<typename remove_reference<RawCompletionToken>::type>::value,
  189. const CompletionToken, CompletionToken>::type,
  190. typename detail::as_tuple_signature<Signatures>::type...>(
  191. init_wrapper<typename decay<Initiation>::type>(
  192. BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
  193. token.token_, BOOST_ASIO_MOVE_CAST(Args)(args)...);
  194. }
  195. };
  196. #if defined(BOOST_ASIO_MSVC)
  197. // Workaround for MSVC internal compiler error.
  198. template <typename CompletionToken, typename Signature>
  199. struct async_result<as_tuple_t<CompletionToken>, Signature>
  200. : async_result<CompletionToken,
  201. typename detail::as_tuple_signature<Signature>::type>
  202. {
  203. template <typename Initiation>
  204. struct init_wrapper
  205. {
  206. init_wrapper(Initiation init)
  207. : initiation_(BOOST_ASIO_MOVE_CAST(Initiation)(init))
  208. {
  209. }
  210. template <typename Handler, typename... Args>
  211. void operator()(
  212. BOOST_ASIO_MOVE_ARG(Handler) handler,
  213. BOOST_ASIO_MOVE_ARG(Args)... args)
  214. {
  215. BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
  216. detail::as_tuple_handler<
  217. typename decay<Handler>::type>(
  218. BOOST_ASIO_MOVE_CAST(Handler)(handler)),
  219. BOOST_ASIO_MOVE_CAST(Args)(args)...);
  220. }
  221. Initiation initiation_;
  222. };
  223. template <typename Initiation, typename RawCompletionToken, typename... Args>
  224. static BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,
  225. typename detail::as_tuple_signature<Signatures>::type...)
  226. initiate(
  227. BOOST_ASIO_MOVE_ARG(Initiation) initiation,
  228. BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
  229. BOOST_ASIO_MOVE_ARG(Args)... args)
  230. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
  231. async_initiate<
  232. typename conditional<
  233. is_const<typename remove_reference<RawCompletionToken>::type>::value,
  234. const CompletionToken, CompletionToken>::type,
  235. typename detail::as_tuple_signature<Signature>::type>(
  236. init_wrapper<typename decay<Initiation>::type>(
  237. BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
  238. token.token_, BOOST_ASIO_MOVE_CAST(Args)(args)...)))
  239. {
  240. return async_initiate<
  241. typename conditional<
  242. is_const<typename remove_reference<RawCompletionToken>::type>::value,
  243. const CompletionToken, CompletionToken>::type,
  244. typename detail::as_tuple_signature<Signature>::type>(
  245. init_wrapper<typename decay<Initiation>::type>(
  246. BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
  247. token.token_, BOOST_ASIO_MOVE_CAST(Args)(args)...);
  248. }
  249. };
  250. #endif // defined(BOOST_ASIO_MSVC)
  251. template <template <typename, typename> class Associator,
  252. typename Handler, typename DefaultCandidate>
  253. struct associator<Associator,
  254. detail::as_tuple_handler<Handler>, DefaultCandidate>
  255. : Associator<Handler, DefaultCandidate>
  256. {
  257. static typename Associator<Handler, DefaultCandidate>::type
  258. get(const detail::as_tuple_handler<Handler>& h) BOOST_ASIO_NOEXCEPT
  259. {
  260. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  261. }
  262. static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
  263. typename Associator<Handler, DefaultCandidate>::type)
  264. get(const detail::as_tuple_handler<Handler>& h,
  265. const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
  266. BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
  267. Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
  268. {
  269. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  270. }
  271. };
  272. #endif // !defined(GENERATING_DOCUMENTATION)
  273. } // namespace asio
  274. } // namespace boost
  275. #include <boost/asio/detail/pop_options.hpp>
  276. #endif // BOOST_ASIO_IMPL_AS_TUPLE_HPP