append.hpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. //
  2. // experimental/impl/append.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2022 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 ASIO_IMPL_EXPERIMENTAL_APPEND_HPP
  11. #define ASIO_IMPL_EXPERIMENTAL_APPEND_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include "asio/associator.hpp"
  17. #include "asio/async_result.hpp"
  18. #include "asio/detail/handler_alloc_helpers.hpp"
  19. #include "asio/detail/handler_cont_helpers.hpp"
  20. #include "asio/detail/handler_invoke_helpers.hpp"
  21. #include "asio/detail/type_traits.hpp"
  22. #include "asio/detail/variadic_templates.hpp"
  23. #include "asio/detail/push_options.hpp"
  24. namespace asio {
  25. namespace experimental {
  26. namespace detail {
  27. // Class to adapt a append_t as a completion handler.
  28. template <typename Handler, typename... Values>
  29. class append_handler
  30. {
  31. public:
  32. typedef void result_type;
  33. template <typename H>
  34. append_handler(ASIO_MOVE_ARG(H) handler, std::tuple<Values...> values)
  35. : handler_(ASIO_MOVE_CAST(H)(handler)),
  36. values_(ASIO_MOVE_CAST(std::tuple<Values...>)(values))
  37. {
  38. }
  39. template <typename... Args>
  40. void operator()(ASIO_MOVE_ARG(Args)... args)
  41. {
  42. this->invoke(
  43. std::make_index_sequence<sizeof...(Values)>{},
  44. ASIO_MOVE_CAST(Args)(args)...);
  45. }
  46. template <std::size_t... I, typename... Args>
  47. void invoke(std::index_sequence<I...>, ASIO_MOVE_ARG(Args)... args)
  48. {
  49. ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
  50. ASIO_MOVE_CAST(Args)(args)...,
  51. ASIO_MOVE_CAST(Values)(std::get<I>(values_))...);
  52. }
  53. //private:
  54. Handler handler_;
  55. std::tuple<Values...> values_;
  56. };
  57. template <typename Handler>
  58. inline asio_handler_allocate_is_deprecated
  59. asio_handler_allocate(std::size_t size,
  60. append_handler<Handler>* this_handler)
  61. {
  62. #if defined(ASIO_NO_DEPRECATED)
  63. asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
  64. return asio_handler_allocate_is_no_longer_used();
  65. #else // defined(ASIO_NO_DEPRECATED)
  66. return asio_handler_alloc_helpers::allocate(
  67. size, this_handler->handler_);
  68. #endif // defined(ASIO_NO_DEPRECATED)
  69. }
  70. template <typename Handler>
  71. inline asio_handler_deallocate_is_deprecated
  72. asio_handler_deallocate(void* pointer, std::size_t size,
  73. append_handler<Handler>* this_handler)
  74. {
  75. asio_handler_alloc_helpers::deallocate(
  76. pointer, size, this_handler->handler_);
  77. #if defined(ASIO_NO_DEPRECATED)
  78. return asio_handler_deallocate_is_no_longer_used();
  79. #endif // defined(ASIO_NO_DEPRECATED)
  80. }
  81. template <typename Handler>
  82. inline bool asio_handler_is_continuation(
  83. append_handler<Handler>* this_handler)
  84. {
  85. return asio_handler_cont_helpers::is_continuation(
  86. this_handler->handler_);
  87. }
  88. template <typename Function, typename Handler>
  89. inline asio_handler_invoke_is_deprecated
  90. asio_handler_invoke(Function& function,
  91. append_handler<Handler>* this_handler)
  92. {
  93. asio_handler_invoke_helpers::invoke(
  94. function, this_handler->handler_);
  95. #if defined(ASIO_NO_DEPRECATED)
  96. return asio_handler_invoke_is_no_longer_used();
  97. #endif // defined(ASIO_NO_DEPRECATED)
  98. }
  99. template <typename Function, typename Handler>
  100. inline asio_handler_invoke_is_deprecated
  101. asio_handler_invoke(const Function& function,
  102. append_handler<Handler>* this_handler)
  103. {
  104. asio_handler_invoke_helpers::invoke(
  105. function, this_handler->handler_);
  106. #if defined(ASIO_NO_DEPRECATED)
  107. return asio_handler_invoke_is_no_longer_used();
  108. #endif // defined(ASIO_NO_DEPRECATED)
  109. }
  110. template <typename Signature, typename... Values>
  111. struct append_signature;
  112. template <typename R, typename... Args, typename... Values>
  113. struct append_signature<R(Args...), Values...>
  114. {
  115. typedef R type(typename decay<Args>::type..., Values...);
  116. };
  117. } // namespace detail
  118. } // namespace experimental
  119. #if !defined(GENERATING_DOCUMENTATION)
  120. template <typename CompletionToken, typename... Values, typename Signature>
  121. struct async_result<
  122. experimental::append_t<CompletionToken, Values...>, Signature>
  123. : async_result<CompletionToken,
  124. typename experimental::detail::append_signature<
  125. Signature, Values...>::type>
  126. {
  127. typedef typename experimental::detail::append_signature<
  128. Signature, Values...>::type signature;
  129. template <typename Initiation>
  130. struct init_wrapper
  131. {
  132. init_wrapper(Initiation init)
  133. : initiation_(ASIO_MOVE_CAST(Initiation)(init))
  134. {
  135. }
  136. template <typename Handler, typename... Args>
  137. void operator()(
  138. ASIO_MOVE_ARG(Handler) handler,
  139. std::tuple<Values...> values,
  140. ASIO_MOVE_ARG(Args)... args)
  141. {
  142. ASIO_MOVE_CAST(Initiation)(initiation_)(
  143. experimental::detail::append_handler<
  144. typename decay<Handler>::type, Values...>(
  145. ASIO_MOVE_CAST(Handler)(handler),
  146. ASIO_MOVE_CAST(std::tuple<Values...>)(values)),
  147. ASIO_MOVE_CAST(Args)(args)...);
  148. }
  149. Initiation initiation_;
  150. };
  151. template <typename Initiation, typename RawCompletionToken, typename... Args>
  152. static 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<ASIO_MOVE_ARG(Args)>()...)))
  158. initiate(
  159. ASIO_MOVE_ARG(Initiation) initiation,
  160. ASIO_MOVE_ARG(RawCompletionToken) token,
  161. ASIO_MOVE_ARG(Args)... args)
  162. {
  163. return async_initiate<CompletionToken, signature>(
  164. init_wrapper<typename decay<Initiation>::type>(
  165. ASIO_MOVE_CAST(Initiation)(initiation)),
  166. token.token_,
  167. ASIO_MOVE_CAST(std::tuple<Values...>)(token.values_),
  168. 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. experimental::detail::append_handler<Handler, Values...>, DefaultCandidate>
  175. : Associator<Handler, DefaultCandidate>
  176. {
  177. static typename Associator<Handler, DefaultCandidate>::type get(
  178. const experimental::detail::append_handler<Handler, Values...>& h,
  179. const DefaultCandidate& c = DefaultCandidate()) ASIO_NOEXCEPT
  180. {
  181. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  182. }
  183. };
  184. #endif // !defined(GENERATING_DOCUMENTATION)
  185. } // namespace asio
  186. #include "asio/detail/pop_options.hpp"
  187. #endif // ASIO_IMPL_EXPERIMENTAL_APPEND_HPP