outstanding_work.hpp 26 KB

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