any_io_executor.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. //
  2. // any_io_executor.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 ASIO_ANY_IO_EXECUTOR_HPP
  11. #define ASIO_ANY_IO_EXECUTOR_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #if defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
  17. # include "asio/executor.hpp"
  18. #else // defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
  19. # include "asio/execution.hpp"
  20. # include "asio/execution_context.hpp"
  21. #endif // defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
  22. #include "asio/detail/push_options.hpp"
  23. namespace asio {
  24. #if defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
  25. typedef executor any_io_executor;
  26. #else // defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
  27. /// Polymorphic executor type for use with I/O objects.
  28. /**
  29. * The @c any_io_executor type is a polymorphic executor that supports the set
  30. * of properties required by I/O objects. It is defined as the
  31. * execution::any_executor class template parameterised as follows:
  32. * @code execution::any_executor<
  33. * execution::context_as_t<execution_context&>,
  34. * execution::blocking_t::never_t,
  35. * execution::prefer_only<execution::blocking_t::possibly_t>,
  36. * execution::prefer_only<execution::outstanding_work_t::tracked_t>,
  37. * execution::prefer_only<execution::outstanding_work_t::untracked_t>,
  38. * execution::prefer_only<execution::relationship_t::fork_t>,
  39. * execution::prefer_only<execution::relationship_t::continuation_t>
  40. * > @endcode
  41. */
  42. class any_io_executor :
  43. #if defined(GENERATING_DOCUMENTATION)
  44. public execution::any_executor<...>
  45. #else // defined(GENERATING_DOCUMENTATION)
  46. public execution::any_executor<
  47. execution::context_as_t<execution_context&>,
  48. execution::blocking_t::never_t,
  49. execution::prefer_only<execution::blocking_t::possibly_t>,
  50. execution::prefer_only<execution::outstanding_work_t::tracked_t>,
  51. execution::prefer_only<execution::outstanding_work_t::untracked_t>,
  52. execution::prefer_only<execution::relationship_t::fork_t>,
  53. execution::prefer_only<execution::relationship_t::continuation_t>
  54. >
  55. #endif // defined(GENERATING_DOCUMENTATION)
  56. {
  57. public:
  58. #if !defined(GENERATING_DOCUMENTATION)
  59. typedef execution::any_executor<
  60. execution::context_as_t<execution_context&>,
  61. execution::blocking_t::never_t,
  62. execution::prefer_only<execution::blocking_t::possibly_t>,
  63. execution::prefer_only<execution::outstanding_work_t::tracked_t>,
  64. execution::prefer_only<execution::outstanding_work_t::untracked_t>,
  65. execution::prefer_only<execution::relationship_t::fork_t>,
  66. execution::prefer_only<execution::relationship_t::continuation_t>
  67. > base_type;
  68. typedef void supportable_properties_type(
  69. execution::context_as_t<execution_context&>,
  70. execution::blocking_t::never_t,
  71. execution::prefer_only<execution::blocking_t::possibly_t>,
  72. execution::prefer_only<execution::outstanding_work_t::tracked_t>,
  73. execution::prefer_only<execution::outstanding_work_t::untracked_t>,
  74. execution::prefer_only<execution::relationship_t::fork_t>,
  75. execution::prefer_only<execution::relationship_t::continuation_t>
  76. );
  77. #endif // !defined(GENERATING_DOCUMENTATION)
  78. /// Default constructor.
  79. ASIO_DECL any_io_executor() noexcept;
  80. /// Construct in an empty state. Equivalent effects to default constructor.
  81. ASIO_DECL any_io_executor(nullptr_t) noexcept;
  82. /// Copy constructor.
  83. ASIO_DECL any_io_executor(const any_io_executor& e) noexcept;
  84. /// Move constructor.
  85. ASIO_DECL any_io_executor(any_io_executor&& e) noexcept;
  86. /// Construct to point to the same target as another any_executor.
  87. #if defined(GENERATING_DOCUMENTATION)
  88. template <class... OtherSupportableProperties>
  89. any_io_executor(execution::any_executor<OtherSupportableProperties...> e);
  90. #else // defined(GENERATING_DOCUMENTATION)
  91. template <typename OtherAnyExecutor>
  92. any_io_executor(OtherAnyExecutor e,
  93. constraint_t<
  94. conditional_t<
  95. !is_same<OtherAnyExecutor, any_io_executor>::value
  96. && is_base_of<execution::detail::any_executor_base,
  97. OtherAnyExecutor>::value,
  98. typename execution::detail::supportable_properties<
  99. 0, supportable_properties_type>::template
  100. is_valid_target<OtherAnyExecutor>,
  101. false_type
  102. >::value
  103. > = 0)
  104. : base_type(static_cast<OtherAnyExecutor&&>(e))
  105. {
  106. }
  107. #endif // defined(GENERATING_DOCUMENTATION)
  108. /// Construct to point to the same target as another any_executor.
  109. #if defined(GENERATING_DOCUMENTATION)
  110. template <class... OtherSupportableProperties>
  111. any_io_executor(std::nothrow_t,
  112. execution::any_executor<OtherSupportableProperties...> e);
  113. #else // defined(GENERATING_DOCUMENTATION)
  114. template <typename OtherAnyExecutor>
  115. any_io_executor(std::nothrow_t, OtherAnyExecutor e,
  116. constraint_t<
  117. conditional_t<
  118. !is_same<OtherAnyExecutor, any_io_executor>::value
  119. && is_base_of<execution::detail::any_executor_base,
  120. OtherAnyExecutor>::value,
  121. typename execution::detail::supportable_properties<
  122. 0, supportable_properties_type>::template
  123. is_valid_target<OtherAnyExecutor>,
  124. false_type
  125. >::value
  126. > = 0) noexcept
  127. : base_type(std::nothrow, static_cast<OtherAnyExecutor&&>(e))
  128. {
  129. }
  130. #endif // defined(GENERATING_DOCUMENTATION)
  131. /// Construct to point to the same target as another any_executor.
  132. ASIO_DECL any_io_executor(std::nothrow_t,
  133. const any_io_executor& e) noexcept;
  134. /// Construct to point to the same target as another any_executor.
  135. ASIO_DECL any_io_executor(std::nothrow_t, any_io_executor&& e) noexcept;
  136. /// Construct a polymorphic wrapper for the specified executor.
  137. #if defined(GENERATING_DOCUMENTATION)
  138. template <ASIO_EXECUTION_EXECUTOR Executor>
  139. any_io_executor(Executor e);
  140. #else // defined(GENERATING_DOCUMENTATION)
  141. template <ASIO_EXECUTION_EXECUTOR Executor>
  142. any_io_executor(Executor e,
  143. constraint_t<
  144. conditional_t<
  145. !is_same<Executor, any_io_executor>::value
  146. && !is_base_of<execution::detail::any_executor_base,
  147. Executor>::value,
  148. execution::detail::is_valid_target_executor<
  149. Executor, supportable_properties_type>,
  150. false_type
  151. >::value
  152. > = 0)
  153. : base_type(static_cast<Executor&&>(e))
  154. {
  155. }
  156. #endif // defined(GENERATING_DOCUMENTATION)
  157. /// Construct a polymorphic wrapper for the specified executor.
  158. #if defined(GENERATING_DOCUMENTATION)
  159. template <ASIO_EXECUTION_EXECUTOR Executor>
  160. any_io_executor(std::nothrow_t, Executor e);
  161. #else // defined(GENERATING_DOCUMENTATION)
  162. template <ASIO_EXECUTION_EXECUTOR Executor>
  163. any_io_executor(std::nothrow_t, Executor e,
  164. constraint_t<
  165. conditional_t<
  166. !is_same<Executor, any_io_executor>::value
  167. && !is_base_of<execution::detail::any_executor_base,
  168. Executor>::value,
  169. execution::detail::is_valid_target_executor<
  170. Executor, supportable_properties_type>,
  171. false_type
  172. >::value
  173. > = 0) noexcept
  174. : base_type(std::nothrow, static_cast<Executor&&>(e))
  175. {
  176. }
  177. #endif // defined(GENERATING_DOCUMENTATION)
  178. /// Assignment operator.
  179. ASIO_DECL any_io_executor& operator=(
  180. const any_io_executor& e) noexcept;
  181. /// Move assignment operator.
  182. ASIO_DECL any_io_executor& operator=(any_io_executor&& e) noexcept;
  183. /// Assignment operator that sets the polymorphic wrapper to the empty state.
  184. ASIO_DECL any_io_executor& operator=(nullptr_t);
  185. /// Destructor.
  186. ASIO_DECL ~any_io_executor();
  187. /// Swap targets with another polymorphic wrapper.
  188. ASIO_DECL void swap(any_io_executor& other) noexcept;
  189. /// Obtain a polymorphic wrapper with the specified property.
  190. /**
  191. * Do not call this function directly. It is intended for use with the
  192. * asio::require and asio::prefer customisation points.
  193. *
  194. * For example:
  195. * @code any_io_executor ex = ...;
  196. * auto ex2 = asio::require(ex, execution::blocking.possibly); @endcode
  197. */
  198. template <typename Property>
  199. any_io_executor require(const Property& p,
  200. constraint_t<
  201. traits::require_member<const base_type&, const Property&>::is_valid
  202. > = 0) const
  203. {
  204. return static_cast<const base_type&>(*this).require(p);
  205. }
  206. /// Obtain a polymorphic wrapper with the specified property.
  207. /**
  208. * Do not call this function directly. It is intended for use with the
  209. * asio::prefer customisation point.
  210. *
  211. * For example:
  212. * @code any_io_executor ex = ...;
  213. * auto ex2 = asio::prefer(ex, execution::blocking.possibly); @endcode
  214. */
  215. template <typename Property>
  216. any_io_executor prefer(const Property& p,
  217. constraint_t<
  218. traits::prefer_member<const base_type&, const Property&>::is_valid
  219. > = 0) const
  220. {
  221. return static_cast<const base_type&>(*this).prefer(p);
  222. }
  223. };
  224. #if !defined(GENERATING_DOCUMENTATION)
  225. template <>
  226. ASIO_DECL any_io_executor any_io_executor::require(
  227. const execution::blocking_t::never_t&, int) const;
  228. template <>
  229. ASIO_DECL any_io_executor any_io_executor::prefer(
  230. const execution::blocking_t::possibly_t&, int) const;
  231. template <>
  232. ASIO_DECL any_io_executor any_io_executor::prefer(
  233. const execution::outstanding_work_t::tracked_t&, int) const;
  234. template <>
  235. ASIO_DECL any_io_executor any_io_executor::prefer(
  236. const execution::outstanding_work_t::untracked_t&, int) const;
  237. template <>
  238. ASIO_DECL any_io_executor any_io_executor::prefer(
  239. const execution::relationship_t::fork_t&, int) const;
  240. template <>
  241. ASIO_DECL any_io_executor any_io_executor::prefer(
  242. const execution::relationship_t::continuation_t&, int) const;
  243. namespace traits {
  244. #if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
  245. template <>
  246. struct equality_comparable<any_io_executor>
  247. {
  248. static const bool is_valid = true;
  249. static const bool is_noexcept = true;
  250. };
  251. #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
  252. #if !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
  253. template <typename F>
  254. struct execute_member<any_io_executor, F>
  255. {
  256. static const bool is_valid = true;
  257. static const bool is_noexcept = false;
  258. typedef void result_type;
  259. };
  260. #endif // !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
  261. #if !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
  262. template <typename Prop>
  263. struct query_member<any_io_executor, Prop> :
  264. query_member<any_io_executor::base_type, Prop>
  265. {
  266. };
  267. #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
  268. #if !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
  269. template <typename Prop>
  270. struct require_member<any_io_executor, Prop> :
  271. require_member<any_io_executor::base_type, Prop>
  272. {
  273. typedef any_io_executor result_type;
  274. };
  275. #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
  276. #if !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
  277. template <typename Prop>
  278. struct prefer_member<any_io_executor, Prop> :
  279. prefer_member<any_io_executor::base_type, Prop>
  280. {
  281. typedef any_io_executor result_type;
  282. };
  283. #endif // !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
  284. } // namespace traits
  285. #endif // !defined(GENERATING_DOCUMENTATION)
  286. #endif // defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
  287. } // namespace asio
  288. #include "asio/detail/pop_options.hpp"
  289. #if defined(ASIO_HEADER_ONLY) \
  290. && !defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
  291. # include "asio/impl/any_io_executor.ipp"
  292. #endif // defined(ASIO_HEADER_ONLY)
  293. // && !defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
  294. #endif // ASIO_ANY_IO_EXECUTOR_HPP