sender.hpp 8.3 KB

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