as_single.hpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. //
  2. // experimental/impl/as_single.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2021 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/associated_executor.hpp>
  18. #include <boost/asio/associated_allocator.hpp>
  19. #include <boost/asio/async_result.hpp>
  20. #include <boost/asio/detail/handler_alloc_helpers.hpp>
  21. #include <boost/asio/detail/handler_cont_helpers.hpp>
  22. #include <boost/asio/detail/handler_invoke_helpers.hpp>
  23. #include <boost/asio/detail/type_traits.hpp>
  24. #include <boost/asio/detail/variadic_templates.hpp>
  25. #include <boost/asio/detail/push_options.hpp>
  26. namespace boost {
  27. namespace asio {
  28. namespace experimental {
  29. namespace detail {
  30. // Class to adapt a as_single_t as a completion handler.
  31. template <typename Handler>
  32. class as_single_handler
  33. {
  34. public:
  35. typedef void result_type;
  36. template <typename CompletionToken>
  37. as_single_handler(as_single_t<CompletionToken> e)
  38. : handler_(BOOST_ASIO_MOVE_CAST(CompletionToken)(e.token_))
  39. {
  40. }
  41. template <typename RedirectedHandler>
  42. as_single_handler(BOOST_ASIO_MOVE_ARG(RedirectedHandler) h)
  43. : handler_(BOOST_ASIO_MOVE_CAST(RedirectedHandler)(h))
  44. {
  45. }
  46. void operator()()
  47. {
  48. handler_();
  49. }
  50. template <typename Arg>
  51. void operator()(BOOST_ASIO_MOVE_ARG(Arg) arg)
  52. {
  53. handler_(BOOST_ASIO_MOVE_CAST(Arg)(arg));
  54. }
  55. template <typename... Args>
  56. void operator()(BOOST_ASIO_MOVE_ARG(Args)... args)
  57. {
  58. handler_(std::make_tuple(BOOST_ASIO_MOVE_CAST(Args)(args)...));
  59. }
  60. //private:
  61. Handler handler_;
  62. };
  63. template <typename Handler>
  64. inline asio_handler_allocate_is_deprecated
  65. asio_handler_allocate(std::size_t size,
  66. as_single_handler<Handler>* this_handler)
  67. {
  68. #if defined(BOOST_ASIO_NO_DEPRECATED)
  69. boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
  70. return asio_handler_allocate_is_no_longer_used();
  71. #else // defined(BOOST_ASIO_NO_DEPRECATED)
  72. return boost_asio_handler_alloc_helpers::allocate(
  73. size, this_handler->handler_);
  74. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  75. }
  76. template <typename Handler>
  77. inline asio_handler_deallocate_is_deprecated
  78. asio_handler_deallocate(void* pointer, std::size_t size,
  79. as_single_handler<Handler>* this_handler)
  80. {
  81. boost_asio_handler_alloc_helpers::deallocate(
  82. pointer, size, this_handler->handler_);
  83. #if defined(BOOST_ASIO_NO_DEPRECATED)
  84. return asio_handler_deallocate_is_no_longer_used();
  85. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  86. }
  87. template <typename Handler>
  88. inline bool asio_handler_is_continuation(
  89. as_single_handler<Handler>* this_handler)
  90. {
  91. return boost_asio_handler_cont_helpers::is_continuation(
  92. this_handler->handler_);
  93. }
  94. template <typename Function, typename Handler>
  95. inline asio_handler_invoke_is_deprecated
  96. asio_handler_invoke(Function& function,
  97. as_single_handler<Handler>* this_handler)
  98. {
  99. boost_asio_handler_invoke_helpers::invoke(
  100. function, this_handler->handler_);
  101. #if defined(BOOST_ASIO_NO_DEPRECATED)
  102. return asio_handler_invoke_is_no_longer_used();
  103. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  104. }
  105. template <typename Function, typename Handler>
  106. inline asio_handler_invoke_is_deprecated
  107. asio_handler_invoke(const Function& function,
  108. as_single_handler<Handler>* this_handler)
  109. {
  110. boost_asio_handler_invoke_helpers::invoke(
  111. function, this_handler->handler_);
  112. #if defined(BOOST_ASIO_NO_DEPRECATED)
  113. return asio_handler_invoke_is_no_longer_used();
  114. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  115. }
  116. template <typename Signature>
  117. struct as_single_signature
  118. {
  119. typedef Signature type;
  120. };
  121. template <typename R>
  122. struct as_single_signature<R()>
  123. {
  124. typedef R type();
  125. };
  126. template <typename R, typename Arg>
  127. struct as_single_signature<R(Arg)>
  128. {
  129. typedef R type(Arg);
  130. };
  131. template <typename R, typename... Args>
  132. struct as_single_signature<R(Args...)>
  133. {
  134. typedef R type(std::tuple<typename decay<Args>::type...>);
  135. };
  136. } // namespace detail
  137. } // namespace experimental
  138. #if !defined(GENERATING_DOCUMENTATION)
  139. template <typename CompletionToken, typename Signature>
  140. struct async_result<experimental::as_single_t<CompletionToken>, Signature>
  141. {
  142. typedef typename async_result<CompletionToken,
  143. typename experimental::detail::as_single_signature<Signature>::type>
  144. ::return_type return_type;
  145. template <typename Initiation>
  146. struct init_wrapper
  147. {
  148. init_wrapper(Initiation init)
  149. : initiation_(BOOST_ASIO_MOVE_CAST(Initiation)(init))
  150. {
  151. }
  152. template <typename Handler, typename... Args>
  153. void operator()(
  154. BOOST_ASIO_MOVE_ARG(Handler) handler,
  155. BOOST_ASIO_MOVE_ARG(Args)... args)
  156. {
  157. BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
  158. experimental::detail::as_single_handler<
  159. typename decay<Handler>::type>(
  160. BOOST_ASIO_MOVE_CAST(Handler)(handler)),
  161. BOOST_ASIO_MOVE_CAST(Args)(args)...);
  162. }
  163. Initiation initiation_;
  164. };
  165. template <typename Initiation, typename RawCompletionToken, typename... Args>
  166. static return_type initiate(
  167. BOOST_ASIO_MOVE_ARG(Initiation) initiation,
  168. BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
  169. BOOST_ASIO_MOVE_ARG(Args)... args)
  170. {
  171. return async_initiate<CompletionToken,
  172. typename experimental::detail::as_single_signature<Signature>::type>(
  173. init_wrapper<typename decay<Initiation>::type>(
  174. BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
  175. token.token_, BOOST_ASIO_MOVE_CAST(Args)(args)...);
  176. }
  177. };
  178. template <typename Handler, typename Executor>
  179. struct associated_executor<
  180. experimental::detail::as_single_handler<Handler>, Executor>
  181. : detail::associated_executor_forwarding_base<Handler, Executor>
  182. {
  183. typedef typename associated_executor<Handler, Executor>::type type;
  184. static type get(
  185. const experimental::detail::as_single_handler<Handler>& h,
  186. const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
  187. {
  188. return associated_executor<Handler, Executor>::get(h.handler_, ex);
  189. }
  190. };
  191. template <typename Handler, typename Allocator>
  192. struct associated_allocator<
  193. experimental::detail::as_single_handler<Handler>, Allocator>
  194. {
  195. typedef typename associated_allocator<Handler, Allocator>::type type;
  196. static type get(
  197. const experimental::detail::as_single_handler<Handler>& h,
  198. const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
  199. {
  200. return associated_allocator<Handler, Allocator>::get(h.handler_, a);
  201. }
  202. };
  203. #endif // !defined(GENERATING_DOCUMENTATION)
  204. } // namespace asio
  205. } // namespace boost
  206. #include <boost/asio/detail/pop_options.hpp>
  207. #endif // BOOST_ASIO_IMPL_EXPERIMENTAL_AS_SINGLE_HPP