as_tuple.hpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. //
  2. // impl/as_tuple.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_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/associated_executor.hpp>
  18. #include <boost/asio/associator.hpp>
  19. #include <boost/asio/async_result.hpp>
  20. #include <boost/asio/detail/handler_cont_helpers.hpp>
  21. #include <boost/asio/detail/initiation_base.hpp>
  22. #include <boost/asio/detail/type_traits.hpp>
  23. #include <boost/asio/detail/push_options.hpp>
  24. namespace boost {
  25. namespace asio {
  26. namespace detail {
  27. // Class to adapt a as_tuple_t as a completion handler.
  28. template <typename Handler>
  29. class as_tuple_handler
  30. {
  31. public:
  32. typedef void result_type;
  33. template <typename CompletionToken>
  34. as_tuple_handler(as_tuple_t<CompletionToken> e)
  35. : handler_(static_cast<CompletionToken&&>(e.token_))
  36. {
  37. }
  38. template <typename RedirectedHandler>
  39. as_tuple_handler(RedirectedHandler&& h)
  40. : handler_(static_cast<RedirectedHandler&&>(h))
  41. {
  42. }
  43. template <typename... Args>
  44. void operator()(Args&&... args)
  45. {
  46. static_cast<Handler&&>(handler_)(
  47. std::make_tuple(static_cast<Args&&>(args)...));
  48. }
  49. //private:
  50. Handler handler_;
  51. };
  52. template <typename Handler>
  53. inline bool asio_handler_is_continuation(
  54. as_tuple_handler<Handler>* this_handler)
  55. {
  56. return boost_asio_handler_cont_helpers::is_continuation(
  57. this_handler->handler_);
  58. }
  59. template <typename Signature>
  60. struct as_tuple_signature;
  61. template <typename R, typename... Args>
  62. struct as_tuple_signature<R(Args...)>
  63. {
  64. typedef R type(std::tuple<decay_t<Args>...>);
  65. };
  66. template <typename R, typename... Args>
  67. struct as_tuple_signature<R(Args...) &>
  68. {
  69. typedef R type(std::tuple<decay_t<Args>...>) &;
  70. };
  71. template <typename R, typename... Args>
  72. struct as_tuple_signature<R(Args...) &&>
  73. {
  74. typedef R type(std::tuple<decay_t<Args>...>) &&;
  75. };
  76. #if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  77. template <typename R, typename... Args>
  78. struct as_tuple_signature<R(Args...) noexcept>
  79. {
  80. typedef R type(std::tuple<decay_t<Args>...>) noexcept;
  81. };
  82. template <typename R, typename... Args>
  83. struct as_tuple_signature<R(Args...) & noexcept>
  84. {
  85. typedef R type(std::tuple<decay_t<Args>...>) & noexcept;
  86. };
  87. template <typename R, typename... Args>
  88. struct as_tuple_signature<R(Args...) && noexcept>
  89. {
  90. typedef R type(std::tuple<decay_t<Args>...>) && noexcept;
  91. };
  92. #endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
  93. } // namespace detail
  94. #if !defined(GENERATING_DOCUMENTATION)
  95. template <typename CompletionToken, typename... Signatures>
  96. struct async_result<as_tuple_t<CompletionToken>, Signatures...>
  97. : async_result<CompletionToken,
  98. typename detail::as_tuple_signature<Signatures>::type...>
  99. {
  100. template <typename Initiation>
  101. struct init_wrapper : detail::initiation_base<Initiation>
  102. {
  103. using detail::initiation_base<Initiation>::initiation_base;
  104. template <typename Handler, typename... Args>
  105. void operator()(Handler&& handler, Args&&... args) &&
  106. {
  107. static_cast<Initiation&&>(*this)(
  108. detail::as_tuple_handler<decay_t<Handler>>(
  109. static_cast<Handler&&>(handler)),
  110. static_cast<Args&&>(args)...);
  111. }
  112. template <typename Handler, typename... Args>
  113. void operator()(Handler&& handler, Args&&... args) const &
  114. {
  115. static_cast<const Initiation&>(*this)(
  116. detail::as_tuple_handler<decay_t<Handler>>(
  117. static_cast<Handler&&>(handler)),
  118. static_cast<Args&&>(args)...);
  119. }
  120. };
  121. template <typename Initiation, typename RawCompletionToken, typename... Args>
  122. static auto initiate(Initiation&& initiation,
  123. RawCompletionToken&& token, Args&&... args)
  124. -> decltype(
  125. async_initiate<
  126. conditional_t<
  127. is_const<remove_reference_t<RawCompletionToken>>::value,
  128. const CompletionToken, CompletionToken>,
  129. typename detail::as_tuple_signature<Signatures>::type...>(
  130. init_wrapper<decay_t<Initiation>>(
  131. static_cast<Initiation&&>(initiation)),
  132. token.token_, static_cast<Args&&>(args)...))
  133. {
  134. return async_initiate<
  135. conditional_t<
  136. is_const<remove_reference_t<RawCompletionToken>>::value,
  137. const CompletionToken, CompletionToken>,
  138. typename detail::as_tuple_signature<Signatures>::type...>(
  139. init_wrapper<decay_t<Initiation>>(
  140. static_cast<Initiation&&>(initiation)),
  141. token.token_, static_cast<Args&&>(args)...);
  142. }
  143. };
  144. #if defined(BOOST_ASIO_MSVC)
  145. // Workaround for MSVC internal compiler error.
  146. template <typename CompletionToken, typename Signature>
  147. struct async_result<as_tuple_t<CompletionToken>, Signature>
  148. : async_result<CompletionToken,
  149. typename detail::as_tuple_signature<Signature>::type>
  150. {
  151. template <typename Initiation>
  152. struct init_wrapper : detail::initiation_base<Initiation>
  153. {
  154. using detail::initiation_base<Initiation>::initiation_base;
  155. template <typename Handler, typename... Args>
  156. void operator()(Handler&& handler, Args&&... args) &&
  157. {
  158. static_cast<Initiation&&>(*this)(
  159. detail::as_tuple_handler<decay_t<Handler>>(
  160. static_cast<Handler&&>(handler)),
  161. static_cast<Args&&>(args)...);
  162. }
  163. template <typename Handler, typename... Args>
  164. void operator()(Handler&& handler, Args&&... args) const &
  165. {
  166. static_cast<const Initiation&>(*this)(
  167. detail::as_tuple_handler<decay_t<Handler>>(
  168. static_cast<Handler&&>(handler)),
  169. static_cast<Args&&>(args)...);
  170. }
  171. };
  172. template <typename Initiation, typename RawCompletionToken, typename... Args>
  173. static auto initiate(Initiation&& initiation,
  174. RawCompletionToken&& token, Args&&... args)
  175. -> decltype(
  176. async_initiate<
  177. conditional_t<
  178. is_const<remove_reference_t<RawCompletionToken>>::value,
  179. const CompletionToken, CompletionToken>,
  180. typename detail::as_tuple_signature<Signature>::type>(
  181. init_wrapper<decay_t<Initiation>>(
  182. static_cast<Initiation&&>(initiation)),
  183. token.token_, static_cast<Args&&>(args)...))
  184. {
  185. return async_initiate<
  186. conditional_t<
  187. is_const<remove_reference_t<RawCompletionToken>>::value,
  188. const CompletionToken, CompletionToken>,
  189. typename detail::as_tuple_signature<Signature>::type>(
  190. init_wrapper<decay_t<Initiation>>(
  191. static_cast<Initiation&&>(initiation)),
  192. token.token_, static_cast<Args&&>(args)...);
  193. }
  194. };
  195. #endif // defined(BOOST_ASIO_MSVC)
  196. template <template <typename, typename> class Associator,
  197. typename Handler, typename DefaultCandidate>
  198. struct associator<Associator,
  199. detail::as_tuple_handler<Handler>, DefaultCandidate>
  200. : Associator<Handler, DefaultCandidate>
  201. {
  202. static typename Associator<Handler, DefaultCandidate>::type get(
  203. const detail::as_tuple_handler<Handler>& h) noexcept
  204. {
  205. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  206. }
  207. static auto get(const detail::as_tuple_handler<Handler>& h,
  208. const DefaultCandidate& c) noexcept
  209. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  210. {
  211. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  212. }
  213. };
  214. template <typename... Signatures>
  215. struct async_result<partial_as_tuple, Signatures...>
  216. {
  217. template <typename Initiation, typename RawCompletionToken, typename... Args>
  218. static auto initiate(Initiation&& initiation,
  219. RawCompletionToken&&, Args&&... args)
  220. -> decltype(
  221. async_initiate<Signatures...>(
  222. static_cast<Initiation&&>(initiation),
  223. as_tuple_t<
  224. default_completion_token_t<associated_executor_t<Initiation>>>{},
  225. static_cast<Args&&>(args)...))
  226. {
  227. return async_initiate<Signatures...>(
  228. static_cast<Initiation&&>(initiation),
  229. as_tuple_t<
  230. default_completion_token_t<associated_executor_t<Initiation>>>{},
  231. static_cast<Args&&>(args)...);
  232. }
  233. };
  234. #endif // !defined(GENERATING_DOCUMENTATION)
  235. } // namespace asio
  236. } // namespace boost
  237. #include <boost/asio/detail/pop_options.hpp>
  238. #endif // BOOST_ASIO_IMPL_AS_TUPLE_HPP