wrapped_handler.hpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. //
  2. // detail/wrapped_handler.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2018 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_alloc_helpers.hpp>
  17. #include <boost/asio/detail/handler_cont_helpers.hpp>
  18. #include <boost/asio/detail/handler_invoke_helpers.hpp>
  19. #include <boost/asio/detail/push_options.hpp>
  20. namespace boost {
  21. namespace asio {
  22. namespace detail {
  23. struct is_continuation_delegated
  24. {
  25. template <typename Dispatcher, typename Handler>
  26. bool operator()(Dispatcher&, Handler& handler) const
  27. {
  28. return boost_asio_handler_cont_helpers::is_continuation(handler);
  29. }
  30. };
  31. struct is_continuation_if_running
  32. {
  33. template <typename Dispatcher, typename Handler>
  34. bool operator()(Dispatcher& dispatcher, Handler&) const
  35. {
  36. return dispatcher.running_in_this_thread();
  37. }
  38. };
  39. template <typename Dispatcher, typename Handler,
  40. typename IsContinuation = is_continuation_delegated>
  41. class wrapped_handler
  42. {
  43. public:
  44. typedef void result_type;
  45. wrapped_handler(Dispatcher dispatcher, Handler& handler)
  46. : dispatcher_(dispatcher),
  47. handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
  48. {
  49. }
  50. #if defined(BOOST_ASIO_HAS_MOVE)
  51. wrapped_handler(const wrapped_handler& other)
  52. : dispatcher_(other.dispatcher_),
  53. handler_(other.handler_)
  54. {
  55. }
  56. wrapped_handler(wrapped_handler&& other)
  57. : dispatcher_(other.dispatcher_),
  58. handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_))
  59. {
  60. }
  61. #endif // defined(BOOST_ASIO_HAS_MOVE)
  62. void operator()()
  63. {
  64. dispatcher_.dispatch(BOOST_ASIO_MOVE_CAST(Handler)(handler_));
  65. }
  66. void operator()() const
  67. {
  68. dispatcher_.dispatch(handler_);
  69. }
  70. template <typename Arg1>
  71. void operator()(const Arg1& arg1)
  72. {
  73. dispatcher_.dispatch(detail::bind_handler(handler_, arg1));
  74. }
  75. template <typename Arg1>
  76. void operator()(const Arg1& arg1) const
  77. {
  78. dispatcher_.dispatch(detail::bind_handler(handler_, arg1));
  79. }
  80. template <typename Arg1, typename Arg2>
  81. void operator()(const Arg1& arg1, const Arg2& arg2)
  82. {
  83. dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2));
  84. }
  85. template <typename Arg1, typename Arg2>
  86. void operator()(const Arg1& arg1, const Arg2& arg2) const
  87. {
  88. dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2));
  89. }
  90. template <typename Arg1, typename Arg2, typename Arg3>
  91. void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3)
  92. {
  93. dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3));
  94. }
  95. template <typename Arg1, typename Arg2, typename Arg3>
  96. void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) const
  97. {
  98. dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3));
  99. }
  100. template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
  101. void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
  102. const Arg4& arg4)
  103. {
  104. dispatcher_.dispatch(
  105. detail::bind_handler(handler_, arg1, arg2, arg3, arg4));
  106. }
  107. template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
  108. void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
  109. const Arg4& arg4) const
  110. {
  111. dispatcher_.dispatch(
  112. detail::bind_handler(handler_, arg1, arg2, arg3, arg4));
  113. }
  114. template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
  115. typename Arg5>
  116. void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
  117. const Arg4& arg4, const Arg5& arg5)
  118. {
  119. dispatcher_.dispatch(
  120. detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5));
  121. }
  122. template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
  123. typename Arg5>
  124. void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
  125. const Arg4& arg4, const Arg5& arg5) const
  126. {
  127. dispatcher_.dispatch(
  128. detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5));
  129. }
  130. //private:
  131. Dispatcher dispatcher_;
  132. Handler handler_;
  133. };
  134. template <typename Handler, typename Context>
  135. class rewrapped_handler
  136. {
  137. public:
  138. explicit rewrapped_handler(Handler& handler, const Context& context)
  139. : context_(context),
  140. handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
  141. {
  142. }
  143. explicit rewrapped_handler(const Handler& handler, const Context& context)
  144. : context_(context),
  145. handler_(handler)
  146. {
  147. }
  148. #if defined(BOOST_ASIO_HAS_MOVE)
  149. rewrapped_handler(const rewrapped_handler& other)
  150. : context_(other.context_),
  151. handler_(other.handler_)
  152. {
  153. }
  154. rewrapped_handler(rewrapped_handler&& other)
  155. : context_(BOOST_ASIO_MOVE_CAST(Context)(other.context_)),
  156. handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_))
  157. {
  158. }
  159. #endif // defined(BOOST_ASIO_HAS_MOVE)
  160. void operator()()
  161. {
  162. handler_();
  163. }
  164. void operator()() const
  165. {
  166. handler_();
  167. }
  168. //private:
  169. Context context_;
  170. Handler handler_;
  171. };
  172. template <typename Dispatcher, typename Handler, typename IsContinuation>
  173. inline void* asio_handler_allocate(std::size_t size,
  174. wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)
  175. {
  176. return boost_asio_handler_alloc_helpers::allocate(
  177. size, this_handler->handler_);
  178. }
  179. template <typename Dispatcher, typename Handler, typename IsContinuation>
  180. inline void asio_handler_deallocate(void* pointer, std::size_t size,
  181. wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)
  182. {
  183. boost_asio_handler_alloc_helpers::deallocate(
  184. pointer, size, this_handler->handler_);
  185. }
  186. template <typename Dispatcher, typename Handler, typename IsContinuation>
  187. inline bool asio_handler_is_continuation(
  188. wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)
  189. {
  190. return IsContinuation()(this_handler->dispatcher_, this_handler->handler_);
  191. }
  192. template <typename Function, typename Dispatcher,
  193. typename Handler, typename IsContinuation>
  194. inline void asio_handler_invoke(Function& function,
  195. wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)
  196. {
  197. this_handler->dispatcher_.dispatch(
  198. rewrapped_handler<Function, Handler>(
  199. function, this_handler->handler_));
  200. }
  201. template <typename Function, typename Dispatcher,
  202. typename Handler, typename IsContinuation>
  203. inline void asio_handler_invoke(const Function& function,
  204. wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)
  205. {
  206. this_handler->dispatcher_.dispatch(
  207. rewrapped_handler<Function, Handler>(
  208. function, this_handler->handler_));
  209. }
  210. template <typename Handler, typename Context>
  211. inline void* asio_handler_allocate(std::size_t size,
  212. rewrapped_handler<Handler, Context>* this_handler)
  213. {
  214. return boost_asio_handler_alloc_helpers::allocate(
  215. size, this_handler->context_);
  216. }
  217. template <typename Handler, typename Context>
  218. inline void asio_handler_deallocate(void* pointer, std::size_t size,
  219. rewrapped_handler<Handler, Context>* this_handler)
  220. {
  221. boost_asio_handler_alloc_helpers::deallocate(
  222. pointer, size, this_handler->context_);
  223. }
  224. template <typename Dispatcher, typename Context>
  225. inline bool asio_handler_is_continuation(
  226. rewrapped_handler<Dispatcher, Context>* this_handler)
  227. {
  228. return boost_asio_handler_cont_helpers::is_continuation(
  229. this_handler->context_);
  230. }
  231. template <typename Function, typename Handler, typename Context>
  232. inline void asio_handler_invoke(Function& function,
  233. rewrapped_handler<Handler, Context>* this_handler)
  234. {
  235. boost_asio_handler_invoke_helpers::invoke(
  236. function, this_handler->context_);
  237. }
  238. template <typename Function, typename Handler, typename Context>
  239. inline void asio_handler_invoke(const Function& function,
  240. rewrapped_handler<Handler, Context>* this_handler)
  241. {
  242. boost_asio_handler_invoke_helpers::invoke(
  243. function, this_handler->context_);
  244. }
  245. } // namespace detail
  246. } // namespace asio
  247. } // namespace boost
  248. #include <boost/asio/detail/pop_options.hpp>
  249. #endif // BOOST_ASIO_DETAIL_WRAPPED_HANDLER_HPP