File indexing completed on 2025-01-30 09:33:38
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 require_result_t<E, execution::blocking_t::never_t> type;
0054
0055 static type get(const E& e) noexcept
0056 {
0057 return boost::asio::require(e, execution::blocking.never);
0058 }
0059 };
0060
0061 template <typename E>
0062 struct default_immediate_executor<E,
0063 enable_if_t<
0064 !execution::is_executor<E>::value
0065 >,
0066 enable_if_t<
0067 is_executor<E>::value
0068 >>
0069 {
0070 class type : public E
0071 {
0072 public:
0073 template <typename Executor1>
0074 explicit type(const Executor1& e,
0075 constraint_t<
0076 conditional_t<
0077 !is_same<Executor1, type>::value,
0078 is_convertible<Executor1, E>,
0079 false_type
0080 >::value
0081 > = 0) noexcept
0082 : E(e)
0083 {
0084 }
0085
0086 type(const type& other) noexcept
0087 : E(static_cast<const E&>(other))
0088 {
0089 }
0090
0091 type(type&& other) noexcept
0092 : E(static_cast<E&&>(other))
0093 {
0094 }
0095
0096 template <typename Function, typename Allocator>
0097 void dispatch(Function&& f, const Allocator& a) const
0098 {
0099 this->post(static_cast<Function&&>(f), a);
0100 }
0101
0102 friend bool operator==(const type& a, const type& b) noexcept
0103 {
0104 return static_cast<const E&>(a) == static_cast<const E&>(b);
0105 }
0106
0107 friend bool operator!=(const type& a, const type& b) noexcept
0108 {
0109 return static_cast<const E&>(a) != static_cast<const E&>(b);
0110 }
0111 };
0112
0113 static type get(const E& e) noexcept
0114 {
0115 return type(e);
0116 }
0117 };
0118
0119 template <typename T, typename E, typename = void, typename = void>
0120 struct associated_immediate_executor_impl
0121 {
0122 typedef void asio_associated_immediate_executor_is_unspecialised;
0123
0124 typedef typename default_immediate_executor<E>::type type;
0125
0126 static auto get(const T&, const E& e) noexcept
0127 -> decltype(default_immediate_executor<E>::get(e))
0128 {
0129 return default_immediate_executor<E>::get(e);
0130 }
0131 };
0132
0133 template <typename T, typename E>
0134 struct associated_immediate_executor_impl<T, E,
0135 void_t<typename T::immediate_executor_type>>
0136 {
0137 typedef typename T::immediate_executor_type type;
0138
0139 static auto get(const T& t, const E&) noexcept
0140 -> decltype(t.get_immediate_executor())
0141 {
0142 return t.get_immediate_executor();
0143 }
0144 };
0145
0146 template <typename T, typename E>
0147 struct associated_immediate_executor_impl<T, E,
0148 enable_if_t<
0149 !has_immediate_executor_type<T>::value
0150 >,
0151 void_t<
0152 typename associator<associated_immediate_executor, T, E>::type
0153 >> : associator<associated_immediate_executor, T, E>
0154 {
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 template <typename T, typename Executor>
0181 struct associated_immediate_executor
0182 #if !defined(GENERATING_DOCUMENTATION)
0183 : detail::associated_immediate_executor_impl<T, Executor>
0184 #endif
0185 {
0186 #if defined(GENERATING_DOCUMENTATION)
0187
0188
0189 typedef see_below type;
0190
0191
0192
0193
0194 static decltype(auto) get(const T& t, const Executor& ex) noexcept;
0195 #endif
0196 };
0197
0198
0199
0200
0201
0202 template <typename T, typename Executor>
0203 BOOST_ASIO_NODISCARD inline auto get_associated_immediate_executor(
0204 const T& t, const Executor& ex,
0205 constraint_t<
0206 is_executor<Executor>::value || execution::is_executor<Executor>::value
0207 > = 0) noexcept
0208 -> decltype(associated_immediate_executor<T, Executor>::get(t, ex))
0209 {
0210 return associated_immediate_executor<T, Executor>::get(t, ex);
0211 }
0212
0213
0214
0215
0216
0217
0218 template <typename T, typename ExecutionContext>
0219 BOOST_ASIO_NODISCARD inline typename associated_immediate_executor<T,
0220 typename ExecutionContext::executor_type>::type
0221 get_associated_immediate_executor(const T& t, ExecutionContext& ctx,
0222 constraint_t<
0223 is_convertible<ExecutionContext&, execution_context&>::value
0224 > = 0) noexcept
0225 {
0226 return associated_immediate_executor<T,
0227 typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
0228 }
0229
0230 template <typename T, typename Executor>
0231 using associated_immediate_executor_t =
0232 typename associated_immediate_executor<T, Executor>::type;
0233
0234 namespace detail {
0235
0236 template <typename T, typename E, typename = void>
0237 struct associated_immediate_executor_forwarding_base
0238 {
0239 };
0240
0241 template <typename T, typename E>
0242 struct associated_immediate_executor_forwarding_base<T, E,
0243 enable_if_t<
0244 is_same<
0245 typename associated_immediate_executor<T,
0246 E>::asio_associated_immediate_executor_is_unspecialised,
0247 void
0248 >::value
0249 >>
0250 {
0251 typedef void asio_associated_immediate_executor_is_unspecialised;
0252 };
0253
0254 }
0255
0256
0257
0258 template <typename T, typename Executor>
0259 struct associated_immediate_executor<reference_wrapper<T>, Executor>
0260 #if !defined(GENERATING_DOCUMENTATION)
0261 : detail::associated_immediate_executor_forwarding_base<T, Executor>
0262 #endif
0263 {
0264
0265
0266 typedef typename associated_immediate_executor<T, Executor>::type type;
0267
0268
0269
0270 static auto get(reference_wrapper<T> t, const Executor& ex) noexcept
0271 -> decltype(associated_immediate_executor<T, Executor>::get(t.get(), ex))
0272 {
0273 return associated_immediate_executor<T, Executor>::get(t.get(), ex);
0274 }
0275 };
0276
0277 }
0278 }
0279
0280 #include <boost/asio/detail/pop_options.hpp>
0281
0282 #endif