File indexing completed on 2025-12-15 09:44:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP
0012 #define BOOST_ASIO_ASSOCIATED_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/executor.hpp>
0023 #include <boost/asio/is_executor.hpp>
0024 #include <boost/asio/system_executor.hpp>
0025
0026 #include <boost/asio/detail/push_options.hpp>
0027
0028 namespace boost {
0029 namespace asio {
0030
0031 template <typename T, typename Executor>
0032 struct associated_executor;
0033
0034 namespace detail {
0035
0036 template <typename T, typename = void>
0037 struct has_executor_type : false_type
0038 {
0039 };
0040
0041 template <typename T>
0042 struct has_executor_type<T, void_t<typename T::executor_type>>
0043 : true_type
0044 {
0045 };
0046
0047 template <typename T, typename E, typename = void, typename = void>
0048 struct associated_executor_impl
0049 {
0050 typedef void asio_associated_executor_is_unspecialised;
0051
0052 typedef E type;
0053
0054 static type get(const T&) noexcept
0055 {
0056 return type();
0057 }
0058
0059 static const type& get(const T&, const E& e) noexcept
0060 {
0061 return e;
0062 }
0063 };
0064
0065 template <typename T, typename E>
0066 struct associated_executor_impl<T, E, void_t<typename T::executor_type>>
0067 {
0068 typedef typename T::executor_type type;
0069
0070 static auto get(const T& t) noexcept
0071 -> decltype(t.get_executor())
0072 {
0073 return t.get_executor();
0074 }
0075
0076 static auto get(const T& t, const E&) noexcept
0077 -> decltype(t.get_executor())
0078 {
0079 return t.get_executor();
0080 }
0081 };
0082
0083 template <typename T, typename E>
0084 struct associated_executor_impl<T, E,
0085 enable_if_t<
0086 !has_executor_type<T>::value
0087 >,
0088 void_t<
0089 typename associator<associated_executor, T, E>::type
0090 >> : associator<associated_executor, T, E>
0091 {
0092 };
0093
0094 }
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 template <typename T, typename Executor = system_executor>
0118 struct associated_executor
0119 #if !defined(GENERATING_DOCUMENTATION)
0120 : detail::associated_executor_impl<T, Executor>
0121 #endif
0122 {
0123 #if defined(GENERATING_DOCUMENTATION)
0124
0125
0126 typedef see_below type;
0127
0128
0129
0130 static decltype(auto) get(const T& t) noexcept;
0131
0132
0133
0134 static decltype(auto) get(const T& t, const Executor& ex) noexcept;
0135 #endif
0136 };
0137
0138
0139
0140
0141
0142 template <typename T>
0143 BOOST_ASIO_NODISCARD inline typename associated_executor<T>::type
0144 get_associated_executor(const T& t) noexcept
0145 {
0146 return associated_executor<T>::get(t);
0147 }
0148
0149
0150
0151
0152
0153 template <typename T, typename Executor>
0154 BOOST_ASIO_NODISCARD inline auto get_associated_executor(
0155 const T& t, const Executor& ex,
0156 constraint_t<
0157 is_executor<Executor>::value || execution::is_executor<Executor>::value
0158 > = 0) noexcept
0159 -> decltype(associated_executor<T, Executor>::get(t, ex))
0160 {
0161 return associated_executor<T, Executor>::get(t, ex);
0162 }
0163
0164
0165
0166
0167
0168
0169 template <typename T, typename ExecutionContext>
0170 BOOST_ASIO_NODISCARD inline typename associated_executor<T,
0171 typename ExecutionContext::executor_type>::type
0172 get_associated_executor(const T& t, ExecutionContext& ctx,
0173 constraint_t<is_convertible<ExecutionContext&,
0174 execution_context&>::value> = 0) noexcept
0175 {
0176 return associated_executor<T,
0177 typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
0178 }
0179
0180 template <typename T, typename Executor = system_executor>
0181 using associated_executor_t = typename associated_executor<T, Executor>::type;
0182
0183 namespace detail {
0184
0185 template <typename T, typename E, typename = void>
0186 struct associated_executor_forwarding_base
0187 {
0188 };
0189
0190 template <typename T, typename E>
0191 struct associated_executor_forwarding_base<T, E,
0192 enable_if_t<
0193 is_same<
0194 typename associated_executor<T,
0195 E>::asio_associated_executor_is_unspecialised,
0196 void
0197 >::value
0198 >>
0199 {
0200 typedef void asio_associated_executor_is_unspecialised;
0201 };
0202
0203 }
0204
0205
0206 template <typename T, typename Executor>
0207 struct associated_executor<reference_wrapper<T>, Executor>
0208 #if !defined(GENERATING_DOCUMENTATION)
0209 : detail::associated_executor_forwarding_base<T, Executor>
0210 #endif
0211 {
0212
0213
0214 typedef typename associated_executor<T, Executor>::type type;
0215
0216
0217
0218 static type get(reference_wrapper<T> t) noexcept
0219 {
0220 return associated_executor<T, Executor>::get(t.get());
0221 }
0222
0223
0224
0225 static auto get(reference_wrapper<T> t, const Executor& ex) noexcept
0226 -> decltype(associated_executor<T, Executor>::get(t.get(), ex))
0227 {
0228 return associated_executor<T, Executor>::get(t.get(), ex);
0229 }
0230 };
0231
0232 }
0233 }
0234
0235 #include <boost/asio/detail/pop_options.hpp>
0236
0237 #endif