initiate_defer.hpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. //
  2. // detail/initiate_defer.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_DETAIL_INITIATE_DEFER_HPP
  11. #define BOOST_ASIO_DETAIL_INITIATE_DEFER_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/associated_allocator.hpp>
  17. #include <boost/asio/associated_executor.hpp>
  18. #include <boost/asio/detail/work_dispatcher.hpp>
  19. #include <boost/asio/execution/allocator.hpp>
  20. #include <boost/asio/execution/blocking.hpp>
  21. #include <boost/asio/execution/relationship.hpp>
  22. #include <boost/asio/prefer.hpp>
  23. #include <boost/asio/require.hpp>
  24. #include <boost/asio/detail/push_options.hpp>
  25. namespace boost {
  26. namespace asio {
  27. namespace detail {
  28. class initiate_defer
  29. {
  30. public:
  31. template <typename CompletionHandler>
  32. void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
  33. typename enable_if<
  34. execution::is_executor<
  35. typename associated_executor<
  36. typename decay<CompletionHandler>::type
  37. >::type
  38. >::value
  39. >::type* = 0) const
  40. {
  41. typedef typename decay<CompletionHandler>::type handler_t;
  42. typename associated_executor<handler_t>::type ex(
  43. (get_associated_executor)(handler));
  44. typename associated_allocator<handler_t>::type alloc(
  45. (get_associated_allocator)(handler));
  46. #if defined(BOOST_ASIO_NO_DEPRECATED)
  47. boost::asio::prefer(
  48. boost::asio::require(ex, execution::blocking.never),
  49. execution::relationship.continuation,
  50. execution::allocator(alloc)
  51. ).execute(
  52. boost::asio::detail::bind_handler(
  53. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)));
  54. #else // defined(BOOST_ASIO_NO_DEPRECATED)
  55. execution::execute(
  56. boost::asio::prefer(
  57. boost::asio::require(ex, execution::blocking.never),
  58. execution::relationship.continuation,
  59. execution::allocator(alloc)),
  60. boost::asio::detail::bind_handler(
  61. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)));
  62. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  63. }
  64. template <typename CompletionHandler>
  65. void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
  66. typename enable_if<
  67. !execution::is_executor<
  68. typename associated_executor<
  69. typename decay<CompletionHandler>::type
  70. >::type
  71. >::value
  72. >::type* = 0) const
  73. {
  74. typedef typename decay<CompletionHandler>::type handler_t;
  75. typename associated_executor<handler_t>::type ex(
  76. (get_associated_executor)(handler));
  77. typename associated_allocator<handler_t>::type alloc(
  78. (get_associated_allocator)(handler));
  79. ex.defer(boost::asio::detail::bind_handler(
  80. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
  81. }
  82. };
  83. template <typename Executor>
  84. class initiate_defer_with_executor
  85. {
  86. public:
  87. typedef Executor executor_type;
  88. explicit initiate_defer_with_executor(const Executor& ex)
  89. : ex_(ex)
  90. {
  91. }
  92. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  93. {
  94. return ex_;
  95. }
  96. template <typename CompletionHandler>
  97. void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
  98. typename enable_if<
  99. execution::is_executor<
  100. typename conditional<true, executor_type, CompletionHandler>::type
  101. >::value
  102. >::type* = 0,
  103. typename enable_if<
  104. !detail::is_work_dispatcher_required<
  105. typename decay<CompletionHandler>::type,
  106. Executor
  107. >::value
  108. >::type* = 0) const
  109. {
  110. typedef typename decay<CompletionHandler>::type handler_t;
  111. typename associated_allocator<handler_t>::type alloc(
  112. (get_associated_allocator)(handler));
  113. #if defined(BOOST_ASIO_NO_DEPRECATED)
  114. boost::asio::prefer(
  115. boost::asio::require(ex_, execution::blocking.never),
  116. execution::relationship.continuation,
  117. execution::allocator(alloc)
  118. ).execute(
  119. boost::asio::detail::bind_handler(
  120. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)));
  121. #else // defined(BOOST_ASIO_NO_DEPRECATED)
  122. execution::execute(
  123. boost::asio::prefer(
  124. boost::asio::require(ex_, execution::blocking.never),
  125. execution::relationship.continuation,
  126. execution::allocator(alloc)),
  127. boost::asio::detail::bind_handler(
  128. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)));
  129. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  130. }
  131. template <typename CompletionHandler>
  132. void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
  133. typename enable_if<
  134. execution::is_executor<
  135. typename conditional<true, executor_type, CompletionHandler>::type
  136. >::value
  137. >::type* = 0,
  138. typename enable_if<
  139. detail::is_work_dispatcher_required<
  140. typename decay<CompletionHandler>::type,
  141. Executor
  142. >::value
  143. >::type* = 0) const
  144. {
  145. typedef typename decay<CompletionHandler>::type handler_t;
  146. typedef typename associated_executor<
  147. handler_t, Executor>::type handler_ex_t;
  148. handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
  149. typename associated_allocator<handler_t>::type alloc(
  150. (get_associated_allocator)(handler));
  151. #if defined(BOOST_ASIO_NO_DEPRECATED)
  152. boost::asio::prefer(
  153. boost::asio::require(ex_, execution::blocking.never),
  154. execution::relationship.continuation,
  155. execution::allocator(alloc)
  156. ).execute(
  157. detail::work_dispatcher<handler_t, handler_ex_t>(
  158. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));
  159. #else // defined(BOOST_ASIO_NO_DEPRECATED)
  160. execution::execute(
  161. boost::asio::prefer(
  162. boost::asio::require(ex_, execution::blocking.never),
  163. execution::relationship.continuation,
  164. execution::allocator(alloc)),
  165. detail::work_dispatcher<handler_t, handler_ex_t>(
  166. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));
  167. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  168. }
  169. template <typename CompletionHandler>
  170. void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
  171. typename enable_if<
  172. !execution::is_executor<
  173. typename conditional<true, executor_type, CompletionHandler>::type
  174. >::value
  175. >::type* = 0,
  176. typename enable_if<
  177. !detail::is_work_dispatcher_required<
  178. typename decay<CompletionHandler>::type,
  179. Executor
  180. >::value
  181. >::type* = 0) const
  182. {
  183. typedef typename decay<CompletionHandler>::type handler_t;
  184. typename associated_allocator<handler_t>::type alloc(
  185. (get_associated_allocator)(handler));
  186. ex_.defer(boost::asio::detail::bind_handler(
  187. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
  188. }
  189. template <typename CompletionHandler>
  190. void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
  191. typename enable_if<
  192. !execution::is_executor<
  193. typename conditional<true, executor_type, CompletionHandler>::type
  194. >::value
  195. >::type* = 0,
  196. typename enable_if<
  197. detail::is_work_dispatcher_required<
  198. typename decay<CompletionHandler>::type,
  199. Executor
  200. >::value
  201. >::type* = 0) const
  202. {
  203. typedef typename decay<CompletionHandler>::type handler_t;
  204. typedef typename associated_executor<
  205. handler_t, Executor>::type handler_ex_t;
  206. handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
  207. typename associated_allocator<handler_t>::type alloc(
  208. (get_associated_allocator)(handler));
  209. ex_.defer(detail::work_dispatcher<handler_t, handler_ex_t>(
  210. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler),
  211. handler_ex), alloc);
  212. }
  213. private:
  214. Executor ex_;
  215. };
  216. } // namespace detail
  217. } // namespace asio
  218. } // namespace boost
  219. #include <boost/asio/detail/pop_options.hpp>
  220. #endif // BOOST_ASIO_DETAIL_INITIATE_DEFER_HPP