relationship.hpp 27 KB

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