outstanding_work.hpp 25 KB

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