any_io_executor.hpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. //
  2. // any_io_executor.hpp
  3. // ~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2022 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() ASIO_NOEXCEPT;
  80. /// Construct in an empty state. Equivalent effects to default constructor.
  81. ASIO_DECL any_io_executor(nullptr_t) ASIO_NOEXCEPT;
  82. /// Copy constructor.
  83. ASIO_DECL any_io_executor(const any_io_executor& e) ASIO_NOEXCEPT;
  84. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  85. /// Move constructor.
  86. ASIO_DECL any_io_executor(any_io_executor&& e) ASIO_NOEXCEPT;
  87. #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  88. /// Construct to point to the same target as another any_executor.
  89. #if defined(GENERATING_DOCUMENTATION)
  90. template <class... OtherSupportableProperties>
  91. any_io_executor(execution::any_executor<OtherSupportableProperties...> e);
  92. #else // defined(GENERATING_DOCUMENTATION)
  93. template <typename OtherAnyExecutor>
  94. any_io_executor(OtherAnyExecutor e,
  95. typename constraint<
  96. conditional<
  97. !is_same<OtherAnyExecutor, any_io_executor>::value
  98. && is_base_of<execution::detail::any_executor_base,
  99. OtherAnyExecutor>::value,
  100. typename execution::detail::supportable_properties<
  101. 0, supportable_properties_type>::template
  102. is_valid_target<OtherAnyExecutor>,
  103. false_type
  104. >::type::value
  105. >::type = 0)
  106. : base_type(ASIO_MOVE_CAST(OtherAnyExecutor)(e))
  107. {
  108. }
  109. #endif // defined(GENERATING_DOCUMENTATION)
  110. /// Construct a polymorphic wrapper for the specified executor.
  111. #if defined(GENERATING_DOCUMENTATION)
  112. template <ASIO_EXECUTION_EXECUTOR Executor>
  113. any_io_executor(Executor e);
  114. #else // defined(GENERATING_DOCUMENTATION)
  115. template <ASIO_EXECUTION_EXECUTOR Executor>
  116. any_io_executor(Executor e,
  117. typename constraint<
  118. conditional<
  119. !is_same<Executor, any_io_executor>::value
  120. && !is_base_of<execution::detail::any_executor_base,
  121. Executor>::value,
  122. execution::detail::is_valid_target_executor<
  123. Executor, supportable_properties_type>,
  124. false_type
  125. >::type::value
  126. >::type = 0)
  127. : base_type(ASIO_MOVE_CAST(Executor)(e))
  128. {
  129. }
  130. #endif // defined(GENERATING_DOCUMENTATION)
  131. /// Assignment operator.
  132. ASIO_DECL any_io_executor& operator=(
  133. const any_io_executor& e) ASIO_NOEXCEPT;
  134. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  135. /// Move assignment operator.
  136. ASIO_DECL any_io_executor& operator=(
  137. any_io_executor&& e) ASIO_NOEXCEPT;
  138. #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  139. /// Assignment operator that sets the polymorphic wrapper to the empty state.
  140. ASIO_DECL any_io_executor& operator=(nullptr_t);
  141. /// Destructor.
  142. ASIO_DECL ~any_io_executor();
  143. /// Swap targets with another polymorphic wrapper.
  144. ASIO_DECL void swap(any_io_executor& other) ASIO_NOEXCEPT;
  145. /// Obtain a polymorphic wrapper with the specified property.
  146. /**
  147. * Do not call this function directly. It is intended for use with the
  148. * asio::require and asio::prefer customisation points.
  149. *
  150. * For example:
  151. * @code any_io_executor ex = ...;
  152. * auto ex2 = asio::require(ex, execution::blocking.possibly); @endcode
  153. */
  154. template <typename Property>
  155. any_io_executor require(const Property& p,
  156. typename constraint<
  157. traits::require_member<const base_type&, const Property&>::is_valid
  158. >::type = 0) const
  159. {
  160. return static_cast<const base_type&>(*this).require(p);
  161. }
  162. /// Obtain a polymorphic wrapper with the specified property.
  163. /**
  164. * Do not call this function directly. It is intended for use with the
  165. * asio::prefer customisation point.
  166. *
  167. * For example:
  168. * @code any_io_executor ex = ...;
  169. * auto ex2 = asio::prefer(ex, execution::blocking.possibly); @endcode
  170. */
  171. template <typename Property>
  172. any_io_executor prefer(const Property& p,
  173. typename constraint<
  174. traits::prefer_member<const base_type&, const Property&>::is_valid
  175. >::type = 0) const
  176. {
  177. return static_cast<const base_type&>(*this).prefer(p);
  178. }
  179. };
  180. #if !defined(GENERATING_DOCUMENTATION)
  181. template <>
  182. ASIO_DECL any_io_executor any_io_executor::require(
  183. const execution::blocking_t::never_t&, int) const;
  184. template <>
  185. ASIO_DECL any_io_executor any_io_executor::prefer(
  186. const execution::blocking_t::possibly_t&, int) const;
  187. template <>
  188. ASIO_DECL any_io_executor any_io_executor::prefer(
  189. const execution::outstanding_work_t::tracked_t&, int) const;
  190. template <>
  191. ASIO_DECL any_io_executor any_io_executor::prefer(
  192. const execution::outstanding_work_t::untracked_t&, int) const;
  193. template <>
  194. ASIO_DECL any_io_executor any_io_executor::prefer(
  195. const execution::relationship_t::fork_t&, int) const;
  196. template <>
  197. ASIO_DECL any_io_executor any_io_executor::prefer(
  198. const execution::relationship_t::continuation_t&, int) const;
  199. namespace traits {
  200. #if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
  201. template <>
  202. struct equality_comparable<any_io_executor>
  203. {
  204. static const bool is_valid = true;
  205. static const bool is_noexcept = true;
  206. };
  207. #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
  208. #if !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
  209. template <typename F>
  210. struct execute_member<any_io_executor, F>
  211. {
  212. static const bool is_valid = true;
  213. static const bool is_noexcept = false;
  214. typedef void result_type;
  215. };
  216. #endif // !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
  217. #if !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
  218. template <typename Prop>
  219. struct query_member<any_io_executor, Prop> :
  220. query_member<any_io_executor::base_type, Prop>
  221. {
  222. };
  223. #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
  224. #if !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
  225. template <typename Prop>
  226. struct require_member<any_io_executor, Prop> :
  227. require_member<any_io_executor::base_type, Prop>
  228. {
  229. typedef any_io_executor result_type;
  230. };
  231. #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
  232. #if !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
  233. template <typename Prop>
  234. struct prefer_member<any_io_executor, Prop> :
  235. prefer_member<any_io_executor::base_type, Prop>
  236. {
  237. typedef any_io_executor result_type;
  238. };
  239. #endif // !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
  240. } // namespace traits
  241. #endif // !defined(GENERATING_DOCUMENTATION)
  242. #endif // defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
  243. } // namespace asio
  244. #include "asio/detail/pop_options.hpp"
  245. #if defined(ASIO_HEADER_ONLY) \
  246. && !defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
  247. # include "asio/impl/any_io_executor.ipp"
  248. #endif // defined(ASIO_HEADER_ONLY)
  249. // && !defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
  250. #endif // ASIO_ANY_IO_EXECUTOR_HPP