1 | // |
2 | // any_io_executor.hpp |
3 | // ~~~~~~~~~~~~~~~~~~~ |
4 | // |
5 | // Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
9 | // |
10 | |
11 | #ifndef BOOST_ASIO_ANY_IO_EXECUTOR_HPP |
12 | #define BOOST_ASIO_ANY_IO_EXECUTOR_HPP |
13 | |
14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) |
15 | # pragma once |
16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) |
17 | |
18 | #include <boost/asio/detail/config.hpp> |
19 | #if defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) |
20 | # include <boost/asio/executor.hpp> |
21 | #else // defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) |
22 | # include <boost/asio/execution.hpp> |
23 | # include <boost/asio/execution_context.hpp> |
24 | #endif // defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) |
25 | |
26 | #include <boost/asio/detail/push_options.hpp> |
27 | |
28 | namespace boost { |
29 | namespace asio { |
30 | |
31 | #if defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) |
32 | |
33 | typedef executor any_io_executor; |
34 | |
35 | #else // defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) |
36 | |
37 | /// Polymorphic executor type for use with I/O objects. |
38 | /** |
39 | * The @c any_io_executor type is a polymorphic executor that supports the set |
40 | * of properties required by I/O objects. It is defined as the |
41 | * execution::any_executor class template parameterised as follows: |
42 | * @code execution::any_executor< |
43 | * execution::context_as_t<execution_context&>, |
44 | * execution::blocking_t::never_t, |
45 | * execution::prefer_only<execution::blocking_t::possibly_t>, |
46 | * execution::prefer_only<execution::outstanding_work_t::tracked_t>, |
47 | * execution::prefer_only<execution::outstanding_work_t::untracked_t>, |
48 | * execution::prefer_only<execution::relationship_t::fork_t>, |
49 | * execution::prefer_only<execution::relationship_t::continuation_t> |
50 | * > @endcode |
51 | */ |
52 | class any_io_executor : |
53 | #if defined(GENERATING_DOCUMENTATION) |
54 | public execution::any_executor<...> |
55 | #else // defined(GENERATING_DOCUMENTATION) |
56 | public execution::any_executor< |
57 | execution::context_as_t<execution_context&>, |
58 | execution::blocking_t::never_t, |
59 | execution::prefer_only<execution::blocking_t::possibly_t>, |
60 | execution::prefer_only<execution::outstanding_work_t::tracked_t>, |
61 | execution::prefer_only<execution::outstanding_work_t::untracked_t>, |
62 | execution::prefer_only<execution::relationship_t::fork_t>, |
63 | execution::prefer_only<execution::relationship_t::continuation_t> |
64 | > |
65 | #endif // defined(GENERATING_DOCUMENTATION) |
66 | { |
67 | public: |
68 | #if !defined(GENERATING_DOCUMENTATION) |
69 | typedef execution::any_executor< |
70 | execution::context_as_t<execution_context&>, |
71 | execution::blocking_t::never_t, |
72 | execution::prefer_only<execution::blocking_t::possibly_t>, |
73 | execution::prefer_only<execution::outstanding_work_t::tracked_t>, |
74 | execution::prefer_only<execution::outstanding_work_t::untracked_t>, |
75 | execution::prefer_only<execution::relationship_t::fork_t>, |
76 | execution::prefer_only<execution::relationship_t::continuation_t> |
77 | > base_type; |
78 | |
79 | typedef void supportable_properties_type( |
80 | execution::context_as_t<execution_context&>, |
81 | execution::blocking_t::never_t, |
82 | execution::prefer_only<execution::blocking_t::possibly_t>, |
83 | execution::prefer_only<execution::outstanding_work_t::tracked_t>, |
84 | execution::prefer_only<execution::outstanding_work_t::untracked_t>, |
85 | execution::prefer_only<execution::relationship_t::fork_t>, |
86 | execution::prefer_only<execution::relationship_t::continuation_t> |
87 | ); |
88 | #endif // !defined(GENERATING_DOCUMENTATION) |
89 | |
90 | /// Default constructor. |
91 | BOOST_ASIO_DECL any_io_executor() noexcept; |
92 | |
93 | /// Construct in an empty state. Equivalent effects to default constructor. |
94 | BOOST_ASIO_DECL any_io_executor(nullptr_t) noexcept; |
95 | |
96 | /// Copy constructor. |
97 | BOOST_ASIO_DECL any_io_executor(const any_io_executor& e) noexcept; |
98 | |
99 | /// Move constructor. |
100 | BOOST_ASIO_DECL any_io_executor(any_io_executor&& e) noexcept; |
101 | |
102 | /// Construct to point to the same target as another any_executor. |
103 | #if defined(GENERATING_DOCUMENTATION) |
104 | template <class... OtherSupportableProperties> |
105 | any_io_executor(execution::any_executor<OtherSupportableProperties...> e); |
106 | #else // defined(GENERATING_DOCUMENTATION) |
107 | template <typename OtherAnyExecutor> |
108 | any_io_executor(OtherAnyExecutor e, |
109 | constraint_t< |
110 | conditional_t< |
111 | !is_same<OtherAnyExecutor, any_io_executor>::value |
112 | && is_base_of<execution::detail::any_executor_base, |
113 | OtherAnyExecutor>::value, |
114 | typename execution::detail::supportable_properties< |
115 | 0, supportable_properties_type>::template |
116 | is_valid_target<OtherAnyExecutor>, |
117 | false_type |
118 | >::value |
119 | > = 0) |
120 | : base_type(static_cast<OtherAnyExecutor&&>(e)) |
121 | { |
122 | } |
123 | #endif // defined(GENERATING_DOCUMENTATION) |
124 | |
125 | /// Construct to point to the same target as another any_executor. |
126 | #if defined(GENERATING_DOCUMENTATION) |
127 | template <class... OtherSupportableProperties> |
128 | any_io_executor(std::nothrow_t, |
129 | execution::any_executor<OtherSupportableProperties...> e); |
130 | #else // defined(GENERATING_DOCUMENTATION) |
131 | template <typename OtherAnyExecutor> |
132 | any_io_executor(std::nothrow_t, OtherAnyExecutor e, |
133 | constraint_t< |
134 | conditional_t< |
135 | !is_same<OtherAnyExecutor, any_io_executor>::value |
136 | && is_base_of<execution::detail::any_executor_base, |
137 | OtherAnyExecutor>::value, |
138 | typename execution::detail::supportable_properties< |
139 | 0, supportable_properties_type>::template |
140 | is_valid_target<OtherAnyExecutor>, |
141 | false_type |
142 | >::value |
143 | > = 0) noexcept |
144 | : base_type(std::nothrow, static_cast<OtherAnyExecutor&&>(e)) |
145 | { |
146 | } |
147 | #endif // defined(GENERATING_DOCUMENTATION) |
148 | |
149 | /// Construct to point to the same target as another any_executor. |
150 | BOOST_ASIO_DECL any_io_executor(std::nothrow_t, |
151 | const any_io_executor& e) noexcept; |
152 | |
153 | /// Construct to point to the same target as another any_executor. |
154 | BOOST_ASIO_DECL any_io_executor(std::nothrow_t, any_io_executor&& e) noexcept; |
155 | |
156 | /// Construct a polymorphic wrapper for the specified executor. |
157 | #if defined(GENERATING_DOCUMENTATION) |
158 | template <BOOST_ASIO_EXECUTION_EXECUTOR Executor> |
159 | any_io_executor(Executor e); |
160 | #else // defined(GENERATING_DOCUMENTATION) |
161 | template <BOOST_ASIO_EXECUTION_EXECUTOR Executor> |
162 | any_io_executor(Executor e, |
163 | constraint_t< |
164 | conditional_t< |
165 | !is_same<Executor, any_io_executor>::value |
166 | && !is_base_of<execution::detail::any_executor_base, |
167 | Executor>::value, |
168 | execution::detail::is_valid_target_executor< |
169 | Executor, supportable_properties_type>, |
170 | false_type |
171 | >::value |
172 | > = 0) |
173 | : base_type(static_cast<Executor&&>(e)) |
174 | { |
175 | } |
176 | #endif // defined(GENERATING_DOCUMENTATION) |
177 | |
178 | /// Construct a polymorphic wrapper for the specified executor. |
179 | #if defined(GENERATING_DOCUMENTATION) |
180 | template <BOOST_ASIO_EXECUTION_EXECUTOR Executor> |
181 | any_io_executor(std::nothrow_t, Executor e); |
182 | #else // defined(GENERATING_DOCUMENTATION) |
183 | template <BOOST_ASIO_EXECUTION_EXECUTOR Executor> |
184 | any_io_executor(std::nothrow_t, Executor e, |
185 | constraint_t< |
186 | conditional_t< |
187 | !is_same<Executor, any_io_executor>::value |
188 | && !is_base_of<execution::detail::any_executor_base, |
189 | Executor>::value, |
190 | execution::detail::is_valid_target_executor< |
191 | Executor, supportable_properties_type>, |
192 | false_type |
193 | >::value |
194 | > = 0) noexcept |
195 | : base_type(std::nothrow, static_cast<Executor&&>(e)) |
196 | { |
197 | } |
198 | #endif // defined(GENERATING_DOCUMENTATION) |
199 | |
200 | /// Assignment operator. |
201 | BOOST_ASIO_DECL any_io_executor& operator=( |
202 | const any_io_executor& e) noexcept; |
203 | |
204 | /// Move assignment operator. |
205 | BOOST_ASIO_DECL any_io_executor& operator=(any_io_executor&& e) noexcept; |
206 | |
207 | /// Assignment operator that sets the polymorphic wrapper to the empty state. |
208 | BOOST_ASIO_DECL any_io_executor& operator=(nullptr_t); |
209 | |
210 | /// Destructor. |
211 | BOOST_ASIO_DECL ~any_io_executor(); |
212 | |
213 | /// Swap targets with another polymorphic wrapper. |
214 | BOOST_ASIO_DECL void swap(any_io_executor& other) noexcept; |
215 | |
216 | /// Obtain a polymorphic wrapper with the specified property. |
217 | /** |
218 | * Do not call this function directly. It is intended for use with the |
219 | * boost::asio::require and boost::asio::prefer customisation points. |
220 | * |
221 | * For example: |
222 | * @code any_io_executor ex = ...; |
223 | * auto ex2 = boost::asio::require(ex, execution::blocking.possibly); @endcode |
224 | */ |
225 | template <typename Property> |
226 | any_io_executor require(const Property& p, |
227 | constraint_t< |
228 | traits::require_member<const base_type&, const Property&>::is_valid |
229 | > = 0) const |
230 | { |
231 | return static_cast<const base_type&>(*this).require(p); |
232 | } |
233 | |
234 | /// Obtain a polymorphic wrapper with the specified property. |
235 | /** |
236 | * Do not call this function directly. It is intended for use with the |
237 | * boost::asio::prefer customisation point. |
238 | * |
239 | * For example: |
240 | * @code any_io_executor ex = ...; |
241 | * auto ex2 = boost::asio::prefer(ex, execution::blocking.possibly); @endcode |
242 | */ |
243 | template <typename Property> |
244 | any_io_executor prefer(const Property& p, |
245 | constraint_t< |
246 | traits::prefer_member<const base_type&, const Property&>::is_valid |
247 | > = 0) const |
248 | { |
249 | return static_cast<const base_type&>(*this).prefer(p); |
250 | } |
251 | }; |
252 | |
253 | #if !defined(GENERATING_DOCUMENTATION) |
254 | |
255 | template <> |
256 | BOOST_ASIO_DECL any_io_executor any_io_executor::require( |
257 | const execution::blocking_t::never_t&, int) const; |
258 | |
259 | template <> |
260 | BOOST_ASIO_DECL any_io_executor any_io_executor::prefer( |
261 | const execution::blocking_t::possibly_t&, int) const; |
262 | |
263 | template <> |
264 | BOOST_ASIO_DECL any_io_executor any_io_executor::prefer( |
265 | const execution::outstanding_work_t::tracked_t&, int) const; |
266 | |
267 | template <> |
268 | BOOST_ASIO_DECL any_io_executor any_io_executor::prefer( |
269 | const execution::outstanding_work_t::untracked_t&, int) const; |
270 | |
271 | template <> |
272 | BOOST_ASIO_DECL any_io_executor any_io_executor::prefer( |
273 | const execution::relationship_t::fork_t&, int) const; |
274 | |
275 | template <> |
276 | BOOST_ASIO_DECL any_io_executor any_io_executor::prefer( |
277 | const execution::relationship_t::continuation_t&, int) const; |
278 | |
279 | namespace traits { |
280 | |
281 | #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) |
282 | |
283 | template <> |
284 | struct equality_comparable<any_io_executor> |
285 | { |
286 | static const bool is_valid = true; |
287 | static const bool is_noexcept = true; |
288 | }; |
289 | |
290 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) |
291 | |
292 | #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) |
293 | |
294 | template <typename F> |
295 | struct execute_member<any_io_executor, F> |
296 | { |
297 | static const bool is_valid = true; |
298 | static const bool is_noexcept = false; |
299 | typedef void result_type; |
300 | }; |
301 | |
302 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) |
303 | |
304 | #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) |
305 | |
306 | template <typename Prop> |
307 | struct query_member<any_io_executor, Prop> : |
308 | query_member<any_io_executor::base_type, Prop> |
309 | { |
310 | }; |
311 | |
312 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) |
313 | |
314 | #if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT) |
315 | |
316 | template <typename Prop> |
317 | struct require_member<any_io_executor, Prop> : |
318 | require_member<any_io_executor::base_type, Prop> |
319 | { |
320 | typedef any_io_executor result_type; |
321 | }; |
322 | |
323 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT) |
324 | |
325 | #if !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT) |
326 | |
327 | template <typename Prop> |
328 | struct prefer_member<any_io_executor, Prop> : |
329 | prefer_member<any_io_executor::base_type, Prop> |
330 | { |
331 | typedef any_io_executor result_type; |
332 | }; |
333 | |
334 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT) |
335 | |
336 | } // namespace traits |
337 | |
338 | #endif // !defined(GENERATING_DOCUMENTATION) |
339 | |
340 | #endif // defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) |
341 | |
342 | } // namespace asio |
343 | } // namespace boost |
344 | |
345 | #include <boost/asio/detail/pop_options.hpp> |
346 | |
347 | #if defined(BOOST_ASIO_HEADER_ONLY) \ |
348 | && !defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) |
349 | # include <boost/asio/impl/any_io_executor.ipp> |
350 | #endif // defined(BOOST_ASIO_HEADER_ONLY) |
351 | // && !defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) |
352 | |
353 | #endif // BOOST_ASIO_ANY_IO_EXECUTOR_HPP |
354 | |