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