prepend.hpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. //
  2. // impl/prepend.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_PREPEND_HPP
  11. #define BOOST_ASIO_IMPL_PREPEND_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 <boost/asio/associator.hpp>
  17. #include <boost/asio/async_result.hpp>
  18. #include <boost/asio/detail/handler_alloc_helpers.hpp>
  19. #include <boost/asio/detail/handler_cont_helpers.hpp>
  20. #include <boost/asio/detail/handler_invoke_helpers.hpp>
  21. #include <boost/asio/detail/type_traits.hpp>
  22. #include <boost/asio/detail/utility.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 prepend_t as a completion handler.
  29. template <typename Handler, typename... Values>
  30. class prepend_handler
  31. {
  32. public:
  33. typedef void result_type;
  34. template <typename H>
  35. prepend_handler(BOOST_ASIO_MOVE_ARG(H) handler, std::tuple<Values...> values)
  36. : handler_(BOOST_ASIO_MOVE_CAST(H)(handler)),
  37. values_(BOOST_ASIO_MOVE_CAST(std::tuple<Values...>)(values))
  38. {
  39. }
  40. template <typename... Args>
  41. void operator()(BOOST_ASIO_MOVE_ARG(Args)... args)
  42. {
  43. this->invoke(
  44. index_sequence_for<Values...>{},
  45. BOOST_ASIO_MOVE_CAST(Args)(args)...);
  46. }
  47. template <std::size_t... I, typename... Args>
  48. void invoke(index_sequence<I...>, BOOST_ASIO_MOVE_ARG(Args)... args)
  49. {
  50. BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
  51. BOOST_ASIO_MOVE_CAST(Values)(std::get<I>(values_))...,
  52. BOOST_ASIO_MOVE_CAST(Args)(args)...);
  53. }
  54. //private:
  55. Handler handler_;
  56. std::tuple<Values...> values_;
  57. };
  58. template <typename Handler>
  59. inline asio_handler_allocate_is_deprecated
  60. asio_handler_allocate(std::size_t size,
  61. prepend_handler<Handler>* this_handler)
  62. {
  63. #if defined(BOOST_ASIO_NO_DEPRECATED)
  64. boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
  65. return asio_handler_allocate_is_no_longer_used();
  66. #else // defined(BOOST_ASIO_NO_DEPRECATED)
  67. return boost_asio_handler_alloc_helpers::allocate(
  68. size, this_handler->handler_);
  69. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  70. }
  71. template <typename Handler>
  72. inline asio_handler_deallocate_is_deprecated
  73. asio_handler_deallocate(void* pointer, std::size_t size,
  74. prepend_handler<Handler>* this_handler)
  75. {
  76. boost_asio_handler_alloc_helpers::deallocate(
  77. pointer, size, this_handler->handler_);
  78. #if defined(BOOST_ASIO_NO_DEPRECATED)
  79. return asio_handler_deallocate_is_no_longer_used();
  80. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  81. }
  82. template <typename Handler>
  83. inline bool asio_handler_is_continuation(
  84. prepend_handler<Handler>* this_handler)
  85. {
  86. return boost_asio_handler_cont_helpers::is_continuation(
  87. this_handler->handler_);
  88. }
  89. template <typename Function, typename Handler>
  90. inline asio_handler_invoke_is_deprecated
  91. asio_handler_invoke(Function& function,
  92. prepend_handler<Handler>* this_handler)
  93. {
  94. boost_asio_handler_invoke_helpers::invoke(
  95. function, this_handler->handler_);
  96. #if defined(BOOST_ASIO_NO_DEPRECATED)
  97. return asio_handler_invoke_is_no_longer_used();
  98. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  99. }
  100. template <typename Function, typename Handler>
  101. inline asio_handler_invoke_is_deprecated
  102. asio_handler_invoke(const Function& function,
  103. prepend_handler<Handler>* this_handler)
  104. {
  105. boost_asio_handler_invoke_helpers::invoke(
  106. function, this_handler->handler_);
  107. #if defined(BOOST_ASIO_NO_DEPRECATED)
  108. return asio_handler_invoke_is_no_longer_used();
  109. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  110. }
  111. template <typename Signature, typename... Values>
  112. struct prepend_signature;
  113. template <typename R, typename... Args, typename... Values>
  114. struct prepend_signature<R(Args...), Values...>
  115. {
  116. typedef R type(Values..., typename decay<Args>::type...);
  117. };
  118. } // namespace detail
  119. #if !defined(GENERATING_DOCUMENTATION)
  120. template <typename CompletionToken, typename... Values, typename Signature>
  121. struct async_result<
  122. prepend_t<CompletionToken, Values...>, Signature>
  123. : async_result<CompletionToken,
  124. typename detail::prepend_signature<
  125. Signature, Values...>::type>
  126. {
  127. typedef typename detail::prepend_signature<
  128. Signature, Values...>::type signature;
  129. template <typename Initiation>
  130. struct init_wrapper
  131. {
  132. init_wrapper(Initiation init)
  133. : initiation_(BOOST_ASIO_MOVE_CAST(Initiation)(init))
  134. {
  135. }
  136. template <typename Handler, typename... Args>
  137. void operator()(
  138. BOOST_ASIO_MOVE_ARG(Handler) handler,
  139. std::tuple<Values...> values,
  140. BOOST_ASIO_MOVE_ARG(Args)... args)
  141. {
  142. BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
  143. detail::prepend_handler<
  144. typename decay<Handler>::type, Values...>(
  145. BOOST_ASIO_MOVE_CAST(Handler)(handler),
  146. BOOST_ASIO_MOVE_CAST(std::tuple<Values...>)(values)),
  147. BOOST_ASIO_MOVE_CAST(Args)(args)...);
  148. }
  149. Initiation initiation_;
  150. };
  151. template <typename Initiation, typename RawCompletionToken, typename... Args>
  152. static BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, signature,
  153. (async_initiate<CompletionToken, signature>(
  154. declval<init_wrapper<typename decay<Initiation>::type> >(),
  155. declval<CompletionToken&>(),
  156. declval<std::tuple<Values...> >(),
  157. declval<BOOST_ASIO_MOVE_ARG(Args)>()...)))
  158. initiate(
  159. BOOST_ASIO_MOVE_ARG(Initiation) initiation,
  160. BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
  161. BOOST_ASIO_MOVE_ARG(Args)... args)
  162. {
  163. return async_initiate<CompletionToken, signature>(
  164. init_wrapper<typename decay<Initiation>::type>(
  165. BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
  166. token.token_,
  167. BOOST_ASIO_MOVE_CAST(std::tuple<Values...>)(token.values_),
  168. BOOST_ASIO_MOVE_CAST(Args)(args)...);
  169. }
  170. };
  171. template <template <typename, typename> class Associator,
  172. typename Handler, typename... Values, typename DefaultCandidate>
  173. struct associator<Associator,
  174. detail::prepend_handler<Handler, Values...>, DefaultCandidate>
  175. : Associator<Handler, DefaultCandidate>
  176. {
  177. static typename Associator<Handler, DefaultCandidate>::type
  178. get(const detail::prepend_handler<Handler, Values...>& h) BOOST_ASIO_NOEXCEPT
  179. {
  180. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  181. }
  182. static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
  183. typename Associator<Handler, DefaultCandidate>::type)
  184. get(const detail::prepend_handler<Handler, Values...>& h,
  185. const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
  186. BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
  187. Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
  188. {
  189. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  190. }
  191. };
  192. #endif // !defined(GENERATING_DOCUMENTATION)
  193. } // namespace asio
  194. } // namespace boost
  195. #include <boost/asio/detail/pop_options.hpp>
  196. #endif // BOOST_ASIO_IMPL_PREPEND_HPP