File indexing completed on 2025-07-02 08:06:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_ASSOCIATED_IMMEDIATE_EXECUTOR_HPP
0012 #define BOOST_ASIO_ASSOCIATED_IMMEDIATE_EXECUTOR_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/associator.hpp>
0020 #include <boost/asio/detail/functional.hpp>
0021 #include <boost/asio/detail/type_traits.hpp>
0022 #include <boost/asio/execution/blocking.hpp>
0023 #include <boost/asio/execution/executor.hpp>
0024 #include <boost/asio/execution_context.hpp>
0025 #include <boost/asio/is_executor.hpp>
0026 #include <boost/asio/require.hpp>
0027
0028 #include <boost/asio/detail/push_options.hpp>
0029
0030 namespace boost {
0031 namespace asio {
0032
0033 template <typename T, typename Executor>
0034 struct associated_immediate_executor;
0035
0036 namespace detail {
0037
0038 template <typename T, typename = void>
0039 struct has_immediate_executor_type : false_type
0040 {
0041 };
0042
0043 template <typename T>
0044 struct has_immediate_executor_type<T,
0045 void_t<typename T::immediate_executor_type>>
0046 : true_type
0047 {
0048 };
0049
0050 template <typename E, typename = void, typename = void>
0051 struct default_immediate_executor
0052 {
0053 typedef decay_t<require_result_t<E, execution::blocking_t::never_t>> type;
0054
0055 static auto get(const E& e) noexcept
0056 -> decltype(boost::asio::require(e, execution::blocking.never))
0057 {
0058 return boost::asio::require(e, execution::blocking.never);
0059 }
0060 };
0061
0062 template <typename E>
0063 struct default_immediate_executor<E,
0064 enable_if_t<
0065 !execution::is_executor<E>::value
0066 >,
0067 enable_if_t<
0068 is_executor<E>::value
0069 >>
0070 {
0071 class type : public E
0072 {
0073 public:
0074 template <typename Executor1>
0075 explicit type(const Executor1& e,
0076 constraint_t<
0077 conditional_t<
0078 !is_same<Executor1, type>::value,
0079 is_convertible<Executor1, E>,
0080 false_type
0081 >::value
0082 > = 0) noexcept
0083 : E(e)
0084 {
0085 }
0086
0087 type(const type& other) noexcept
0088 : E(static_cast<const E&>(other))
0089 {
0090 }
0091
0092 type(type&& other) noexcept
0093 : E(static_cast<E&&>(other))
0094 {
0095 }
0096
0097 template <typename Function, typename Allocator>
0098 void dispatch(Function&& f, const Allocator& a) const
0099 {
0100 this->post(static_cast<Function&&>(f), a);
0101 }
0102
0103 friend bool operator==(const type& a, const type& b) noexcept
0104 {
0105 return static_cast<const E&>(a) == static_cast<const E&>(b);
0106 }
0107
0108 friend bool operator!=(const type& a, const type& b) noexcept
0109 {
0110 return static_cast<const E&>(a) != static_cast<const E&>(b);
0111 }
0112 };
0113
0114 static type get(const E& e) noexcept
0115 {
0116 return type(e);
0117 }
0118 };
0119
0120 template <typename T, typename E, typename = void, typename = void>
0121 struct associated_immediate_executor_impl
0122 {
0123 typedef void asio_associated_immediate_executor_is_unspecialised;
0124
0125 typedef typename default_immediate_executor<E>::type type;
0126
0127 static auto get(const T&, const E& e) noexcept
0128 -> decltype(default_immediate_executor<E>::get(e))
0129 {
0130 return default_immediate_executor<E>::get(e);
0131 }
0132 };
0133
0134 template <typename T, typename E>
0135 struct associated_immediate_executor_impl<T, E,
0136 void_t<typename T::immediate_executor_type>>
0137 {
0138 typedef typename T::immediate_executor_type type;
0139
0140 static auto get(const T& t, const E&) noexcept
0141 -> decltype(t.get_immediate_executor())
0142 {
0143 return t.get_immediate_executor();
0144 }
0145 };
0146
0147 template <typename T, typename E>
0148 struct associated_immediate_executor_impl<T, E,
0149 enable_if_t<
0150 !has_immediate_executor_type<T>::value
0151 >,
0152 void_t<
0153 typename associator<associated_immediate_executor, T, E>::type
0154 >> : associator<associated_immediate_executor, T, E>
0155 {
0156 };
0157
0158 }
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 template <typename T, typename Executor>
0182 struct associated_immediate_executor
0183 #if !defined(GENERATING_DOCUMENTATION)
0184 : detail::associated_immediate_executor_impl<T, Executor>
0185 #endif
0186 {
0187 #if defined(GENERATING_DOCUMENTATION)
0188
0189
0190 typedef see_below type;
0191
0192
0193
0194
0195 static decltype(auto) get(const T& t, const Executor& ex) noexcept;
0196 #endif
0197 };
0198
0199
0200
0201
0202
0203 template <typename T, typename Executor>
0204 BOOST_ASIO_NODISCARD inline auto get_associated_immediate_executor(
0205 const T& t, const Executor& ex,
0206 constraint_t<
0207 is_executor<Executor>::value || execution::is_executor<Executor>::value
0208 > = 0) noexcept
0209 -> decltype(associated_immediate_executor<T, Executor>::get(t, ex))
0210 {
0211 return associated_immediate_executor<T, Executor>::get(t, ex);
0212 }
0213
0214
0215
0216
0217
0218
0219 template <typename T, typename ExecutionContext>
0220 BOOST_ASIO_NODISCARD inline typename associated_immediate_executor<T,
0221 typename ExecutionContext::executor_type>::type
0222 get_associated_immediate_executor(const T& t, ExecutionContext& ctx,
0223 constraint_t<
0224 is_convertible<ExecutionContext&, execution_context&>::value
0225 > = 0) noexcept
0226 {
0227 return associated_immediate_executor<T,
0228 typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
0229 }
0230
0231 template <typename T, typename Executor>
0232 using associated_immediate_executor_t =
0233 typename associated_immediate_executor<T, Executor>::type;
0234
0235 namespace detail {
0236
0237 template <typename T, typename E, typename = void>
0238 struct associated_immediate_executor_forwarding_base
0239 {
0240 };
0241
0242 template <typename T, typename E>
0243 struct associated_immediate_executor_forwarding_base<T, E,
0244 enable_if_t<
0245 is_same<
0246 typename associated_immediate_executor<T,
0247 E>::asio_associated_immediate_executor_is_unspecialised,
0248 void
0249 >::value
0250 >>
0251 {
0252 typedef void asio_associated_immediate_executor_is_unspecialised;
0253 };
0254
0255 }
0256
0257
0258
0259 template <typename T, typename Executor>
0260 struct associated_immediate_executor<reference_wrapper<T>, Executor>
0261 #if !defined(GENERATING_DOCUMENTATION)
0262 : detail::associated_immediate_executor_forwarding_base<T, Executor>
0263 #endif
0264 {
0265
0266
0267 typedef typename associated_immediate_executor<T, Executor>::type type;
0268
0269
0270
0271 static auto get(reference_wrapper<T> t, const Executor& ex) noexcept
0272 -> decltype(associated_immediate_executor<T, Executor>::get(t.get(), ex))
0273 {
0274 return associated_immediate_executor<T, Executor>::get(t.get(), ex);
0275 }
0276 };
0277
0278 }
0279 }
0280
0281 #include <boost/asio/detail/pop_options.hpp>
0282
0283 #endif