inline_executor.hpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. //
  2. // inline_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_INLINE_EXECUTOR_HPP
  11. #define BOOST_ASIO_INLINE_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/non_const_lvalue.hpp>
  17. #include <boost/asio/detail/type_traits.hpp>
  18. #include <boost/asio/execution.hpp>
  19. #include <boost/asio/detail/push_options.hpp>
  20. namespace boost {
  21. namespace asio {
  22. /// An executor that always executes the function object inline.
  23. template <typename InlineExceptionHandling>
  24. class basic_inline_executor
  25. {
  26. public:
  27. /// Default constructor.
  28. basic_inline_executor() noexcept
  29. {
  30. }
  31. #if !defined(GENERATING_DOCUMENTATION)
  32. private:
  33. friend struct boost_asio_require_fn::impl;
  34. friend struct boost_asio_prefer_fn::impl;
  35. #endif // !defined(GENERATING_DOCUMENTATION)
  36. /// Obtain an executor with the @c inline_exception_handling.propagate
  37. /// property.
  38. /**
  39. * Do not call this function directly. It is intended for use with the
  40. * boost::asio::require customisation point.
  41. *
  42. * For example:
  43. * @code boost::asio::inline_executor ex1;
  44. * auto ex2 = boost::asio::require(ex1,
  45. * boost::asio::execution::inline_exception_handling.propagate); @endcode
  46. */
  47. basic_inline_executor<execution::inline_exception_handling_t::propagate_t>
  48. require(execution::inline_exception_handling_t::propagate_t) const noexcept
  49. {
  50. return basic_inline_executor<
  51. execution::inline_exception_handling_t::propagate_t>();
  52. }
  53. /// Obtain an executor with the @c inline_exception_handling.terminate
  54. /// property.
  55. /**
  56. * Do not call this function directly. It is intended for use with the
  57. * boost::asio::require customisation point.
  58. *
  59. * For example:
  60. * @code boost::asio::inline_executor ex1;
  61. * auto ex2 = boost::asio::require(ex1,
  62. * boost::asio::execution::inline_exception_handling.terminate); @endcode
  63. */
  64. basic_inline_executor<execution::inline_exception_handling_t::terminate_t>
  65. require(execution::inline_exception_handling_t::terminate_t) const noexcept
  66. {
  67. return basic_inline_executor<
  68. execution::inline_exception_handling_t::terminate_t>();
  69. }
  70. #if !defined(GENERATING_DOCUMENTATION)
  71. private:
  72. friend struct boost_asio_query_fn::impl;
  73. friend struct boost::asio::execution::detail::blocking_t<0>;
  74. friend struct boost::asio::execution::detail::mapping_t<0>;
  75. friend struct boost::asio::execution::detail::inline_exception_handling_t<0>;
  76. #endif // !defined(GENERATING_DOCUMENTATION)
  77. /// Query the current value of the @c mapping property.
  78. /**
  79. * Do not call this function directly. It is intended for use with the
  80. * boost::asio::query customisation point.
  81. *
  82. * For example:
  83. * @code boost::asio::inline_executor ex;
  84. * if (boost::asio::query(ex, boost::asio::execution::mapping)
  85. * == boost::asio::execution::mapping.thread)
  86. * ... @endcode
  87. */
  88. static constexpr execution::mapping_t query(
  89. execution::mapping_t) noexcept
  90. {
  91. return execution::mapping.thread;
  92. }
  93. /// Query the current value of the @c inline_exception_handling property.
  94. /**
  95. * Do not call this function directly. It is intended for use with the
  96. * boost::asio::query customisation point.
  97. *
  98. * For example:
  99. * @code boost::asio::inline_executor ex;
  100. * if (boost::asio::query(ex,
  101. * boost::asio::execution::inline_exception_handling)
  102. * == boost::asio::execution::inline_exception_handling.propagate)
  103. * ... @endcode
  104. */
  105. static constexpr execution::inline_exception_handling_t query(
  106. execution::inline_exception_handling_t) noexcept
  107. {
  108. return InlineExceptionHandling();
  109. }
  110. /// Query the current value of the @c blocking property.
  111. /**
  112. * Do not call this function directly. It is intended for use with the
  113. * boost::asio::query customisation point.
  114. *
  115. * For example:
  116. * @code boost::asio::inline_executor ex;
  117. * if (boost::asio::query(ex, boost::asio::execution::blocking)
  118. * == boost::asio::execution::blocking.always)
  119. * ... @endcode
  120. */
  121. static constexpr execution::blocking_t query(
  122. execution::blocking_t) noexcept
  123. {
  124. return execution::blocking.always;
  125. }
  126. public:
  127. /// Compare two executors for equality.
  128. /**
  129. * Two inline executors are always considered equal.
  130. */
  131. friend bool operator==(const basic_inline_executor&,
  132. const basic_inline_executor&) noexcept
  133. {
  134. return true;
  135. }
  136. /// Compare two executors for inequality.
  137. /**
  138. * Two inline executors are never considered unequal.
  139. */
  140. friend bool operator!=(const basic_inline_executor&,
  141. const basic_inline_executor&) noexcept
  142. {
  143. return false;
  144. }
  145. /// Execution function.
  146. template <typename Function>
  147. void execute(Function&& f) const
  148. {
  149. #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
  150. try
  151. #endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
  152. {
  153. detail::non_const_lvalue<Function> f2(f);
  154. static_cast<decay_t<Function>&&>(f2.value)();
  155. }
  156. #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
  157. catch (...)
  158. {
  159. if (is_same<InlineExceptionHandling,
  160. execution::inline_exception_handling_t::terminate_t>::value)
  161. {
  162. std::terminate();
  163. }
  164. else
  165. {
  166. throw;
  167. }
  168. }
  169. #endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
  170. }
  171. };
  172. /// An executor that always executes the function object inline.
  173. typedef basic_inline_executor<
  174. execution::inline_exception_handling_t::propagate_t>
  175. inline_executor;
  176. #if !defined(GENERATING_DOCUMENTATION)
  177. namespace traits {
  178. #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
  179. template <typename InlineExceptionHandling>
  180. struct equality_comparable<
  181. basic_inline_executor<InlineExceptionHandling>
  182. >
  183. {
  184. static constexpr bool is_valid = true;
  185. static constexpr bool is_noexcept = true;
  186. };
  187. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
  188. #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
  189. template <typename InlineExceptionHandling, typename Function>
  190. struct execute_member<
  191. basic_inline_executor<InlineExceptionHandling>,
  192. Function
  193. >
  194. {
  195. static constexpr bool is_valid = true;
  196. static constexpr bool is_noexcept = false;
  197. typedef void result_type;
  198. };
  199. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
  200. #if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
  201. template <typename InlineExceptionHandling>
  202. struct require_member<
  203. basic_inline_executor<InlineExceptionHandling>,
  204. execution::inline_exception_handling_t::propagate_t
  205. >
  206. {
  207. static constexpr bool is_valid = true;
  208. static constexpr bool is_noexcept = true;
  209. typedef basic_inline_executor<
  210. execution::inline_exception_handling_t::propagate_t>
  211. result_type;
  212. };
  213. template <typename InlineExceptionHandling>
  214. struct require_member<
  215. basic_inline_executor<InlineExceptionHandling>,
  216. execution::inline_exception_handling_t::terminate_t
  217. >
  218. {
  219. static constexpr bool is_valid = true;
  220. static constexpr bool is_noexcept = true;
  221. typedef basic_inline_executor<
  222. execution::inline_exception_handling_t::terminate_t>
  223. result_type;
  224. };
  225. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
  226. #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  227. template <typename InlineExceptionHandling, typename Property>
  228. struct query_static_constexpr_member<
  229. basic_inline_executor<InlineExceptionHandling>,
  230. Property,
  231. enable_if_t<
  232. is_convertible<
  233. Property,
  234. execution::mapping_t
  235. >::value
  236. >
  237. >
  238. {
  239. static constexpr bool is_valid = true;
  240. static constexpr bool is_noexcept = true;
  241. typedef execution::mapping_t::thread_t result_type;
  242. static constexpr result_type value() noexcept
  243. {
  244. return result_type();
  245. }
  246. };
  247. template <typename InlineExceptionHandling, typename Property>
  248. struct query_static_constexpr_member<
  249. basic_inline_executor<InlineExceptionHandling>,
  250. Property,
  251. enable_if_t<
  252. is_convertible<
  253. Property,
  254. execution::inline_exception_handling_t
  255. >::value
  256. >
  257. >
  258. {
  259. static constexpr bool is_valid = true;
  260. static constexpr bool is_noexcept = true;
  261. typedef InlineExceptionHandling result_type;
  262. static constexpr result_type value() noexcept
  263. {
  264. return result_type();
  265. }
  266. };
  267. template <typename InlineExceptionHandling, typename Property>
  268. struct query_static_constexpr_member<
  269. basic_inline_executor<InlineExceptionHandling>,
  270. Property,
  271. enable_if_t<
  272. is_convertible<
  273. Property,
  274. execution::blocking_t
  275. >::value
  276. >
  277. >
  278. {
  279. static constexpr bool is_valid = true;
  280. static constexpr bool is_noexcept = true;
  281. typedef execution::blocking_t::always_t result_type;
  282. static constexpr result_type value() noexcept
  283. {
  284. return result_type();
  285. }
  286. };
  287. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  288. } // namespace traits
  289. #endif // !defined(GENERATING_DOCUMENTATION)
  290. } // namespace asio
  291. } // namespace boost
  292. #include <boost/asio/detail/pop_options.hpp>
  293. #endif // BOOST_ASIO_INLINE_EXECUTOR_HPP