system_executor.hpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. //
  2. // system_executor.hpp
  3. // ~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2025 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_SYSTEM_EXECUTOR_HPP
  11. #define BOOST_ASIO_SYSTEM_EXECUTOR_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/memory.hpp>
  17. #include <boost/asio/execution.hpp>
  18. #include <boost/asio/detail/push_options.hpp>
  19. namespace boost {
  20. namespace asio {
  21. class system_context;
  22. /// An executor that uses arbitrary threads.
  23. /**
  24. * The system executor represents an execution context where functions are
  25. * permitted to run on arbitrary threads. When the blocking.never property is
  26. * established, the system executor will schedule the function to run on an
  27. * unspecified system thread pool. When either blocking.possibly or
  28. * blocking.always is established, the executor invokes the function
  29. * immediately.
  30. */
  31. template <typename Blocking, typename Relationship, typename Allocator>
  32. class basic_system_executor
  33. {
  34. public:
  35. /// Default constructor.
  36. basic_system_executor() noexcept
  37. : allocator_(Allocator())
  38. {
  39. }
  40. #if !defined(GENERATING_DOCUMENTATION)
  41. private:
  42. friend struct boost_asio_require_fn::impl;
  43. friend struct boost_asio_prefer_fn::impl;
  44. #endif // !defined(GENERATING_DOCUMENTATION)
  45. /// Obtain an executor with the @c blocking.possibly property.
  46. /**
  47. * Do not call this function directly. It is intended for use with the
  48. * boost::asio::require customisation point.
  49. *
  50. * For example:
  51. * @code boost::asio::system_executor ex1;
  52. * auto ex2 = boost::asio::require(ex1,
  53. * boost::asio::execution::blocking.possibly); @endcode
  54. */
  55. basic_system_executor<execution::blocking_t::possibly_t,
  56. Relationship, Allocator>
  57. require(execution::blocking_t::possibly_t) const
  58. {
  59. return basic_system_executor<execution::blocking_t::possibly_t,
  60. Relationship, Allocator>(allocator_);
  61. }
  62. /// Obtain an executor with the @c blocking.always property.
  63. /**
  64. * Do not call this function directly. It is intended for use with the
  65. * boost::asio::require customisation point.
  66. *
  67. * For example:
  68. * @code boost::asio::system_executor ex1;
  69. * auto ex2 = boost::asio::require(ex1,
  70. * boost::asio::execution::blocking.always); @endcode
  71. */
  72. basic_system_executor<execution::blocking_t::always_t,
  73. Relationship, Allocator>
  74. require(execution::blocking_t::always_t) const
  75. {
  76. return basic_system_executor<execution::blocking_t::always_t,
  77. Relationship, Allocator>(allocator_);
  78. }
  79. /// Obtain an executor with the @c blocking.never property.
  80. /**
  81. * Do not call this function directly. It is intended for use with the
  82. * boost::asio::require customisation point.
  83. *
  84. * For example:
  85. * @code boost::asio::system_executor ex1;
  86. * auto ex2 = boost::asio::require(ex1,
  87. * boost::asio::execution::blocking.never); @endcode
  88. */
  89. basic_system_executor<execution::blocking_t::never_t,
  90. Relationship, Allocator>
  91. require(execution::blocking_t::never_t) const
  92. {
  93. return basic_system_executor<execution::blocking_t::never_t,
  94. Relationship, Allocator>(allocator_);
  95. }
  96. /// Obtain an executor with the @c relationship.continuation property.
  97. /**
  98. * Do not call this function directly. It is intended for use with the
  99. * boost::asio::require customisation point.
  100. *
  101. * For example:
  102. * @code boost::asio::system_executor ex1;
  103. * auto ex2 = boost::asio::require(ex1,
  104. * boost::asio::execution::relationship.continuation); @endcode
  105. */
  106. basic_system_executor<Blocking,
  107. execution::relationship_t::continuation_t, Allocator>
  108. require(execution::relationship_t::continuation_t) const
  109. {
  110. return basic_system_executor<Blocking,
  111. execution::relationship_t::continuation_t, Allocator>(allocator_);
  112. }
  113. /// Obtain an executor with the @c relationship.fork property.
  114. /**
  115. * Do not call this function directly. It is intended for use with the
  116. * boost::asio::require customisation point.
  117. *
  118. * For example:
  119. * @code boost::asio::system_executor ex1;
  120. * auto ex2 = boost::asio::require(ex1,
  121. * boost::asio::execution::relationship.fork); @endcode
  122. */
  123. basic_system_executor<Blocking,
  124. execution::relationship_t::fork_t, Allocator>
  125. require(execution::relationship_t::fork_t) const
  126. {
  127. return basic_system_executor<Blocking,
  128. execution::relationship_t::fork_t, Allocator>(allocator_);
  129. }
  130. /// Obtain an executor with the specified @c allocator property.
  131. /**
  132. * Do not call this function directly. It is intended for use with the
  133. * boost::asio::require customisation point.
  134. *
  135. * For example:
  136. * @code boost::asio::system_executor ex1;
  137. * auto ex2 = boost::asio::require(ex1,
  138. * boost::asio::execution::allocator(my_allocator)); @endcode
  139. */
  140. template <typename OtherAllocator>
  141. basic_system_executor<Blocking, Relationship, OtherAllocator>
  142. require(execution::allocator_t<OtherAllocator> a) const
  143. {
  144. return basic_system_executor<Blocking,
  145. Relationship, OtherAllocator>(a.value());
  146. }
  147. /// Obtain an executor with the default @c allocator property.
  148. /**
  149. * Do not call this function directly. It is intended for use with the
  150. * boost::asio::require customisation point.
  151. *
  152. * For example:
  153. * @code boost::asio::system_executor ex1;
  154. * auto ex2 = boost::asio::require(ex1,
  155. * boost::asio::execution::allocator); @endcode
  156. */
  157. basic_system_executor<Blocking, Relationship, std::allocator<void>>
  158. require(execution::allocator_t<void>) const
  159. {
  160. return basic_system_executor<Blocking,
  161. Relationship, std::allocator<void>>();
  162. }
  163. #if !defined(GENERATING_DOCUMENTATION)
  164. private:
  165. friend struct boost_asio_query_fn::impl;
  166. friend struct boost::asio::execution::detail::blocking_t<0>;
  167. friend struct boost::asio::execution::detail::mapping_t<0>;
  168. friend struct boost::asio::execution::detail::inline_exception_handling_t<0>;
  169. friend struct boost::asio::execution::detail::outstanding_work_t<0>;
  170. friend struct boost::asio::execution::detail::relationship_t<0>;
  171. #endif // !defined(GENERATING_DOCUMENTATION)
  172. /// Query the current value of the @c mapping property.
  173. /**
  174. * Do not call this function directly. It is intended for use with the
  175. * boost::asio::query customisation point.
  176. *
  177. * For example:
  178. * @code boost::asio::system_executor ex;
  179. * if (boost::asio::query(ex, boost::asio::execution::mapping)
  180. * == boost::asio::execution::mapping.thread)
  181. * ... @endcode
  182. */
  183. static constexpr execution::mapping_t query(
  184. execution::mapping_t) noexcept
  185. {
  186. return execution::mapping.thread;
  187. }
  188. /// Query the current value of the @c inline_exception_handling property.
  189. /**
  190. * Do not call this function directly. It is intended for use with the
  191. * boost::asio::query customisation point.
  192. *
  193. * For example:
  194. * @code boost::asio::system_executor ex;
  195. * if (boost::asio::query(ex,
  196. * boost::asio::execution::inline_exception_handling)
  197. * == boost::asio::execution::inline_exception_handling.thread)
  198. * ... @endcode
  199. */
  200. static constexpr execution::inline_exception_handling_t query(
  201. execution::inline_exception_handling_t) noexcept
  202. {
  203. return execution::inline_exception_handling.terminate;
  204. }
  205. /// Query the current value of the @c context property.
  206. /**
  207. * Do not call this function directly. It is intended for use with the
  208. * boost::asio::query customisation point.
  209. *
  210. * For example:
  211. * @code boost::asio::system_executor ex;
  212. * boost::asio::system_context& pool = boost::asio::query(
  213. * ex, boost::asio::execution::context); @endcode
  214. */
  215. static system_context& query(execution::context_t) noexcept;
  216. /// Query the current value of the @c blocking property.
  217. /**
  218. * Do not call this function directly. It is intended for use with the
  219. * boost::asio::query customisation point.
  220. *
  221. * For example:
  222. * @code boost::asio::system_executor ex;
  223. * if (boost::asio::query(ex, boost::asio::execution::blocking)
  224. * == boost::asio::execution::blocking.always)
  225. * ... @endcode
  226. */
  227. static constexpr execution::blocking_t query(
  228. execution::blocking_t) noexcept
  229. {
  230. return Blocking();
  231. }
  232. /// Query the current value of the @c relationship property.
  233. /**
  234. * Do not call this function directly. It is intended for use with the
  235. * boost::asio::query customisation point.
  236. *
  237. * For example:
  238. * @code boost::asio::system_executor ex;
  239. * if (boost::asio::query(ex, boost::asio::execution::relationship)
  240. * == boost::asio::execution::relationship.continuation)
  241. * ... @endcode
  242. */
  243. static constexpr execution::relationship_t query(
  244. execution::relationship_t) noexcept
  245. {
  246. return Relationship();
  247. }
  248. /// Query the current value of the @c allocator property.
  249. /**
  250. * Do not call this function directly. It is intended for use with the
  251. * boost::asio::query customisation point.
  252. *
  253. * For example:
  254. * @code boost::asio::system_executor ex;
  255. * auto alloc = boost::asio::query(ex,
  256. * boost::asio::execution::allocator); @endcode
  257. */
  258. template <typename OtherAllocator>
  259. constexpr Allocator query(
  260. execution::allocator_t<OtherAllocator>) const noexcept
  261. {
  262. return allocator_;
  263. }
  264. /// Query the current value of the @c allocator property.
  265. /**
  266. * Do not call this function directly. It is intended for use with the
  267. * boost::asio::query customisation point.
  268. *
  269. * For example:
  270. * @code boost::asio::system_executor ex;
  271. * auto alloc = boost::asio::query(ex,
  272. * boost::asio::execution::allocator); @endcode
  273. */
  274. constexpr Allocator query(
  275. execution::allocator_t<void>) const noexcept
  276. {
  277. return allocator_;
  278. }
  279. /// Query the occupancy (recommended number of work items) for the system
  280. /// context.
  281. /**
  282. * Do not call this function directly. It is intended for use with the
  283. * boost::asio::query customisation point.
  284. *
  285. * For example:
  286. * @code boost::asio::system_executor ex;
  287. * std::size_t occupancy = boost::asio::query(
  288. * ex, boost::asio::execution::occupancy); @endcode
  289. */
  290. std::size_t query(execution::occupancy_t) const noexcept;
  291. public:
  292. /// Compare two executors for equality.
  293. /**
  294. * Two executors are equal if they refer to the same underlying io_context.
  295. */
  296. friend bool operator==(const basic_system_executor&,
  297. const basic_system_executor&) noexcept
  298. {
  299. return true;
  300. }
  301. /// Compare two executors for inequality.
  302. /**
  303. * Two executors are equal if they refer to the same underlying io_context.
  304. */
  305. friend bool operator!=(const basic_system_executor&,
  306. const basic_system_executor&) noexcept
  307. {
  308. return false;
  309. }
  310. /// Execution function.
  311. template <typename Function>
  312. void execute(Function&& f) const
  313. {
  314. this->do_execute(static_cast<Function&&>(f), Blocking());
  315. }
  316. #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
  317. public:
  318. /// Obtain the underlying execution context.
  319. system_context& context() const noexcept;
  320. /// Inform the executor that it has some outstanding work to do.
  321. /**
  322. * For the system executor, this is a no-op.
  323. */
  324. void on_work_started() const noexcept
  325. {
  326. }
  327. /// Inform the executor that some work is no longer outstanding.
  328. /**
  329. * For the system executor, this is a no-op.
  330. */
  331. void on_work_finished() const noexcept
  332. {
  333. }
  334. /// Request the system executor to invoke the given function object.
  335. /**
  336. * This function is used to ask the executor to execute the given function
  337. * object. The function object will always be executed inside this function.
  338. *
  339. * @param f The function object to be called. The executor will make
  340. * a copy of the handler object as required. The function signature of the
  341. * function object must be: @code void function(); @endcode
  342. *
  343. * @param a An allocator that may be used by the executor to allocate the
  344. * internal storage needed for function invocation.
  345. */
  346. template <typename Function, typename OtherAllocator>
  347. void dispatch(Function&& f, const OtherAllocator& a) const;
  348. /// Request the system executor to invoke the given function object.
  349. /**
  350. * This function is used to ask the executor to execute the given function
  351. * object. The function object will never be executed inside this function.
  352. * Instead, it will be scheduled to run on an unspecified system thread pool.
  353. *
  354. * @param f The function object to be called. The executor will make
  355. * a copy of the handler object as required. The function signature of the
  356. * function object must be: @code void function(); @endcode
  357. *
  358. * @param a An allocator that may be used by the executor to allocate the
  359. * internal storage needed for function invocation.
  360. */
  361. template <typename Function, typename OtherAllocator>
  362. void post(Function&& f, const OtherAllocator& a) const;
  363. /// Request the system executor to invoke the given function object.
  364. /**
  365. * This function is used to ask the executor to execute the given function
  366. * object. The function object will never be executed inside this function.
  367. * Instead, it will be scheduled to run on an unspecified system thread pool.
  368. *
  369. * @param f The function object to be called. The executor will make
  370. * a copy of the handler object as required. The function signature of the
  371. * function object must be: @code void function(); @endcode
  372. *
  373. * @param a An allocator that may be used by the executor to allocate the
  374. * internal storage needed for function invocation.
  375. */
  376. template <typename Function, typename OtherAllocator>
  377. void defer(Function&& f, const OtherAllocator& a) const;
  378. #endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
  379. private:
  380. template <typename, typename, typename> friend class basic_system_executor;
  381. // Constructor used by require().
  382. basic_system_executor(const Allocator& a)
  383. : allocator_(a)
  384. {
  385. }
  386. /// Execution helper implementation for the possibly blocking property.
  387. template <typename Function>
  388. void do_execute(Function&& f,
  389. execution::blocking_t::possibly_t) const;
  390. /// Execution helper implementation for the always blocking property.
  391. template <typename Function>
  392. void do_execute(Function&& f,
  393. execution::blocking_t::always_t) const;
  394. /// Execution helper implementation for the never blocking property.
  395. template <typename Function>
  396. void do_execute(Function&& f,
  397. execution::blocking_t::never_t) const;
  398. // The allocator used for execution functions.
  399. Allocator allocator_;
  400. };
  401. /// An executor that uses arbitrary threads.
  402. /**
  403. * The system executor represents an execution context where functions are
  404. * permitted to run on arbitrary threads. When the blocking.never property is
  405. * established, the system executor will schedule the function to run on an
  406. * unspecified system thread pool. When either blocking.possibly or
  407. * blocking.always is established, the executor invokes the function
  408. * immediately.
  409. */
  410. typedef basic_system_executor<execution::blocking_t::possibly_t,
  411. execution::relationship_t::fork_t, std::allocator<void>>
  412. system_executor;
  413. #if !defined(GENERATING_DOCUMENTATION)
  414. namespace traits {
  415. #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
  416. template <typename Blocking, typename Relationship, typename Allocator>
  417. struct equality_comparable<
  418. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>
  419. >
  420. {
  421. static constexpr bool is_valid = true;
  422. static constexpr bool is_noexcept = true;
  423. };
  424. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
  425. #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
  426. template <typename Blocking, typename Relationship,
  427. typename Allocator, typename Function>
  428. struct execute_member<
  429. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  430. Function
  431. >
  432. {
  433. static constexpr bool is_valid = true;
  434. static constexpr bool is_noexcept = false;
  435. typedef void result_type;
  436. };
  437. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
  438. #if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
  439. template <typename Blocking, typename Relationship, typename Allocator>
  440. struct require_member<
  441. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  442. boost::asio::execution::blocking_t::possibly_t
  443. >
  444. {
  445. static constexpr bool is_valid = true;
  446. static constexpr bool is_noexcept = false;
  447. typedef boost::asio::basic_system_executor<
  448. boost::asio::execution::blocking_t::possibly_t,
  449. Relationship, Allocator> result_type;
  450. };
  451. template <typename Blocking, typename Relationship, typename Allocator>
  452. struct require_member<
  453. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  454. boost::asio::execution::blocking_t::always_t
  455. >
  456. {
  457. static constexpr bool is_valid = true;
  458. static constexpr bool is_noexcept = false;
  459. typedef boost::asio::basic_system_executor<
  460. boost::asio::execution::blocking_t::always_t,
  461. Relationship, Allocator> result_type;
  462. };
  463. template <typename Blocking, typename Relationship, typename Allocator>
  464. struct require_member<
  465. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  466. boost::asio::execution::blocking_t::never_t
  467. >
  468. {
  469. static constexpr bool is_valid = true;
  470. static constexpr bool is_noexcept = false;
  471. typedef boost::asio::basic_system_executor<
  472. boost::asio::execution::blocking_t::never_t,
  473. Relationship, Allocator> result_type;
  474. };
  475. template <typename Blocking, typename Relationship, typename Allocator>
  476. struct require_member<
  477. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  478. boost::asio::execution::relationship_t::fork_t
  479. >
  480. {
  481. static constexpr bool is_valid = true;
  482. static constexpr bool is_noexcept = false;
  483. typedef boost::asio::basic_system_executor<Blocking,
  484. boost::asio::execution::relationship_t::fork_t,
  485. Allocator> result_type;
  486. };
  487. template <typename Blocking, typename Relationship, typename Allocator>
  488. struct require_member<
  489. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  490. boost::asio::execution::relationship_t::continuation_t
  491. >
  492. {
  493. static constexpr bool is_valid = true;
  494. static constexpr bool is_noexcept = false;
  495. typedef boost::asio::basic_system_executor<Blocking,
  496. boost::asio::execution::relationship_t::continuation_t,
  497. Allocator> result_type;
  498. };
  499. template <typename Blocking, typename Relationship, typename Allocator>
  500. struct require_member<
  501. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  502. boost::asio::execution::allocator_t<void>
  503. >
  504. {
  505. static constexpr bool is_valid = true;
  506. static constexpr bool is_noexcept = false;
  507. typedef boost::asio::basic_system_executor<Blocking,
  508. Relationship, std::allocator<void>> result_type;
  509. };
  510. template <typename Blocking, typename Relationship,
  511. typename Allocator, typename OtherAllocator>
  512. struct require_member<
  513. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  514. boost::asio::execution::allocator_t<OtherAllocator>
  515. >
  516. {
  517. static constexpr bool is_valid = true;
  518. static constexpr bool is_noexcept = false;
  519. typedef boost::asio::basic_system_executor<Blocking,
  520. Relationship, OtherAllocator> result_type;
  521. };
  522. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
  523. #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  524. template <typename Blocking, typename Relationship,
  525. typename Allocator, typename Property>
  526. struct query_static_constexpr_member<
  527. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  528. Property,
  529. typename boost::asio::enable_if<
  530. boost::asio::is_convertible<
  531. Property,
  532. boost::asio::execution::mapping_t
  533. >::value
  534. >::type
  535. >
  536. {
  537. static constexpr bool is_valid = true;
  538. static constexpr bool is_noexcept = true;
  539. typedef boost::asio::execution::mapping_t::thread_t result_type;
  540. static constexpr result_type value() noexcept
  541. {
  542. return result_type();
  543. }
  544. };
  545. template <typename Blocking, typename Relationship,
  546. typename Allocator, typename Property>
  547. struct query_static_constexpr_member<
  548. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  549. Property,
  550. typename boost::asio::enable_if<
  551. boost::asio::is_convertible<
  552. Property,
  553. boost::asio::execution::inline_exception_handling_t
  554. >::value
  555. >::type
  556. >
  557. {
  558. static constexpr bool is_valid = true;
  559. static constexpr bool is_noexcept = true;
  560. typedef boost::asio::execution::inline_exception_handling_t::terminate_t
  561. result_type;
  562. static constexpr result_type value() noexcept
  563. {
  564. return result_type();
  565. }
  566. };
  567. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  568. #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
  569. template <typename Blocking, typename Relationship,
  570. typename Allocator, typename Property>
  571. struct query_member<
  572. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  573. Property,
  574. typename boost::asio::enable_if<
  575. boost::asio::is_convertible<
  576. Property,
  577. boost::asio::execution::blocking_t
  578. >::value
  579. >::type
  580. >
  581. {
  582. static constexpr bool is_valid = true;
  583. static constexpr bool is_noexcept = true;
  584. typedef boost::asio::execution::blocking_t result_type;
  585. };
  586. template <typename Blocking, typename Relationship,
  587. typename Allocator, typename Property>
  588. struct query_member<
  589. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  590. Property,
  591. typename boost::asio::enable_if<
  592. boost::asio::is_convertible<
  593. Property,
  594. boost::asio::execution::relationship_t
  595. >::value
  596. >::type
  597. >
  598. {
  599. static constexpr bool is_valid = true;
  600. static constexpr bool is_noexcept = true;
  601. typedef boost::asio::execution::relationship_t result_type;
  602. };
  603. template <typename Blocking, typename Relationship, typename Allocator>
  604. struct query_member<
  605. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  606. boost::asio::execution::context_t
  607. >
  608. {
  609. static constexpr bool is_valid = true;
  610. static constexpr bool is_noexcept = true;
  611. typedef boost::asio::system_context& result_type;
  612. };
  613. template <typename Blocking, typename Relationship, typename Allocator>
  614. struct query_member<
  615. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  616. boost::asio::execution::allocator_t<void>
  617. >
  618. {
  619. static constexpr bool is_valid = true;
  620. static constexpr bool is_noexcept = true;
  621. typedef Allocator result_type;
  622. };
  623. template <typename Blocking, typename Relationship, typename Allocator>
  624. struct query_member<
  625. boost::asio::basic_system_executor<Blocking, Relationship, Allocator>,
  626. boost::asio::execution::allocator_t<Allocator>
  627. >
  628. {
  629. static constexpr bool is_valid = true;
  630. static constexpr bool is_noexcept = true;
  631. typedef Allocator result_type;
  632. };
  633. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
  634. } // namespace traits
  635. #endif // !defined(GENERATING_DOCUMENTATION)
  636. } // namespace asio
  637. } // namespace boost
  638. #include <boost/asio/detail/pop_options.hpp>
  639. #include <boost/asio/impl/system_executor.hpp>
  640. #endif // BOOST_ASIO_SYSTEM_EXECUTOR_HPP