initiate_dispatch.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. //
  2. // detail/initiate_dispatch.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 ASIO_DETAIL_INITIATE_DISPATCH_HPP
  11. #define ASIO_DETAIL_INITIATE_DISPATCH_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/associated_allocator.hpp"
  17. #include "asio/associated_executor.hpp"
  18. #include "asio/detail/work_dispatcher.hpp"
  19. #include "asio/execution/allocator.hpp"
  20. #include "asio/execution/blocking.hpp"
  21. #include "asio/prefer.hpp"
  22. #include "asio/detail/push_options.hpp"
  23. namespace asio {
  24. namespace detail {
  25. class initiate_dispatch
  26. {
  27. public:
  28. template <typename CompletionHandler>
  29. void operator()(CompletionHandler&& handler,
  30. enable_if_t<
  31. execution::is_executor<
  32. associated_executor_t<decay_t<CompletionHandler>>
  33. >::value
  34. >* = 0) const
  35. {
  36. associated_executor_t<decay_t<CompletionHandler>> ex(
  37. (get_associated_executor)(handler));
  38. associated_allocator_t<decay_t<CompletionHandler>> alloc(
  39. (get_associated_allocator)(handler));
  40. asio::prefer(ex, execution::allocator(alloc)).execute(
  41. asio::detail::bind_handler(
  42. static_cast<CompletionHandler&&>(handler)));
  43. }
  44. template <typename CompletionHandler>
  45. void operator()(CompletionHandler&& handler,
  46. enable_if_t<
  47. !execution::is_executor<
  48. associated_executor_t<decay_t<CompletionHandler>>
  49. >::value
  50. >* = 0) const
  51. {
  52. associated_executor_t<decay_t<CompletionHandler>> ex(
  53. (get_associated_executor)(handler));
  54. associated_allocator_t<decay_t<CompletionHandler>> alloc(
  55. (get_associated_allocator)(handler));
  56. ex.dispatch(asio::detail::bind_handler(
  57. static_cast<CompletionHandler&&>(handler)), alloc);
  58. }
  59. };
  60. template <typename Executor>
  61. class initiate_dispatch_with_executor
  62. {
  63. public:
  64. typedef Executor executor_type;
  65. explicit initiate_dispatch_with_executor(const Executor& ex)
  66. : ex_(ex)
  67. {
  68. }
  69. executor_type get_executor() const noexcept
  70. {
  71. return ex_;
  72. }
  73. template <typename CompletionHandler>
  74. void operator()(CompletionHandler&& handler,
  75. enable_if_t<
  76. execution::is_executor<
  77. conditional_t<true, executor_type, CompletionHandler>
  78. >::value
  79. >* = 0,
  80. enable_if_t<
  81. !detail::is_work_dispatcher_required<
  82. decay_t<CompletionHandler>,
  83. Executor
  84. >::value
  85. >* = 0) const
  86. {
  87. associated_allocator_t<decay_t<CompletionHandler>> alloc(
  88. (get_associated_allocator)(handler));
  89. asio::prefer(ex_, execution::allocator(alloc)).execute(
  90. asio::detail::bind_handler(
  91. static_cast<CompletionHandler&&>(handler)));
  92. }
  93. template <typename CompletionHandler>
  94. void operator()(CompletionHandler&& handler,
  95. enable_if_t<
  96. execution::is_executor<
  97. conditional_t<true, executor_type, CompletionHandler>
  98. >::value
  99. >* = 0,
  100. enable_if_t<
  101. detail::is_work_dispatcher_required<
  102. decay_t<CompletionHandler>,
  103. Executor
  104. >::value
  105. >* = 0) const
  106. {
  107. typedef decay_t<CompletionHandler> handler_t;
  108. typedef associated_executor_t<handler_t, Executor> handler_ex_t;
  109. handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
  110. associated_allocator_t<handler_t> alloc(
  111. (get_associated_allocator)(handler));
  112. asio::prefer(ex_, execution::allocator(alloc)).execute(
  113. detail::work_dispatcher<handler_t, handler_ex_t>(
  114. static_cast<CompletionHandler&&>(handler), handler_ex));
  115. }
  116. template <typename CompletionHandler>
  117. void operator()(CompletionHandler&& handler,
  118. enable_if_t<
  119. !execution::is_executor<
  120. conditional_t<true, executor_type, CompletionHandler>
  121. >::value
  122. >* = 0,
  123. enable_if_t<
  124. !detail::is_work_dispatcher_required<
  125. decay_t<CompletionHandler>,
  126. Executor
  127. >::value
  128. >* = 0) const
  129. {
  130. associated_allocator_t<decay_t<CompletionHandler>> alloc(
  131. (get_associated_allocator)(handler));
  132. ex_.dispatch(asio::detail::bind_handler(
  133. static_cast<CompletionHandler&&>(handler)), alloc);
  134. }
  135. template <typename CompletionHandler>
  136. void operator()(CompletionHandler&& handler,
  137. enable_if_t<
  138. !execution::is_executor<
  139. conditional_t<true, executor_type, CompletionHandler>
  140. >::value
  141. >* = 0,
  142. enable_if_t<
  143. detail::is_work_dispatcher_required<
  144. decay_t<CompletionHandler>,
  145. Executor
  146. >::value
  147. >* = 0) const
  148. {
  149. typedef decay_t<CompletionHandler> handler_t;
  150. typedef associated_executor_t<handler_t, Executor> handler_ex_t;
  151. handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
  152. associated_allocator_t<handler_t> alloc(
  153. (get_associated_allocator)(handler));
  154. ex_.dispatch(detail::work_dispatcher<handler_t, handler_ex_t>(
  155. static_cast<CompletionHandler&&>(handler), handler_ex), alloc);
  156. }
  157. private:
  158. Executor ex_;
  159. };
  160. } // namespace detail
  161. } // namespace asio
  162. #include "asio/detail/pop_options.hpp"
  163. #endif // ASIO_DETAIL_INITIATE_DISPATCH_HPP