as_tuple.hpp 7.2 KB

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