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_DEFER_HPP
0012 #define BOOST_ASIO_DETAIL_INITIATE_DEFER_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/execution/relationship.hpp>
0025 #include <boost/asio/prefer.hpp>
0026 #include <boost/asio/require.hpp>
0027
0028 #include <boost/asio/detail/push_options.hpp>
0029
0030 namespace boost {
0031 namespace asio {
0032 namespace detail {
0033
0034 class initiate_defer
0035 {
0036 public:
0037 template <typename CompletionHandler>
0038 void operator()(CompletionHandler&& handler,
0039 enable_if_t<
0040 execution::is_executor<
0041 associated_executor_t<decay_t<CompletionHandler>>
0042 >::value
0043 >* = 0) const
0044 {
0045 associated_executor_t<decay_t<CompletionHandler>> ex(
0046 (get_associated_executor)(handler));
0047
0048 associated_allocator_t<decay_t<CompletionHandler>> alloc(
0049 (get_associated_allocator)(handler));
0050
0051 boost::asio::prefer(
0052 boost::asio::require(ex, execution::blocking.never),
0053 execution::relationship.continuation,
0054 execution::allocator(alloc)
0055 ).execute(
0056 boost::asio::detail::bind_handler(
0057 static_cast<CompletionHandler&&>(handler)));
0058 }
0059
0060 template <typename CompletionHandler>
0061 void operator()(CompletionHandler&& handler,
0062 enable_if_t<
0063 !execution::is_executor<
0064 associated_executor_t<decay_t<CompletionHandler>>
0065 >::value
0066 >* = 0) const
0067 {
0068 associated_executor_t<decay_t<CompletionHandler>> ex(
0069 (get_associated_executor)(handler));
0070
0071 associated_allocator_t<decay_t<CompletionHandler>> alloc(
0072 (get_associated_allocator)(handler));
0073
0074 ex.defer(boost::asio::detail::bind_handler(
0075 static_cast<CompletionHandler&&>(handler)), alloc);
0076 }
0077 };
0078
0079 template <typename Executor>
0080 class initiate_defer_with_executor
0081 {
0082 public:
0083 typedef Executor executor_type;
0084
0085 explicit initiate_defer_with_executor(const Executor& ex)
0086 : ex_(ex)
0087 {
0088 }
0089
0090 executor_type get_executor() const noexcept
0091 {
0092 return ex_;
0093 }
0094
0095 template <typename CompletionHandler>
0096 void operator()(CompletionHandler&& handler,
0097 enable_if_t<
0098 execution::is_executor<
0099 conditional_t<true, executor_type, CompletionHandler>
0100 >::value
0101 >* = 0,
0102 enable_if_t<
0103 !detail::is_work_dispatcher_required<
0104 decay_t<CompletionHandler>,
0105 Executor
0106 >::value
0107 >* = 0) const
0108 {
0109 associated_allocator_t<decay_t<CompletionHandler>> alloc(
0110 (get_associated_allocator)(handler));
0111
0112 boost::asio::prefer(
0113 boost::asio::require(ex_, execution::blocking.never),
0114 execution::relationship.continuation,
0115 execution::allocator(alloc)
0116 ).execute(
0117 boost::asio::detail::bind_handler(
0118 static_cast<CompletionHandler&&>(handler)));
0119 }
0120
0121 template <typename CompletionHandler>
0122 void operator()(CompletionHandler&& handler,
0123 enable_if_t<
0124 execution::is_executor<
0125 conditional_t<true, executor_type, CompletionHandler>
0126 >::value
0127 >* = 0,
0128 enable_if_t<
0129 detail::is_work_dispatcher_required<
0130 decay_t<CompletionHandler>,
0131 Executor
0132 >::value
0133 >* = 0) const
0134 {
0135 typedef decay_t<CompletionHandler> handler_t;
0136
0137 typedef associated_executor_t<handler_t, Executor> handler_ex_t;
0138 handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
0139
0140 associated_allocator_t<handler_t> alloc(
0141 (get_associated_allocator)(handler));
0142
0143 boost::asio::prefer(
0144 boost::asio::require(ex_, execution::blocking.never),
0145 execution::relationship.continuation,
0146 execution::allocator(alloc)
0147 ).execute(
0148 detail::work_dispatcher<handler_t, handler_ex_t>(
0149 static_cast<CompletionHandler&&>(handler), handler_ex));
0150 }
0151
0152 template <typename CompletionHandler>
0153 void operator()(CompletionHandler&& handler,
0154 enable_if_t<
0155 !execution::is_executor<
0156 conditional_t<true, executor_type, CompletionHandler>
0157 >::value
0158 >* = 0,
0159 enable_if_t<
0160 !detail::is_work_dispatcher_required<
0161 decay_t<CompletionHandler>,
0162 Executor
0163 >::value
0164 >* = 0) const
0165 {
0166 associated_allocator_t<decay_t<CompletionHandler>> alloc(
0167 (get_associated_allocator)(handler));
0168
0169 ex_.defer(boost::asio::detail::bind_handler(
0170 static_cast<CompletionHandler&&>(handler)), alloc);
0171 }
0172
0173 template <typename CompletionHandler>
0174 void operator()(CompletionHandler&& handler,
0175 enable_if_t<
0176 !execution::is_executor<
0177 conditional_t<true, executor_type, CompletionHandler>
0178 >::value
0179 >* = 0,
0180 enable_if_t<
0181 detail::is_work_dispatcher_required<
0182 decay_t<CompletionHandler>,
0183 Executor
0184 >::value
0185 >* = 0) const
0186 {
0187 typedef decay_t<CompletionHandler> handler_t;
0188
0189 typedef associated_executor_t<handler_t, Executor> handler_ex_t;
0190 handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
0191
0192 associated_allocator_t<handler_t> alloc(
0193 (get_associated_allocator)(handler));
0194
0195 ex_.defer(detail::work_dispatcher<handler_t, handler_ex_t>(
0196 static_cast<CompletionHandler&&>(handler), handler_ex), alloc);
0197 }
0198
0199 private:
0200 Executor ex_;
0201 };
0202
0203 }
0204 }
0205 }
0206
0207 #include <boost/asio/detail/pop_options.hpp>
0208
0209 #endif