mapping.hpp 28 KB

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