as_single.hpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. //
  2. // experimental/impl/as_single.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_EXPERIMENTAL_AS_SINGLE_HPP
  11. #define BOOST_ASIO_IMPL_EXPERIMENTAL_AS_SINGLE_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/initiation_base.hpp>
  21. #include <boost/asio/detail/type_traits.hpp>
  22. #include <boost/asio/detail/push_options.hpp>
  23. namespace boost {
  24. namespace asio {
  25. namespace experimental {
  26. namespace detail {
  27. // Class to adapt a as_single_t as a completion handler.
  28. template <typename Handler>
  29. class as_single_handler
  30. {
  31. public:
  32. typedef void result_type;
  33. template <typename CompletionToken>
  34. as_single_handler(as_single_t<CompletionToken> e)
  35. : handler_(static_cast<CompletionToken&&>(e.token_))
  36. {
  37. }
  38. template <typename RedirectedHandler>
  39. as_single_handler(RedirectedHandler&& h)
  40. : handler_(static_cast<RedirectedHandler&&>(h))
  41. {
  42. }
  43. void operator()()
  44. {
  45. static_cast<Handler&&>(handler_)();
  46. }
  47. template <typename Arg>
  48. void operator()(Arg&& arg)
  49. {
  50. static_cast<Handler&&>(handler_)(static_cast<Arg&&>(arg));
  51. }
  52. template <typename... Args>
  53. void operator()(Args&&... args)
  54. {
  55. static_cast<Handler&&>(handler_)(
  56. std::make_tuple(static_cast<Args&&>(args)...));
  57. }
  58. //private:
  59. Handler handler_;
  60. };
  61. template <typename Handler>
  62. inline bool asio_handler_is_continuation(
  63. as_single_handler<Handler>* this_handler)
  64. {
  65. return boost_asio_handler_cont_helpers::is_continuation(
  66. this_handler->handler_);
  67. }
  68. template <typename Signature>
  69. struct as_single_signature
  70. {
  71. typedef Signature type;
  72. };
  73. template <typename R>
  74. struct as_single_signature<R()>
  75. {
  76. typedef R type();
  77. };
  78. template <typename R, typename Arg>
  79. struct as_single_signature<R(Arg)>
  80. {
  81. typedef R type(Arg);
  82. };
  83. template <typename R, typename... Args>
  84. struct as_single_signature<R(Args...)>
  85. {
  86. typedef R type(std::tuple<decay_t<Args>...>);
  87. };
  88. } // namespace detail
  89. } // namespace experimental
  90. #if !defined(GENERATING_DOCUMENTATION)
  91. template <typename CompletionToken, typename Signature>
  92. struct async_result<experimental::as_single_t<CompletionToken>, Signature>
  93. {
  94. template <typename Initiation>
  95. struct init_wrapper : detail::initiation_base<Initiation>
  96. {
  97. using detail::initiation_base<Initiation>::initiation_base;
  98. template <typename Handler, typename... Args>
  99. void operator()(Handler&& handler, Args&&... args) &&
  100. {
  101. static_cast<Initiation&&>(*this)(
  102. experimental::detail::as_single_handler<decay_t<Handler>>(
  103. static_cast<Handler&&>(handler)),
  104. static_cast<Args&&>(args)...);
  105. }
  106. template <typename Handler, typename... Args>
  107. void operator()(Handler&& handler, Args&&... args) const &
  108. {
  109. static_cast<const Initiation&>(*this)(
  110. experimental::detail::as_single_handler<decay_t<Handler>>(
  111. static_cast<Handler&&>(handler)),
  112. static_cast<Args&&>(args)...);
  113. }
  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<CompletionToken,
  120. typename experimental::detail::as_single_signature<Signature>::type>(
  121. init_wrapper<decay_t<Initiation>>(
  122. static_cast<Initiation&&>(initiation)),
  123. token.token_, static_cast<Args&&>(args)...))
  124. {
  125. return async_initiate<CompletionToken,
  126. typename experimental::detail::as_single_signature<Signature>::type>(
  127. init_wrapper<decay_t<Initiation>>(
  128. static_cast<Initiation&&>(initiation)),
  129. token.token_, static_cast<Args&&>(args)...);
  130. }
  131. };
  132. template <template <typename, typename> class Associator,
  133. typename Handler, typename DefaultCandidate>
  134. struct associator<Associator,
  135. experimental::detail::as_single_handler<Handler>, DefaultCandidate>
  136. : Associator<Handler, DefaultCandidate>
  137. {
  138. static typename Associator<Handler, DefaultCandidate>::type get(
  139. const experimental::detail::as_single_handler<Handler>& h) noexcept
  140. {
  141. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  142. }
  143. static auto get(const experimental::detail::as_single_handler<Handler>& h,
  144. const DefaultCandidate& c) noexcept
  145. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  146. {
  147. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  148. }
  149. };
  150. #endif // !defined(GENERATING_DOCUMENTATION)
  151. } // namespace asio
  152. } // namespace boost
  153. #include <boost/asio/detail/pop_options.hpp>
  154. #endif // BOOST_ASIO_IMPL_EXPERIMENTAL_AS_SINGLE_HPP