sender.hpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. //
  2. // execution/sender.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 BOOST_ASIO_EXECUTION_SENDER_HPP
  11. #define BOOST_ASIO_EXECUTION_SENDER_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. #if !defined(BOOST_ASIO_NO_DEPRECATED)
  17. #include <boost/asio/detail/type_traits.hpp>
  18. #include <boost/asio/execution/detail/as_invocable.hpp>
  19. #include <boost/asio/execution/detail/void_receiver.hpp>
  20. #include <boost/asio/execution/executor.hpp>
  21. #include <boost/asio/execution/receiver.hpp>
  22. #include <boost/asio/detail/push_options.hpp>
  23. #if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) \
  24. && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
  25. && defined(BOOST_ASIO_HAS_DECLTYPE) \
  26. && !defined(BOOST_ASIO_MSVC) || (_MSC_VER >= 1910)
  27. # define BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT 1
  28. #endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
  29. // && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  30. // && defined(BOOST_ASIO_HAS_DECLTYPE)
  31. // && !defined(BOOST_ASIO_MSVC) || (_MSC_VER >= 1910)
  32. namespace boost {
  33. namespace asio {
  34. namespace execution {
  35. namespace detail {
  36. namespace sender_base_ns { struct sender_base {}; }
  37. template <typename S, typename = void>
  38. struct sender_traits_base
  39. {
  40. typedef void asio_execution_sender_traits_base_is_unspecialised;
  41. };
  42. template <typename S>
  43. struct sender_traits_base<S,
  44. typename enable_if<
  45. is_base_of<sender_base_ns::sender_base, S>::value
  46. >::type>
  47. {
  48. };
  49. template <typename S, typename = void, typename = void, typename = void>
  50. struct has_sender_types : false_type
  51. {
  52. };
  53. #if defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
  54. template <
  55. template <
  56. template <typename...> class Tuple,
  57. template <typename...> class Variant
  58. > class>
  59. struct has_value_types
  60. {
  61. typedef void type;
  62. };
  63. template <
  64. template <
  65. template <typename...> class Variant
  66. > class>
  67. struct has_error_types
  68. {
  69. typedef void type;
  70. };
  71. template <typename S>
  72. struct has_sender_types<S,
  73. typename has_value_types<S::template value_types>::type,
  74. typename has_error_types<S::template error_types>::type,
  75. typename conditional<S::sends_done, void, void>::type> : true_type
  76. {
  77. };
  78. template <typename S>
  79. struct sender_traits_base<S,
  80. typename enable_if<
  81. has_sender_types<S>::value
  82. >::type>
  83. {
  84. template <
  85. template <typename...> class Tuple,
  86. template <typename...> class Variant>
  87. using value_types = typename S::template value_types<Tuple, Variant>;
  88. template <template <typename...> class Variant>
  89. using error_types = typename S::template error_types<Variant>;
  90. BOOST_ASIO_STATIC_CONSTEXPR(bool, sends_done = S::sends_done);
  91. };
  92. #endif // defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
  93. template <typename S>
  94. struct sender_traits_base<S,
  95. typename enable_if<
  96. !has_sender_types<S>::value
  97. && detail::is_executor_of_impl<S,
  98. as_invocable<void_receiver, S> >::value
  99. >::type>
  100. {
  101. #if defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT) \
  102. && defined(BOOST_ASIO_HAS_STD_EXCEPTION_PTR)
  103. template <
  104. template <typename...> class Tuple,
  105. template <typename...> class Variant>
  106. using value_types = Variant<Tuple<>>;
  107. template <template <typename...> class Variant>
  108. using error_types = Variant<std::exception_ptr>;
  109. BOOST_ASIO_STATIC_CONSTEXPR(bool, sends_done = true);
  110. #endif // defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
  111. // && defined(BOOST_ASIO_HAS_STD_EXCEPTION_PTR)
  112. };
  113. } // namespace detail
  114. /// Base class used for tagging senders.
  115. #if defined(GENERATING_DOCUMENTATION)
  116. typedef unspecified sender_base;
  117. #else // defined(GENERATING_DOCUMENTATION)
  118. typedef detail::sender_base_ns::sender_base sender_base;
  119. #endif // defined(GENERATING_DOCUMENTATION)
  120. /// Traits for senders.
  121. template <typename S>
  122. struct sender_traits
  123. #if !defined(GENERATING_DOCUMENTATION)
  124. : detail::sender_traits_base<S>
  125. #endif // !defined(GENERATING_DOCUMENTATION)
  126. {
  127. };
  128. namespace detail {
  129. template <typename S, typename = void>
  130. struct has_sender_traits : true_type
  131. {
  132. };
  133. template <typename S>
  134. struct has_sender_traits<S,
  135. typename enable_if<
  136. is_same<
  137. typename boost::asio::execution::sender_traits<
  138. S>::asio_execution_sender_traits_base_is_unspecialised,
  139. void
  140. >::value
  141. >::type> : false_type
  142. {
  143. };
  144. } // namespace detail
  145. /// The is_sender trait detects whether a type T satisfies the
  146. /// execution::sender concept.
  147. /**
  148. * Class template @c is_sender is a type trait that is derived from @c
  149. * true_type if the type @c T meets the concept definition for a sender,
  150. * otherwise @c false_type.
  151. */
  152. template <typename T>
  153. struct is_sender :
  154. #if defined(GENERATING_DOCUMENTATION)
  155. integral_constant<bool, automatically_determined>
  156. #else // defined(GENERATING_DOCUMENTATION)
  157. conditional<
  158. detail::has_sender_traits<typename remove_cvref<T>::type>::value,
  159. is_move_constructible<typename remove_cvref<T>::type>,
  160. false_type
  161. >::type
  162. #endif // defined(GENERATING_DOCUMENTATION)
  163. {
  164. };
  165. #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  166. template <typename T>
  167. BOOST_ASIO_CONSTEXPR const bool is_sender_v = is_sender<T>::value;
  168. #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  169. #if defined(BOOST_ASIO_HAS_CONCEPTS)
  170. template <typename T>
  171. BOOST_ASIO_CONCEPT sender = is_sender<T>::value;
  172. #define BOOST_ASIO_EXECUTION_SENDER ::boost::asio::execution::sender
  173. #else // defined(BOOST_ASIO_HAS_CONCEPTS)
  174. #define BOOST_ASIO_EXECUTION_SENDER typename
  175. #endif // defined(BOOST_ASIO_HAS_CONCEPTS)
  176. template <typename S, typename R>
  177. struct can_connect;
  178. /// The is_sender_to trait detects whether a type T satisfies the
  179. /// execution::sender_to concept for some receiver.
  180. /**
  181. * Class template @c is_sender_to is a type trait that is derived from @c
  182. * true_type if the type @c T meets the concept definition for a sender
  183. * for some receiver type R, otherwise @c false.
  184. */
  185. template <typename T, typename R>
  186. struct is_sender_to :
  187. #if defined(GENERATING_DOCUMENTATION)
  188. integral_constant<bool, automatically_determined>
  189. #else // defined(GENERATING_DOCUMENTATION)
  190. integral_constant<bool,
  191. is_sender<T>::value
  192. && is_receiver<R>::value
  193. && can_connect<T, R>::value
  194. >
  195. #endif // defined(GENERATING_DOCUMENTATION)
  196. {
  197. };
  198. #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  199. template <typename T, typename R>
  200. BOOST_ASIO_CONSTEXPR const bool is_sender_to_v =
  201. is_sender_to<T, R>::value;
  202. #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  203. #if defined(BOOST_ASIO_HAS_CONCEPTS)
  204. template <typename T, typename R>
  205. BOOST_ASIO_CONCEPT sender_to = is_sender_to<T, R>::value;
  206. #define BOOST_ASIO_EXECUTION_SENDER_TO(r) \
  207. ::boost::asio::execution::sender_to<r>
  208. #else // defined(BOOST_ASIO_HAS_CONCEPTS)
  209. #define BOOST_ASIO_EXECUTION_SENDER_TO(r) typename
  210. #endif // defined(BOOST_ASIO_HAS_CONCEPTS)
  211. /// The is_typed_sender trait detects whether a type T satisfies the
  212. /// execution::typed_sender concept.
  213. /**
  214. * Class template @c is_typed_sender is a type trait that is derived from @c
  215. * true_type if the type @c T meets the concept definition for a typed sender,
  216. * otherwise @c false.
  217. */
  218. template <typename T>
  219. struct is_typed_sender :
  220. #if defined(GENERATING_DOCUMENTATION)
  221. integral_constant<bool, automatically_determined>
  222. #else // defined(GENERATING_DOCUMENTATION)
  223. integral_constant<bool,
  224. is_sender<T>::value
  225. && detail::has_sender_types<
  226. sender_traits<typename remove_cvref<T>::type> >::value
  227. >
  228. #endif // defined(GENERATING_DOCUMENTATION)
  229. {
  230. };
  231. #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  232. template <typename T>
  233. BOOST_ASIO_CONSTEXPR const bool is_typed_sender_v = is_typed_sender<T>::value;
  234. #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  235. #if defined(BOOST_ASIO_HAS_CONCEPTS)
  236. template <typename T>
  237. BOOST_ASIO_CONCEPT typed_sender = is_typed_sender<T>::value;
  238. #define BOOST_ASIO_EXECUTION_TYPED_SENDER \
  239. ::boost::asio::execution::typed_sender
  240. #else // defined(BOOST_ASIO_HAS_CONCEPTS)
  241. #define BOOST_ASIO_EXECUTION_TYPED_SENDER typename
  242. #endif // defined(BOOST_ASIO_HAS_CONCEPTS)
  243. } // namespace execution
  244. } // namespace asio
  245. } // namespace boost
  246. #include <boost/asio/detail/pop_options.hpp>
  247. #include <boost/asio/execution/connect.hpp>
  248. #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
  249. #endif // BOOST_ASIO_EXECUTION_SENDER_HPP