wrapped_handler.hpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. //
  2. // detail/wrapped_handler.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2025 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_DETAIL_WRAPPED_HANDLER_HPP
  11. #define BOOST_ASIO_DETAIL_WRAPPED_HANDLER_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/bind_handler.hpp>
  16. #include <boost/asio/detail/handler_cont_helpers.hpp>
  17. #include <boost/asio/detail/initiate_dispatch.hpp>
  18. #include <boost/asio/detail/push_options.hpp>
  19. namespace boost {
  20. namespace asio {
  21. namespace detail {
  22. struct is_continuation_delegated
  23. {
  24. template <typename Dispatcher, typename Handler>
  25. bool operator()(Dispatcher&, Handler& handler) const
  26. {
  27. return boost_asio_handler_cont_helpers::is_continuation(handler);
  28. }
  29. };
  30. struct is_continuation_if_running
  31. {
  32. template <typename Dispatcher, typename Handler>
  33. bool operator()(Dispatcher& dispatcher, Handler&) const
  34. {
  35. return dispatcher.running_in_this_thread();
  36. }
  37. };
  38. template <typename Dispatcher, typename = void>
  39. struct wrapped_executor
  40. {
  41. typedef Dispatcher executor_type;
  42. static const Dispatcher& get(const Dispatcher& dispatcher) noexcept
  43. {
  44. return dispatcher;
  45. }
  46. };
  47. template <typename Dispatcher>
  48. struct wrapped_executor<Dispatcher,
  49. void_type<typename Dispatcher::executor_type>>
  50. {
  51. typedef typename Dispatcher::executor_type executor_type;
  52. static executor_type get(const Dispatcher& dispatcher) noexcept
  53. {
  54. return dispatcher.get_executor();
  55. }
  56. };
  57. template <typename Dispatcher, typename Handler,
  58. typename IsContinuation = is_continuation_delegated>
  59. class wrapped_handler
  60. {
  61. public:
  62. typedef void result_type;
  63. typedef typename wrapped_executor<Dispatcher>::executor_type executor_type;
  64. wrapped_handler(Dispatcher dispatcher, Handler& handler)
  65. : dispatcher_(dispatcher),
  66. handler_(static_cast<Handler&&>(handler))
  67. {
  68. }
  69. wrapped_handler(const wrapped_handler& other)
  70. : dispatcher_(other.dispatcher_),
  71. handler_(other.handler_)
  72. {
  73. }
  74. wrapped_handler(wrapped_handler&& other)
  75. : dispatcher_(other.dispatcher_),
  76. handler_(static_cast<Handler&&>(other.handler_))
  77. {
  78. }
  79. executor_type get_executor() const noexcept
  80. {
  81. return wrapped_executor<Dispatcher>::get(dispatcher_);
  82. }
  83. void operator()()
  84. {
  85. detail::initiate_dispatch_with_executor<executor_type>(
  86. this->get_executor())(static_cast<Handler&&>(handler_),
  87. empty_work_function());
  88. }
  89. void operator()() const
  90. {
  91. detail::initiate_dispatch_with_executor<executor_type>(
  92. this->get_executor())(handler_, empty_work_function());
  93. }
  94. template <typename Arg1>
  95. void operator()(const Arg1& arg1)
  96. {
  97. detail::initiate_dispatch_with_executor<executor_type>(
  98. this->get_executor())(detail::bind_handler(handler_, arg1),
  99. empty_work_function());
  100. }
  101. template <typename Arg1>
  102. void operator()(const Arg1& arg1) const
  103. {
  104. detail::initiate_dispatch_with_executor<executor_type>(
  105. this->get_executor())(detail::bind_handler(handler_, arg1),
  106. empty_work_function());
  107. }
  108. template <typename Arg1, typename Arg2>
  109. void operator()(const Arg1& arg1, const Arg2& arg2)
  110. {
  111. detail::initiate_dispatch_with_executor<executor_type>(
  112. this->get_executor())(detail::bind_handler(handler_, arg1, arg2),
  113. empty_work_function());
  114. }
  115. template <typename Arg1, typename Arg2>
  116. void operator()(const Arg1& arg1, const Arg2& arg2) const
  117. {
  118. detail::initiate_dispatch_with_executor<executor_type>(
  119. this->get_executor())(detail::bind_handler(handler_, arg1, arg2),
  120. empty_work_function());
  121. }
  122. template <typename Arg1, typename Arg2, typename Arg3>
  123. void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3)
  124. {
  125. detail::initiate_dispatch_with_executor<executor_type>(
  126. this->get_executor())(detail::bind_handler(handler_, arg1, arg2, arg3),
  127. empty_work_function());
  128. }
  129. template <typename Arg1, typename Arg2, typename Arg3>
  130. void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) const
  131. {
  132. detail::initiate_dispatch_with_executor<executor_type>(
  133. this->get_executor())(detail::bind_handler(handler_, arg1, arg2, arg3),
  134. empty_work_function());
  135. }
  136. template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
  137. void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
  138. const Arg4& arg4)
  139. {
  140. detail::initiate_dispatch_with_executor<executor_type>(
  141. this->get_executor())(
  142. detail::bind_handler(handler_, arg1, arg2, arg3, arg4),
  143. empty_work_function());
  144. }
  145. template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
  146. void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
  147. const Arg4& arg4) const
  148. {
  149. detail::initiate_dispatch_with_executor<executor_type>(
  150. this->get_executor())(
  151. detail::bind_handler(handler_, arg1, arg2, arg3, arg4),
  152. empty_work_function());
  153. }
  154. template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
  155. typename Arg5>
  156. void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
  157. const Arg4& arg4, const Arg5& arg5)
  158. {
  159. detail::initiate_dispatch_with_executor<executor_type>(
  160. this->get_executor())(
  161. detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5),
  162. empty_work_function());
  163. }
  164. template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
  165. typename Arg5>
  166. void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
  167. const Arg4& arg4, const Arg5& arg5) const
  168. {
  169. detail::initiate_dispatch_with_executor<executor_type>(
  170. this->get_executor())(
  171. detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5),
  172. empty_work_function());
  173. }
  174. //private:
  175. Dispatcher dispatcher_;
  176. Handler handler_;
  177. };
  178. template <typename Dispatcher, typename Handler, typename IsContinuation>
  179. inline bool asio_handler_is_continuation(
  180. wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)
  181. {
  182. return IsContinuation()(this_handler->dispatcher_, this_handler->handler_);
  183. }
  184. } // namespace detail
  185. } // namespace asio
  186. } // namespace boost
  187. #include <boost/asio/detail/pop_options.hpp>
  188. #endif // BOOST_ASIO_DETAIL_WRAPPED_HANDLER_HPP