1 | // |
2 | // execution/outstanding_work.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_EXECUTION_OUTSTANDING_WORK_HPP |
12 | #define BOOST_ASIO_EXECUTION_OUTSTANDING_WORK_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 | #include <boost/asio/detail/type_traits.hpp> |
20 | #include <boost/asio/execution/executor.hpp> |
21 | #include <boost/asio/is_applicable_property.hpp> |
22 | #include <boost/asio/query.hpp> |
23 | #include <boost/asio/traits/query_free.hpp> |
24 | #include <boost/asio/traits/query_member.hpp> |
25 | #include <boost/asio/traits/query_static_constexpr_member.hpp> |
26 | #include <boost/asio/traits/static_query.hpp> |
27 | #include <boost/asio/traits/static_require.hpp> |
28 | |
29 | #include <boost/asio/detail/push_options.hpp> |
30 | |
31 | namespace boost { |
32 | namespace asio { |
33 | |
34 | #if defined(GENERATING_DOCUMENTATION) |
35 | |
36 | namespace execution { |
37 | |
38 | /// A property to describe whether task submission is likely in the future. |
39 | struct outstanding_work_t |
40 | { |
41 | /// The outstanding_work_t property applies to executors. |
42 | template <typename T> |
43 | static constexpr bool is_applicable_property_v = is_executor_v<T>; |
44 | |
45 | /// The top-level outstanding_work_t property cannot be required. |
46 | static constexpr bool is_requirable = false; |
47 | |
48 | /// The top-level outstanding_work_t property cannot be preferred. |
49 | static constexpr bool is_preferable = false; |
50 | |
51 | /// The type returned by queries against an @c any_executor. |
52 | typedef outstanding_work_t polymorphic_query_result_type; |
53 | |
54 | /// A sub-property that indicates that the executor does not represent likely |
55 | /// future submission of a function object. |
56 | struct untracked_t |
57 | { |
58 | /// The outstanding_work_t::untracked_t property applies to executors. |
59 | template <typename T> |
60 | static constexpr bool is_applicable_property_v = is_executor_v<T>; |
61 | |
62 | /// The outstanding_work_t::untracked_t property can be required. |
63 | static constexpr bool is_requirable = true; |
64 | |
65 | /// The outstanding_work_t::untracked_t property can be preferred. |
66 | static constexpr bool is_preferable = true; |
67 | |
68 | /// The type returned by queries against an @c any_executor. |
69 | typedef outstanding_work_t polymorphic_query_result_type; |
70 | |
71 | /// Default constructor. |
72 | constexpr untracked_t(); |
73 | |
74 | /// Get the value associated with a property object. |
75 | /** |
76 | * @returns untracked_t(); |
77 | */ |
78 | static constexpr outstanding_work_t value(); |
79 | }; |
80 | |
81 | /// A sub-property that indicates that the executor represents likely |
82 | /// future submission of a function object. |
83 | struct tracked_t |
84 | { |
85 | /// The outstanding_work_t::untracked_t property applies to executors. |
86 | template <typename T> |
87 | static constexpr bool is_applicable_property_v = is_executor_v<T>; |
88 | |
89 | /// The outstanding_work_t::tracked_t property can be required. |
90 | static constexpr bool is_requirable = true; |
91 | |
92 | /// The outstanding_work_t::tracked_t property can be preferred. |
93 | static constexpr bool is_preferable = true; |
94 | |
95 | /// The type returned by queries against an @c any_executor. |
96 | typedef outstanding_work_t polymorphic_query_result_type; |
97 | |
98 | /// Default constructor. |
99 | constexpr tracked_t(); |
100 | |
101 | /// Get the value associated with a property object. |
102 | /** |
103 | * @returns tracked_t(); |
104 | */ |
105 | static constexpr outstanding_work_t value(); |
106 | }; |
107 | |
108 | /// A special value used for accessing the outstanding_work_t::untracked_t |
109 | /// property. |
110 | static constexpr untracked_t untracked; |
111 | |
112 | /// A special value used for accessing the outstanding_work_t::tracked_t |
113 | /// property. |
114 | static constexpr tracked_t tracked; |
115 | |
116 | /// Default constructor. |
117 | constexpr outstanding_work_t(); |
118 | |
119 | /// Construct from a sub-property value. |
120 | constexpr outstanding_work_t(untracked_t); |
121 | |
122 | /// Construct from a sub-property value. |
123 | constexpr outstanding_work_t(tracked_t); |
124 | |
125 | /// Compare property values for equality. |
126 | friend constexpr bool operator==( |
127 | const outstanding_work_t& a, const outstanding_work_t& b) noexcept; |
128 | |
129 | /// Compare property values for inequality. |
130 | friend constexpr bool operator!=( |
131 | const outstanding_work_t& a, const outstanding_work_t& b) noexcept; |
132 | }; |
133 | |
134 | /// A special value used for accessing the outstanding_work_t property. |
135 | constexpr outstanding_work_t outstanding_work; |
136 | |
137 | } // namespace execution |
138 | |
139 | #else // defined(GENERATING_DOCUMENTATION) |
140 | |
141 | namespace execution { |
142 | namespace detail { |
143 | namespace outstanding_work { |
144 | |
145 | template <int I> struct untracked_t; |
146 | template <int I> struct tracked_t; |
147 | |
148 | } // namespace outstanding_work |
149 | |
150 | template <int I = 0> |
151 | struct outstanding_work_t |
152 | { |
153 | #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) |
154 | template <typename T> |
155 | static constexpr bool is_applicable_property_v = is_executor<T>::value; |
156 | #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) |
157 | |
158 | static constexpr bool is_requirable = false; |
159 | static constexpr bool is_preferable = false; |
160 | typedef outstanding_work_t polymorphic_query_result_type; |
161 | |
162 | typedef detail::outstanding_work::untracked_t<I> untracked_t; |
163 | typedef detail::outstanding_work::tracked_t<I> tracked_t; |
164 | |
165 | constexpr outstanding_work_t() |
166 | : value_(-1) |
167 | { |
168 | } |
169 | |
170 | constexpr outstanding_work_t(untracked_t) |
171 | : value_(0) |
172 | { |
173 | } |
174 | |
175 | constexpr outstanding_work_t(tracked_t) |
176 | : value_(1) |
177 | { |
178 | } |
179 | |
180 | template <typename T> |
181 | struct proxy |
182 | { |
183 | #if defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) |
184 | struct type |
185 | { |
186 | template <typename P> |
187 | auto query(P&& p) const |
188 | noexcept( |
189 | noexcept( |
190 | declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p)) |
191 | ) |
192 | ) |
193 | -> decltype( |
194 | declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p)) |
195 | ); |
196 | }; |
197 | #else // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) |
198 | typedef T type; |
199 | #endif // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) |
200 | }; |
201 | |
202 | template <typename T> |
203 | struct static_proxy |
204 | { |
205 | #if defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT) |
206 | struct type |
207 | { |
208 | template <typename P> |
209 | static constexpr auto query(P&& p) |
210 | noexcept( |
211 | noexcept( |
212 | conditional_t<true, T, P>::query(static_cast<P&&>(p)) |
213 | ) |
214 | ) |
215 | -> decltype( |
216 | conditional_t<true, T, P>::query(static_cast<P&&>(p)) |
217 | ) |
218 | { |
219 | return T::query(static_cast<P&&>(p)); |
220 | } |
221 | }; |
222 | #else // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT) |
223 | typedef T type; |
224 | #endif // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT) |
225 | }; |
226 | |
227 | template <typename T> |
228 | struct query_member : |
229 | traits::query_member<typename proxy<T>::type, outstanding_work_t> {}; |
230 | |
231 | template <typename T> |
232 | struct query_static_constexpr_member : |
233 | traits::query_static_constexpr_member< |
234 | typename static_proxy<T>::type, outstanding_work_t> {}; |
235 | |
236 | #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ |
237 | && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) |
238 | template <typename T> |
239 | static constexpr |
240 | typename query_static_constexpr_member<T>::result_type |
241 | static_query() |
242 | noexcept(query_static_constexpr_member<T>::is_noexcept) |
243 | { |
244 | return query_static_constexpr_member<T>::value(); |
245 | } |
246 | |
247 | template <typename T> |
248 | static constexpr |
249 | typename traits::static_query<T, untracked_t>::result_type |
250 | static_query( |
251 | enable_if_t< |
252 | !query_static_constexpr_member<T>::is_valid |
253 | >* = 0, |
254 | enable_if_t< |
255 | !query_member<T>::is_valid |
256 | >* = 0, |
257 | enable_if_t< |
258 | traits::static_query<T, untracked_t>::is_valid |
259 | >* = 0) noexcept |
260 | { |
261 | return traits::static_query<T, untracked_t>::value(); |
262 | } |
263 | |
264 | template <typename T> |
265 | static constexpr |
266 | typename traits::static_query<T, tracked_t>::result_type |
267 | static_query( |
268 | enable_if_t< |
269 | !query_static_constexpr_member<T>::is_valid |
270 | >* = 0, |
271 | enable_if_t< |
272 | !query_member<T>::is_valid |
273 | >* = 0, |
274 | enable_if_t< |
275 | !traits::static_query<T, untracked_t>::is_valid |
276 | >* = 0, |
277 | enable_if_t< |
278 | traits::static_query<T, tracked_t>::is_valid |
279 | >* = 0) noexcept |
280 | { |
281 | return traits::static_query<T, tracked_t>::value(); |
282 | } |
283 | |
284 | template <typename E, |
285 | typename T = decltype(outstanding_work_t::static_query<E>())> |
286 | static constexpr const T static_query_v |
287 | = outstanding_work_t::static_query<E>(); |
288 | #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) |
289 | // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) |
290 | |
291 | friend constexpr bool operator==( |
292 | const outstanding_work_t& a, const outstanding_work_t& b) |
293 | { |
294 | return a.value_ == b.value_; |
295 | } |
296 | |
297 | friend constexpr bool operator!=( |
298 | const outstanding_work_t& a, const outstanding_work_t& b) |
299 | { |
300 | return a.value_ != b.value_; |
301 | } |
302 | |
303 | struct convertible_from_outstanding_work_t |
304 | { |
305 | constexpr convertible_from_outstanding_work_t(outstanding_work_t) |
306 | { |
307 | } |
308 | }; |
309 | |
310 | template <typename Executor> |
311 | friend constexpr outstanding_work_t query( |
312 | const Executor& ex, convertible_from_outstanding_work_t, |
313 | enable_if_t< |
314 | can_query<const Executor&, untracked_t>::value |
315 | >* = 0) |
316 | #if !defined(__clang__) // Clang crashes if noexcept is used here. |
317 | #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified. |
318 | noexcept(is_nothrow_query<const Executor&, |
319 | outstanding_work_t<>::untracked_t>::value) |
320 | #else // defined(BOOST_ASIO_MSVC) |
321 | noexcept(is_nothrow_query<const Executor&, untracked_t>::value) |
322 | #endif // defined(BOOST_ASIO_MSVC) |
323 | #endif // !defined(__clang__) |
324 | { |
325 | return boost::asio::query(ex, untracked_t()); |
326 | } |
327 | |
328 | template <typename Executor> |
329 | friend constexpr outstanding_work_t query( |
330 | const Executor& ex, convertible_from_outstanding_work_t, |
331 | enable_if_t< |
332 | !can_query<const Executor&, untracked_t>::value |
333 | >* = 0, |
334 | enable_if_t< |
335 | can_query<const Executor&, tracked_t>::value |
336 | >* = 0) |
337 | #if !defined(__clang__) // Clang crashes if noexcept is used here. |
338 | #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified. |
339 | noexcept(is_nothrow_query<const Executor&, |
340 | outstanding_work_t<>::tracked_t>::value) |
341 | #else // defined(BOOST_ASIO_MSVC) |
342 | noexcept(is_nothrow_query<const Executor&, tracked_t>::value) |
343 | #endif // defined(BOOST_ASIO_MSVC) |
344 | #endif // !defined(__clang__) |
345 | { |
346 | return boost::asio::query(ex, tracked_t()); |
347 | } |
348 | |
349 | BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(untracked_t, untracked); |
350 | BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(tracked_t, tracked); |
351 | |
352 | private: |
353 | int value_; |
354 | }; |
355 | |
356 | #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ |
357 | && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) |
358 | template <int I> template <typename E, typename T> |
359 | const T outstanding_work_t<I>::static_query_v; |
360 | #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) |
361 | // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) |
362 | |
363 | template <int I> |
364 | const typename outstanding_work_t<I>::untracked_t |
365 | outstanding_work_t<I>::untracked; |
366 | |
367 | template <int I> |
368 | const typename outstanding_work_t<I>::tracked_t |
369 | outstanding_work_t<I>::tracked; |
370 | |
371 | namespace outstanding_work { |
372 | |
373 | template <int I = 0> |
374 | struct untracked_t |
375 | { |
376 | #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) |
377 | template <typename T> |
378 | static constexpr bool is_applicable_property_v = is_executor<T>::value; |
379 | #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) |
380 | |
381 | static constexpr bool is_requirable = true; |
382 | static constexpr bool is_preferable = true; |
383 | typedef outstanding_work_t<I> polymorphic_query_result_type; |
384 | |
385 | constexpr untracked_t() |
386 | { |
387 | } |
388 | |
389 | template <typename T> |
390 | struct query_member : |
391 | traits::query_member< |
392 | typename outstanding_work_t<I>::template proxy<T>::type, untracked_t> {}; |
393 | |
394 | template <typename T> |
395 | struct query_static_constexpr_member : |
396 | traits::query_static_constexpr_member< |
397 | typename outstanding_work_t<I>::template static_proxy<T>::type, |
398 | untracked_t> {}; |
399 | |
400 | #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ |
401 | && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) |
402 | template <typename T> |
403 | static constexpr |
404 | typename query_static_constexpr_member<T>::result_type |
405 | static_query() |
406 | noexcept(query_static_constexpr_member<T>::is_noexcept) |
407 | { |
408 | return query_static_constexpr_member<T>::value(); |
409 | } |
410 | |
411 | template <typename T> |
412 | static constexpr untracked_t static_query( |
413 | enable_if_t< |
414 | !query_static_constexpr_member<T>::is_valid |
415 | >* = 0, |
416 | enable_if_t< |
417 | !query_member<T>::is_valid |
418 | >* = 0, |
419 | enable_if_t< |
420 | !traits::query_free<T, untracked_t>::is_valid |
421 | >* = 0, |
422 | enable_if_t< |
423 | !can_query<T, tracked_t<I>>::value |
424 | >* = 0) noexcept |
425 | { |
426 | return untracked_t(); |
427 | } |
428 | |
429 | template <typename E, typename T = decltype(untracked_t::static_query<E>())> |
430 | static constexpr const T static_query_v = untracked_t::static_query<E>(); |
431 | #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) |
432 | // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) |
433 | |
434 | static constexpr outstanding_work_t<I> value() |
435 | { |
436 | return untracked_t(); |
437 | } |
438 | |
439 | friend constexpr bool operator==(const untracked_t&, const untracked_t&) |
440 | { |
441 | return true; |
442 | } |
443 | |
444 | friend constexpr bool operator!=(const untracked_t&, const untracked_t&) |
445 | { |
446 | return false; |
447 | } |
448 | |
449 | friend constexpr bool operator==(const untracked_t&, const tracked_t<I>&) |
450 | { |
451 | return false; |
452 | } |
453 | |
454 | friend constexpr bool operator!=(const untracked_t&, const tracked_t<I>&) |
455 | { |
456 | return true; |
457 | } |
458 | }; |
459 | |
460 | #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ |
461 | && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) |
462 | template <int I> template <typename E, typename T> |
463 | const T untracked_t<I>::static_query_v; |
464 | #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) |
465 | // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) |
466 | |
467 | template <int I = 0> |
468 | struct tracked_t |
469 | { |
470 | #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) |
471 | template <typename T> |
472 | static constexpr bool is_applicable_property_v = is_executor<T>::value; |
473 | #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) |
474 | |
475 | static constexpr bool is_requirable = true; |
476 | static constexpr bool is_preferable = true; |
477 | typedef outstanding_work_t<I> polymorphic_query_result_type; |
478 | |
479 | constexpr tracked_t() |
480 | { |
481 | } |
482 | |
483 | template <typename T> |
484 | struct query_member : |
485 | traits::query_member< |
486 | typename outstanding_work_t<I>::template proxy<T>::type, tracked_t> {}; |
487 | |
488 | template <typename T> |
489 | struct query_static_constexpr_member : |
490 | traits::query_static_constexpr_member< |
491 | typename outstanding_work_t<I>::template static_proxy<T>::type, |
492 | tracked_t> {}; |
493 | |
494 | #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ |
495 | && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) |
496 | template <typename T> |
497 | static constexpr |
498 | typename query_static_constexpr_member<T>::result_type |
499 | static_query() |
500 | noexcept(query_static_constexpr_member<T>::is_noexcept) |
501 | { |
502 | return query_static_constexpr_member<T>::value(); |
503 | } |
504 | |
505 | template <typename E, typename T = decltype(tracked_t::static_query<E>())> |
506 | static constexpr const T static_query_v = tracked_t::static_query<E>(); |
507 | #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) |
508 | // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) |
509 | |
510 | static constexpr outstanding_work_t<I> value() |
511 | { |
512 | return tracked_t(); |
513 | } |
514 | |
515 | friend constexpr bool operator==(const tracked_t&, const tracked_t&) |
516 | { |
517 | return true; |
518 | } |
519 | |
520 | friend constexpr bool operator!=(const tracked_t&, const tracked_t&) |
521 | { |
522 | return false; |
523 | } |
524 | |
525 | friend constexpr bool operator==(const tracked_t&, const untracked_t<I>&) |
526 | { |
527 | return false; |
528 | } |
529 | |
530 | friend constexpr bool operator!=(const tracked_t&, const untracked_t<I>&) |
531 | { |
532 | return true; |
533 | } |
534 | }; |
535 | |
536 | #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ |
537 | && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) |
538 | template <int I> template <typename E, typename T> |
539 | const T tracked_t<I>::static_query_v; |
540 | #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) |
541 | // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) |
542 | |
543 | } // namespace outstanding_work |
544 | } // namespace detail |
545 | |
546 | typedef detail::outstanding_work_t<> outstanding_work_t; |
547 | |
548 | constexpr outstanding_work_t outstanding_work; |
549 | |
550 | } // namespace execution |
551 | |
552 | #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) |
553 | |
554 | template <typename T> |
555 | struct is_applicable_property<T, execution::outstanding_work_t> |
556 | : integral_constant<bool, execution::is_executor<T>::value> |
557 | { |
558 | }; |
559 | |
560 | template <typename T> |
561 | struct is_applicable_property<T, execution::outstanding_work_t::untracked_t> |
562 | : integral_constant<bool, execution::is_executor<T>::value> |
563 | { |
564 | }; |
565 | |
566 | template <typename T> |
567 | struct is_applicable_property<T, execution::outstanding_work_t::tracked_t> |
568 | : integral_constant<bool, execution::is_executor<T>::value> |
569 | { |
570 | }; |
571 | |
572 | #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) |
573 | |
574 | namespace traits { |
575 | |
576 | #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) |
577 | |
578 | template <typename T> |
579 | struct query_free_default<T, execution::outstanding_work_t, |
580 | enable_if_t< |
581 | can_query<T, execution::outstanding_work_t::untracked_t>::value |
582 | >> |
583 | { |
584 | static constexpr bool is_valid = true; |
585 | static constexpr bool is_noexcept = |
586 | is_nothrow_query<T, execution::outstanding_work_t::untracked_t>::value; |
587 | |
588 | typedef execution::outstanding_work_t result_type; |
589 | }; |
590 | |
591 | template <typename T> |
592 | struct query_free_default<T, execution::outstanding_work_t, |
593 | enable_if_t< |
594 | !can_query<T, execution::outstanding_work_t::untracked_t>::value |
595 | && can_query<T, execution::outstanding_work_t::tracked_t>::value |
596 | >> |
597 | { |
598 | static constexpr bool is_valid = true; |
599 | static constexpr bool is_noexcept = |
600 | is_nothrow_query<T, execution::outstanding_work_t::tracked_t>::value; |
601 | |
602 | typedef execution::outstanding_work_t result_type; |
603 | }; |
604 | |
605 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) |
606 | |
607 | #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ |
608 | || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) |
609 | |
610 | template <typename T> |
611 | struct static_query<T, execution::outstanding_work_t, |
612 | enable_if_t< |
613 | execution::detail::outstanding_work_t<0>:: |
614 | query_static_constexpr_member<T>::is_valid |
615 | >> |
616 | { |
617 | static constexpr bool is_valid = true; |
618 | static constexpr bool is_noexcept = true; |
619 | |
620 | typedef typename execution::detail::outstanding_work_t<0>:: |
621 | query_static_constexpr_member<T>::result_type result_type; |
622 | |
623 | static constexpr result_type value() |
624 | { |
625 | return execution::detail::outstanding_work_t<0>:: |
626 | query_static_constexpr_member<T>::value(); |
627 | } |
628 | }; |
629 | |
630 | template <typename T> |
631 | struct static_query<T, execution::outstanding_work_t, |
632 | enable_if_t< |
633 | !execution::detail::outstanding_work_t<0>:: |
634 | query_static_constexpr_member<T>::is_valid |
635 | && !execution::detail::outstanding_work_t<0>:: |
636 | query_member<T>::is_valid |
637 | && traits::static_query<T, |
638 | execution::outstanding_work_t::untracked_t>::is_valid |
639 | >> |
640 | { |
641 | static constexpr bool is_valid = true; |
642 | static constexpr bool is_noexcept = true; |
643 | |
644 | typedef typename traits::static_query<T, |
645 | execution::outstanding_work_t::untracked_t>::result_type result_type; |
646 | |
647 | static constexpr result_type value() |
648 | { |
649 | return traits::static_query<T, |
650 | execution::outstanding_work_t::untracked_t>::value(); |
651 | } |
652 | }; |
653 | |
654 | template <typename T> |
655 | struct static_query<T, execution::outstanding_work_t, |
656 | enable_if_t< |
657 | !execution::detail::outstanding_work_t<0>:: |
658 | query_static_constexpr_member<T>::is_valid |
659 | && !execution::detail::outstanding_work_t<0>:: |
660 | query_member<T>::is_valid |
661 | && !traits::static_query<T, |
662 | execution::outstanding_work_t::untracked_t>::is_valid |
663 | && traits::static_query<T, |
664 | execution::outstanding_work_t::tracked_t>::is_valid |
665 | >> |
666 | { |
667 | static constexpr bool is_valid = true; |
668 | static constexpr bool is_noexcept = true; |
669 | |
670 | typedef typename traits::static_query<T, |
671 | execution::outstanding_work_t::tracked_t>::result_type result_type; |
672 | |
673 | static constexpr result_type value() |
674 | { |
675 | return traits::static_query<T, |
676 | execution::outstanding_work_t::tracked_t>::value(); |
677 | } |
678 | }; |
679 | |
680 | template <typename T> |
681 | struct static_query<T, execution::outstanding_work_t::untracked_t, |
682 | enable_if_t< |
683 | execution::detail::outstanding_work::untracked_t<0>:: |
684 | query_static_constexpr_member<T>::is_valid |
685 | >> |
686 | { |
687 | static constexpr bool is_valid = true; |
688 | static constexpr bool is_noexcept = true; |
689 | |
690 | typedef typename execution::detail::outstanding_work::untracked_t<0>:: |
691 | query_static_constexpr_member<T>::result_type result_type; |
692 | |
693 | static constexpr result_type value() |
694 | { |
695 | return execution::detail::outstanding_work::untracked_t<0>:: |
696 | query_static_constexpr_member<T>::value(); |
697 | } |
698 | }; |
699 | |
700 | template <typename T> |
701 | struct static_query<T, execution::outstanding_work_t::untracked_t, |
702 | enable_if_t< |
703 | !execution::detail::outstanding_work::untracked_t<0>:: |
704 | query_static_constexpr_member<T>::is_valid |
705 | && !execution::detail::outstanding_work::untracked_t<0>:: |
706 | query_member<T>::is_valid |
707 | && !traits::query_free<T, |
708 | execution::outstanding_work_t::untracked_t>::is_valid |
709 | && !can_query<T, execution::outstanding_work_t::tracked_t>::value |
710 | >> |
711 | { |
712 | static constexpr bool is_valid = true; |
713 | static constexpr bool is_noexcept = true; |
714 | |
715 | typedef execution::outstanding_work_t::untracked_t result_type; |
716 | |
717 | static constexpr result_type value() |
718 | { |
719 | return result_type(); |
720 | } |
721 | }; |
722 | |
723 | template <typename T> |
724 | struct static_query<T, execution::outstanding_work_t::tracked_t, |
725 | enable_if_t< |
726 | execution::detail::outstanding_work::tracked_t<0>:: |
727 | query_static_constexpr_member<T>::is_valid |
728 | >> |
729 | { |
730 | static constexpr bool is_valid = true; |
731 | static constexpr bool is_noexcept = true; |
732 | |
733 | typedef typename execution::detail::outstanding_work::tracked_t<0>:: |
734 | query_static_constexpr_member<T>::result_type result_type; |
735 | |
736 | static constexpr result_type value() |
737 | { |
738 | return execution::detail::outstanding_work::tracked_t<0>:: |
739 | query_static_constexpr_member<T>::value(); |
740 | } |
741 | }; |
742 | |
743 | #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) |
744 | // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) |
745 | |
746 | } // namespace traits |
747 | |
748 | #endif // defined(GENERATING_DOCUMENTATION) |
749 | |
750 | } // namespace asio |
751 | } // namespace boost |
752 | |
753 | #include <boost/asio/detail/pop_options.hpp> |
754 | |
755 | #endif // BOOST_ASIO_EXECUTION_OUTSTANDING_WORK_HPP |
756 | |