File indexing completed on 2025-01-18 09:28:39
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DETAIL_INITIATE_DISPATCH_HPP
0012 #define BOOST_ASIO_DETAIL_INITIATE_DISPATCH_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/associated_allocator.hpp>
0020 #include <boost/asio/associated_executor.hpp>
0021 #include <boost/asio/detail/work_dispatcher.hpp>
0022 #include <boost/asio/execution/allocator.hpp>
0023 #include <boost/asio/execution/blocking.hpp>
0024 #include <boost/asio/prefer.hpp>
0025
0026 #include <boost/asio/detail/push_options.hpp>
0027
0028 namespace boost {
0029 namespace asio {
0030 namespace detail {
0031
0032 class initiate_dispatch
0033 {
0034 public:
0035 template <typename CompletionHandler>
0036 void operator()(CompletionHandler&& handler,
0037 enable_if_t<
0038 execution::is_executor<
0039 associated_executor_t<decay_t<CompletionHandler>>
0040 >::value
0041 >* = 0) const
0042 {
0043 associated_executor_t<decay_t<CompletionHandler>> ex(
0044 (get_associated_executor)(handler));
0045
0046 associated_allocator_t<decay_t<CompletionHandler>> alloc(
0047 (get_associated_allocator)(handler));
0048
0049 boost::asio::prefer(ex, execution::allocator(alloc)).execute(
0050 boost::asio::detail::bind_handler(
0051 static_cast<CompletionHandler&&>(handler)));
0052 }
0053
0054 template <typename CompletionHandler>
0055 void operator()(CompletionHandler&& handler,
0056 enable_if_t<
0057 !execution::is_executor<
0058 associated_executor_t<decay_t<CompletionHandler>>
0059 >::value
0060 >* = 0) const
0061 {
0062 associated_executor_t<decay_t<CompletionHandler>> ex(
0063 (get_associated_executor)(handler));
0064
0065 associated_allocator_t<decay_t<CompletionHandler>> alloc(
0066 (get_associated_allocator)(handler));
0067
0068 ex.dispatch(boost::asio::detail::bind_handler(
0069 static_cast<CompletionHandler&&>(handler)), alloc);
0070 }
0071 };
0072
0073 template <typename Executor>
0074 class initiate_dispatch_with_executor
0075 {
0076 public:
0077 typedef Executor executor_type;
0078
0079 explicit initiate_dispatch_with_executor(const Executor& ex)
0080 : ex_(ex)
0081 {
0082 }
0083
0084 executor_type get_executor() const noexcept
0085 {
0086 return ex_;
0087 }
0088
0089 template <typename CompletionHandler>
0090 void operator()(CompletionHandler&& handler,
0091 enable_if_t<
0092 execution::is_executor<
0093 conditional_t<true, executor_type, CompletionHandler>
0094 >::value
0095 >* = 0,
0096 enable_if_t<
0097 !detail::is_work_dispatcher_required<
0098 decay_t<CompletionHandler>,
0099 Executor
0100 >::value
0101 >* = 0) const
0102 {
0103 associated_allocator_t<decay_t<CompletionHandler>> alloc(
0104 (get_associated_allocator)(handler));
0105
0106 boost::asio::prefer(ex_, execution::allocator(alloc)).execute(
0107 boost::asio::detail::bind_handler(
0108 static_cast<CompletionHandler&&>(handler)));
0109 }
0110
0111 template <typename CompletionHandler>
0112 void operator()(CompletionHandler&& handler,
0113 enable_if_t<
0114 execution::is_executor<
0115 conditional_t<true, executor_type, CompletionHandler>
0116 >::value
0117 >* = 0,
0118 enable_if_t<
0119 detail::is_work_dispatcher_required<
0120 decay_t<CompletionHandler>,
0121 Executor
0122 >::value
0123 >* = 0) const
0124 {
0125 typedef decay_t<CompletionHandler> handler_t;
0126
0127 typedef associated_executor_t<handler_t, Executor> handler_ex_t;
0128 handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
0129
0130 associated_allocator_t<handler_t> alloc(
0131 (get_associated_allocator)(handler));
0132
0133 boost::asio::prefer(ex_, execution::allocator(alloc)).execute(
0134 detail::work_dispatcher<handler_t, handler_ex_t>(
0135 static_cast<CompletionHandler&&>(handler), handler_ex));
0136 }
0137
0138 template <typename CompletionHandler>
0139 void operator()(CompletionHandler&& handler,
0140 enable_if_t<
0141 !execution::is_executor<
0142 conditional_t<true, executor_type, CompletionHandler>
0143 >::value
0144 >* = 0,
0145 enable_if_t<
0146 !detail::is_work_dispatcher_required<
0147 decay_t<CompletionHandler>,
0148 Executor
0149 >::value
0150 >* = 0) const
0151 {
0152 associated_allocator_t<decay_t<CompletionHandler>> alloc(
0153 (get_associated_allocator)(handler));
0154
0155 ex_.dispatch(boost::asio::detail::bind_handler(
0156 static_cast<CompletionHandler&&>(handler)), alloc);
0157 }
0158
0159 template <typename CompletionHandler>
0160 void operator()(CompletionHandler&& handler,
0161 enable_if_t<
0162 !execution::is_executor<
0163 conditional_t<true, executor_type, CompletionHandler>
0164 >::value
0165 >* = 0,
0166 enable_if_t<
0167 detail::is_work_dispatcher_required<
0168 decay_t<CompletionHandler>,
0169 Executor
0170 >::value
0171 >* = 0) const
0172 {
0173 typedef decay_t<CompletionHandler> handler_t;
0174
0175 typedef associated_executor_t<handler_t, Executor> handler_ex_t;
0176 handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
0177
0178 associated_allocator_t<handler_t> alloc(
0179 (get_associated_allocator)(handler));
0180
0181 ex_.dispatch(detail::work_dispatcher<handler_t, handler_ex_t>(
0182 static_cast<CompletionHandler&&>(handler), handler_ex), alloc);
0183 }
0184
0185 private:
0186 Executor ex_;
0187 };
0188
0189 }
0190 }
0191 }
0192
0193 #include <boost/asio/detail/pop_options.hpp>
0194
0195 #endif