2 // execution/outstanding_work.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_EXECUTION_OUTSTANDING_WORK_HPP
12 #define BOOST_ASIO_EXECUTION_OUTSTANDING_WORK_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
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/execution/scheduler.hpp>
22 #include <boost/asio/execution/sender.hpp>
23 #include <boost/asio/is_applicable_property.hpp>
24 #include <boost/asio/query.hpp>
25 #include <boost/asio/traits/query_free.hpp>
26 #include <boost/asio/traits/query_member.hpp>
27 #include <boost/asio/traits/query_static_constexpr_member.hpp>
28 #include <boost/asio/traits/static_query.hpp>
29 #include <boost/asio/traits/static_require.hpp>
31 #include <boost/asio/detail/push_options.hpp>
36 #if defined(GENERATING_DOCUMENTATION)
40 /// A property to describe whether task submission is likely in the future.
41 struct outstanding_work_t
43 /// The outstanding_work_t property applies to executors, senders, and
46 static constexpr bool is_applicable_property_v =
47 is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
49 /// The top-level outstanding_work_t property cannot be required.
50 static constexpr bool is_requirable = false;
52 /// The top-level outstanding_work_t property cannot be preferred.
53 static constexpr bool is_preferable = false;
55 /// The type returned by queries against an @c any_executor.
56 typedef outstanding_work_t polymorphic_query_result_type;
58 /// A sub-property that indicates that the executor does not represent likely
59 /// future submission of a function object.
62 /// The outstanding_work_t::untracked_t property applies to executors,
63 /// senders, and schedulers.
65 static constexpr bool is_applicable_property_v =
66 is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
68 /// The outstanding_work_t::untracked_t property can be required.
69 static constexpr bool is_requirable = true;
71 /// The outstanding_work_t::untracked_t property can be preferred.
72 static constexpr bool is_preferable = true;
74 /// The type returned by queries against an @c any_executor.
75 typedef outstanding_work_t polymorphic_query_result_type;
77 /// Default constructor.
78 constexpr untracked_t();
80 /// Get the value associated with a property object.
82 * @returns untracked_t();
84 static constexpr outstanding_work_t value();
87 /// A sub-property that indicates that the executor represents likely
88 /// future submission of a function object.
91 /// The outstanding_work_t::untracked_t property applies to executors,
92 /// senders, and schedulers.
94 static constexpr bool is_applicable_property_v =
95 is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
97 /// The outstanding_work_t::tracked_t property can be required.
98 static constexpr bool is_requirable = true;
100 /// The outstanding_work_t::tracked_t property can be preferred.
101 static constexpr bool is_preferable = true;
103 /// The type returned by queries against an @c any_executor.
104 typedef outstanding_work_t polymorphic_query_result_type;
106 /// Default constructor.
107 constexpr tracked_t();
109 /// Get the value associated with a property object.
111 * @returns tracked_t();
113 static constexpr outstanding_work_t value();
116 /// A special value used for accessing the outstanding_work_t::untracked_t
118 static constexpr untracked_t untracked;
120 /// A special value used for accessing the outstanding_work_t::tracked_t
122 static constexpr tracked_t tracked;
124 /// Default constructor.
125 constexpr outstanding_work_t();
127 /// Construct from a sub-property value.
128 constexpr outstanding_work_t(untracked_t);
130 /// Construct from a sub-property value.
131 constexpr outstanding_work_t(tracked_t);
133 /// Compare property values for equality.
134 friend constexpr bool operator==(
135 const outstanding_work_t& a, const outstanding_work_t& b) noexcept;
137 /// Compare property values for inequality.
138 friend constexpr bool operator!=(
139 const outstanding_work_t& a, const outstanding_work_t& b) noexcept;
142 /// A special value used for accessing the outstanding_work_t property.
143 constexpr outstanding_work_t outstanding_work;
145 } // namespace execution
147 #else // defined(GENERATING_DOCUMENTATION)
149 namespace execution {
151 namespace outstanding_work {
153 template <int I> struct untracked_t;
154 template <int I> struct tracked_t;
156 } // namespace outstanding_work
159 struct outstanding_work_t
161 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
162 template <typename T>
163 BOOST_ASIO_STATIC_CONSTEXPR(bool,
164 is_applicable_property_v = is_executor<T>::value
165 || is_sender<T>::value || is_scheduler<T>::value);
166 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
168 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);
169 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);
170 typedef outstanding_work_t polymorphic_query_result_type;
172 typedef detail::outstanding_work::untracked_t<I> untracked_t;
173 typedef detail::outstanding_work::tracked_t<I> tracked_t;
175 BOOST_ASIO_CONSTEXPR outstanding_work_t()
180 BOOST_ASIO_CONSTEXPR outstanding_work_t(untracked_t)
185 BOOST_ASIO_CONSTEXPR outstanding_work_t(tracked_t)
190 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
191 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
192 template <typename T>
193 static BOOST_ASIO_CONSTEXPR
194 typename traits::query_static_constexpr_member<
195 T, outstanding_work_t>::result_type
197 BOOST_ASIO_NOEXCEPT_IF((
198 traits::query_static_constexpr_member<
199 T, outstanding_work_t
202 return traits::query_static_constexpr_member<
203 T, outstanding_work_t>::value();
206 template <typename T>
207 static BOOST_ASIO_CONSTEXPR
208 typename traits::static_query<T, untracked_t>::result_type
211 !traits::query_static_constexpr_member<
212 T, outstanding_work_t>::is_valid
213 && !traits::query_member<T, outstanding_work_t>::is_valid
214 && traits::static_query<T, untracked_t>::is_valid
215 >::type* = 0) BOOST_ASIO_NOEXCEPT
217 return traits::static_query<T, untracked_t>::value();
220 template <typename T>
221 static BOOST_ASIO_CONSTEXPR
222 typename traits::static_query<T, tracked_t>::result_type
225 !traits::query_static_constexpr_member<
226 T, outstanding_work_t>::is_valid
227 && !traits::query_member<T, outstanding_work_t>::is_valid
228 && !traits::static_query<T, untracked_t>::is_valid
229 && traits::static_query<T, tracked_t>::is_valid
230 >::type* = 0) BOOST_ASIO_NOEXCEPT
232 return traits::static_query<T, tracked_t>::value();
235 template <typename E,
236 typename T = decltype(outstanding_work_t::static_query<E>())>
237 static BOOST_ASIO_CONSTEXPR const T static_query_v
238 = outstanding_work_t::static_query<E>();
239 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
240 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
242 friend BOOST_ASIO_CONSTEXPR bool operator==(
243 const outstanding_work_t& a, const outstanding_work_t& b)
245 return a.value_ == b.value_;
248 friend BOOST_ASIO_CONSTEXPR bool operator!=(
249 const outstanding_work_t& a, const outstanding_work_t& b)
251 return a.value_ != b.value_;
254 struct convertible_from_outstanding_work_t
256 BOOST_ASIO_CONSTEXPR convertible_from_outstanding_work_t(outstanding_work_t)
261 template <typename Executor>
262 friend BOOST_ASIO_CONSTEXPR outstanding_work_t query(
263 const Executor& ex, convertible_from_outstanding_work_t,
265 can_query<const Executor&, untracked_t>::value
267 #if !defined(__clang__) // Clang crashes if noexcept is used here.
268 #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified.
269 BOOST_ASIO_NOEXCEPT_IF((
270 is_nothrow_query<const Executor&,
271 outstanding_work_t<>::untracked_t>::value))
272 #else // defined(BOOST_ASIO_MSVC)
273 BOOST_ASIO_NOEXCEPT_IF((
274 is_nothrow_query<const Executor&, untracked_t>::value))
275 #endif // defined(BOOST_ASIO_MSVC)
276 #endif // !defined(__clang__)
278 return boost::asio::query(ex, untracked_t());
281 template <typename Executor>
282 friend BOOST_ASIO_CONSTEXPR outstanding_work_t query(
283 const Executor& ex, convertible_from_outstanding_work_t,
285 !can_query<const Executor&, untracked_t>::value
286 && can_query<const Executor&, tracked_t>::value
288 #if !defined(__clang__) // Clang crashes if noexcept is used here.
289 #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified.
290 BOOST_ASIO_NOEXCEPT_IF((
291 is_nothrow_query<const Executor&,
292 outstanding_work_t<>::tracked_t>::value))
293 #else // defined(BOOST_ASIO_MSVC)
294 BOOST_ASIO_NOEXCEPT_IF((
295 is_nothrow_query<const Executor&, tracked_t>::value))
296 #endif // defined(BOOST_ASIO_MSVC)
297 #endif // !defined(__clang__)
299 return boost::asio::query(ex, tracked_t());
302 BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(untracked_t, untracked);
303 BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(tracked_t, tracked);
305 #if !defined(BOOST_ASIO_HAS_CONSTEXPR)
306 static const outstanding_work_t instance;
307 #endif // !defined(BOOST_ASIO_HAS_CONSTEXPR)
313 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
314 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
315 template <int I> template <typename E, typename T>
316 const T outstanding_work_t<I>::static_query_v;
317 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
318 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
320 #if !defined(BOOST_ASIO_HAS_CONSTEXPR)
322 const outstanding_work_t<I> outstanding_work_t<I>::instance;
326 const typename outstanding_work_t<I>::untracked_t
327 outstanding_work_t<I>::untracked;
330 const typename outstanding_work_t<I>::tracked_t
331 outstanding_work_t<I>::tracked;
333 namespace outstanding_work {
338 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
339 template <typename T>
340 BOOST_ASIO_STATIC_CONSTEXPR(bool,
341 is_applicable_property_v = is_executor<T>::value
342 || is_sender<T>::value || is_scheduler<T>::value);
343 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
345 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
346 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);
347 typedef outstanding_work_t<I> polymorphic_query_result_type;
349 BOOST_ASIO_CONSTEXPR untracked_t()
353 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
354 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
355 template <typename T>
356 static BOOST_ASIO_CONSTEXPR
357 typename traits::query_static_constexpr_member<T, untracked_t>::result_type
359 BOOST_ASIO_NOEXCEPT_IF((
360 traits::query_static_constexpr_member<T, untracked_t>::is_noexcept))
362 return traits::query_static_constexpr_member<T, untracked_t>::value();
365 template <typename T>
366 static BOOST_ASIO_CONSTEXPR untracked_t static_query(
368 !traits::query_static_constexpr_member<T, untracked_t>::is_valid
369 && !traits::query_member<T, untracked_t>::is_valid
370 && !traits::query_free<T, untracked_t>::is_valid
371 && !can_query<T, tracked_t<I> >::value
372 >::type* = 0) BOOST_ASIO_NOEXCEPT
374 return untracked_t();
377 template <typename E, typename T = decltype(untracked_t::static_query<E>())>
378 static BOOST_ASIO_CONSTEXPR const T static_query_v
379 = untracked_t::static_query<E>();
380 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
381 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
383 static BOOST_ASIO_CONSTEXPR outstanding_work_t<I> value()
385 return untracked_t();
388 friend BOOST_ASIO_CONSTEXPR bool operator==(
389 const untracked_t&, const untracked_t&)
394 friend BOOST_ASIO_CONSTEXPR bool operator!=(
395 const untracked_t&, const untracked_t&)
401 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
402 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
403 template <int I> template <typename E, typename T>
404 const T untracked_t<I>::static_query_v;
405 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
406 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
411 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
412 template <typename T>
413 BOOST_ASIO_STATIC_CONSTEXPR(bool,
414 is_applicable_property_v = is_executor<T>::value
415 || is_sender<T>::value || is_scheduler<T>::value);
416 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
418 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
419 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);
420 typedef outstanding_work_t<I> polymorphic_query_result_type;
422 BOOST_ASIO_CONSTEXPR tracked_t()
426 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
427 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
428 template <typename T>
429 static BOOST_ASIO_CONSTEXPR
430 typename traits::query_static_constexpr_member<T, tracked_t>::result_type
432 BOOST_ASIO_NOEXCEPT_IF((
433 traits::query_static_constexpr_member<T, tracked_t>::is_noexcept))
435 return traits::query_static_constexpr_member<T, tracked_t>::value();
438 template <typename E, typename T = decltype(tracked_t::static_query<E>())>
439 static BOOST_ASIO_CONSTEXPR const T static_query_v
440 = tracked_t::static_query<E>();
441 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
442 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
444 static BOOST_ASIO_CONSTEXPR outstanding_work_t<I> value()
449 friend BOOST_ASIO_CONSTEXPR bool operator==(
450 const tracked_t&, const tracked_t&)
455 friend BOOST_ASIO_CONSTEXPR bool operator!=(
456 const tracked_t&, const tracked_t&)
462 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
463 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
464 template <int I> template <typename E, typename T>
465 const T tracked_t<I>::static_query_v;
466 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
467 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
469 } // namespace outstanding_work
470 } // namespace detail
472 typedef detail::outstanding_work_t<> outstanding_work_t;
474 #if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
475 constexpr outstanding_work_t outstanding_work;
476 #else // defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
477 namespace { static const outstanding_work_t&
478 outstanding_work = outstanding_work_t::instance; }
481 } // namespace execution
483 #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
485 template <typename T>
486 struct is_applicable_property<T, execution::outstanding_work_t>
487 : integral_constant<bool,
488 execution::is_executor<T>::value
489 || execution::is_sender<T>::value
490 || execution::is_scheduler<T>::value>
494 template <typename T>
495 struct is_applicable_property<T, execution::outstanding_work_t::untracked_t>
496 : integral_constant<bool,
497 execution::is_executor<T>::value
498 || execution::is_sender<T>::value
499 || execution::is_scheduler<T>::value>
503 template <typename T>
504 struct is_applicable_property<T, execution::outstanding_work_t::tracked_t>
505 : integral_constant<bool,
506 execution::is_executor<T>::value
507 || execution::is_sender<T>::value
508 || execution::is_scheduler<T>::value>
512 #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
516 #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
518 template <typename T>
519 struct query_free_default<T, execution::outstanding_work_t,
521 can_query<T, execution::outstanding_work_t::untracked_t>::value
524 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
525 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
526 (is_nothrow_query<T, execution::outstanding_work_t::untracked_t>::value));
528 typedef execution::outstanding_work_t result_type;
531 template <typename T>
532 struct query_free_default<T, execution::outstanding_work_t,
534 !can_query<T, execution::outstanding_work_t::untracked_t>::value
535 && can_query<T, execution::outstanding_work_t::tracked_t>::value
538 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
539 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
540 (is_nothrow_query<T, execution::outstanding_work_t::tracked_t>::value));
542 typedef execution::outstanding_work_t result_type;
545 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
547 #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
548 || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
550 template <typename T>
551 struct static_query<T, execution::outstanding_work_t,
553 traits::query_static_constexpr_member<T,
554 execution::outstanding_work_t>::is_valid
557 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
558 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
560 typedef typename traits::query_static_constexpr_member<T,
561 execution::outstanding_work_t>::result_type result_type;
563 static BOOST_ASIO_CONSTEXPR result_type value()
565 return traits::query_static_constexpr_member<T,
566 execution::outstanding_work_t>::value();
570 template <typename T>
571 struct static_query<T, execution::outstanding_work_t,
573 !traits::query_static_constexpr_member<T,
574 execution::outstanding_work_t>::is_valid
575 && !traits::query_member<T,
576 execution::outstanding_work_t>::is_valid
577 && traits::static_query<T,
578 execution::outstanding_work_t::untracked_t>::is_valid
581 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
582 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
584 typedef typename traits::static_query<T,
585 execution::outstanding_work_t::untracked_t>::result_type result_type;
587 static BOOST_ASIO_CONSTEXPR result_type value()
589 return traits::static_query<T,
590 execution::outstanding_work_t::untracked_t>::value();
594 template <typename T>
595 struct static_query<T, execution::outstanding_work_t,
597 !traits::query_static_constexpr_member<T,
598 execution::outstanding_work_t>::is_valid
599 && !traits::query_member<T,
600 execution::outstanding_work_t>::is_valid
601 && !traits::static_query<T,
602 execution::outstanding_work_t::untracked_t>::is_valid
603 && traits::static_query<T,
604 execution::outstanding_work_t::tracked_t>::is_valid
607 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
608 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
610 typedef typename traits::static_query<T,
611 execution::outstanding_work_t::tracked_t>::result_type result_type;
613 static BOOST_ASIO_CONSTEXPR result_type value()
615 return traits::static_query<T,
616 execution::outstanding_work_t::tracked_t>::value();
620 template <typename T>
621 struct static_query<T, execution::outstanding_work_t::untracked_t,
623 traits::query_static_constexpr_member<T,
624 execution::outstanding_work_t::untracked_t>::is_valid
627 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
628 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
630 typedef typename traits::query_static_constexpr_member<T,
631 execution::outstanding_work_t::untracked_t>::result_type result_type;
633 static BOOST_ASIO_CONSTEXPR result_type value()
635 return traits::query_static_constexpr_member<T,
636 execution::outstanding_work_t::untracked_t>::value();
640 template <typename T>
641 struct static_query<T, execution::outstanding_work_t::untracked_t,
643 !traits::query_static_constexpr_member<T,
644 execution::outstanding_work_t::untracked_t>::is_valid
645 && !traits::query_member<T,
646 execution::outstanding_work_t::untracked_t>::is_valid
647 && !traits::query_free<T,
648 execution::outstanding_work_t::untracked_t>::is_valid
649 && !can_query<T, execution::outstanding_work_t::tracked_t>::value
652 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
653 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
655 typedef execution::outstanding_work_t::untracked_t result_type;
657 static BOOST_ASIO_CONSTEXPR result_type value()
659 return result_type();
663 template <typename T>
664 struct static_query<T, execution::outstanding_work_t::tracked_t,
666 traits::query_static_constexpr_member<T,
667 execution::outstanding_work_t::tracked_t>::is_valid
670 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
671 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
673 typedef typename traits::query_static_constexpr_member<T,
674 execution::outstanding_work_t::tracked_t>::result_type result_type;
676 static BOOST_ASIO_CONSTEXPR result_type value()
678 return traits::query_static_constexpr_member<T,
679 execution::outstanding_work_t::tracked_t>::value();
683 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
684 // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
686 #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)
688 template <typename T>
689 struct static_require<T, execution::outstanding_work_t::untracked_t,
691 static_query<T, execution::outstanding_work_t::untracked_t>::is_valid
694 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid =
695 (is_same<typename static_query<T,
696 execution::outstanding_work_t::untracked_t>::result_type,
697 execution::outstanding_work_t::untracked_t>::value));
700 template <typename T>
701 struct static_require<T, execution::outstanding_work_t::tracked_t,
703 static_query<T, execution::outstanding_work_t::tracked_t>::is_valid
706 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid =
707 (is_same<typename static_query<T,
708 execution::outstanding_work_t::tracked_t>::result_type,
709 execution::outstanding_work_t::tracked_t>::value));
712 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)
714 } // namespace traits
716 #endif // defined(GENERATING_DOCUMENTATION)
721 #include <boost/asio/detail/pop_options.hpp>
723 #endif // BOOST_ASIO_EXECUTION_OUTSTANDING_WORK_HPP