start.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. //
  2. // execution/start.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_START_HPP
  11. #define BOOST_ASIO_EXECUTION_START_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/traits/start_member.hpp>
  19. #include <boost/asio/traits/start_free.hpp>
  20. #include <boost/asio/detail/push_options.hpp>
  21. #if defined(GENERATING_DOCUMENTATION)
  22. namespace boost {
  23. namespace asio {
  24. namespace execution {
  25. /// A customisation point that notifies an operation state object to start
  26. /// its associated operation.
  27. /**
  28. * The name <tt>execution::start</tt> denotes a customisation point object.
  29. * The expression <tt>execution::start(R)</tt> for some subexpression
  30. * <tt>R</tt> is expression-equivalent to:
  31. *
  32. * @li <tt>R.start()</tt>, if that expression is valid.
  33. *
  34. * @li Otherwise, <tt>start(R)</tt>, if that expression is valid, with
  35. * overload resolution performed in a context that includes the declaration
  36. * <tt>void start();</tt> and that does not include a declaration of
  37. * <tt>execution::start</tt>.
  38. *
  39. * @li Otherwise, <tt>execution::start(R)</tt> is ill-formed.
  40. */
  41. inline constexpr unspecified start = unspecified;
  42. /// A type trait that determines whether a @c start expression is
  43. /// well-formed.
  44. /**
  45. * Class template @c can_start is a trait that is derived from
  46. * @c true_type if the expression <tt>execution::start(std::declval<R>(),
  47. * std::declval<E>())</tt> is well formed; otherwise @c false_type.
  48. */
  49. template <typename R>
  50. struct can_start :
  51. integral_constant<bool, automatically_determined>
  52. {
  53. };
  54. } // namespace execution
  55. } // namespace asio
  56. } // namespace boost
  57. #else // defined(GENERATING_DOCUMENTATION)
  58. namespace boost_asio_execution_start_fn {
  59. using boost::asio::decay;
  60. using boost::asio::declval;
  61. using boost::asio::enable_if;
  62. using boost::asio::traits::start_free;
  63. using boost::asio::traits::start_member;
  64. void start();
  65. enum overload_type
  66. {
  67. call_member,
  68. call_free,
  69. ill_formed
  70. };
  71. template <typename R, typename = void, typename = void>
  72. struct call_traits
  73. {
  74. BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);
  75. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
  76. typedef void result_type;
  77. };
  78. template <typename R>
  79. struct call_traits<R,
  80. typename enable_if<
  81. start_member<R>::is_valid
  82. >::type> :
  83. start_member<R>
  84. {
  85. BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);
  86. };
  87. template <typename R>
  88. struct call_traits<R,
  89. typename enable_if<
  90. !start_member<R>::is_valid
  91. >::type,
  92. typename enable_if<
  93. start_free<R>::is_valid
  94. >::type> :
  95. start_free<R>
  96. {
  97. BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);
  98. };
  99. struct impl
  100. {
  101. #if defined(BOOST_ASIO_HAS_MOVE)
  102. template <typename R>
  103. BOOST_ASIO_CONSTEXPR typename enable_if<
  104. call_traits<R>::overload == call_member,
  105. typename call_traits<R>::result_type
  106. >::type
  107. operator()(R&& r) const
  108. BOOST_ASIO_NOEXCEPT_IF((
  109. call_traits<R>::is_noexcept))
  110. {
  111. return BOOST_ASIO_MOVE_CAST(R)(r).start();
  112. }
  113. template <typename R>
  114. BOOST_ASIO_CONSTEXPR typename enable_if<
  115. call_traits<R>::overload == call_free,
  116. typename call_traits<R>::result_type
  117. >::type
  118. operator()(R&& r) const
  119. BOOST_ASIO_NOEXCEPT_IF((
  120. call_traits<R>::is_noexcept))
  121. {
  122. return start(BOOST_ASIO_MOVE_CAST(R)(r));
  123. }
  124. #else // defined(BOOST_ASIO_HAS_MOVE)
  125. template <typename R>
  126. BOOST_ASIO_CONSTEXPR typename enable_if<
  127. call_traits<R&>::overload == call_member,
  128. typename call_traits<R&>::result_type
  129. >::type
  130. operator()(R& r) const
  131. BOOST_ASIO_NOEXCEPT_IF((
  132. call_traits<R&>::is_noexcept))
  133. {
  134. return r.start();
  135. }
  136. template <typename R>
  137. BOOST_ASIO_CONSTEXPR typename enable_if<
  138. call_traits<const R&>::overload == call_member,
  139. typename call_traits<const R&>::result_type
  140. >::type
  141. operator()(const R& r) const
  142. BOOST_ASIO_NOEXCEPT_IF((
  143. call_traits<const R&>::is_noexcept))
  144. {
  145. return r.start();
  146. }
  147. template <typename R>
  148. BOOST_ASIO_CONSTEXPR typename enable_if<
  149. call_traits<R&>::overload == call_free,
  150. typename call_traits<R&>::result_type
  151. >::type
  152. operator()(R& r) const
  153. BOOST_ASIO_NOEXCEPT_IF((
  154. call_traits<R&>::is_noexcept))
  155. {
  156. return start(r);
  157. }
  158. template <typename R>
  159. BOOST_ASIO_CONSTEXPR typename enable_if<
  160. call_traits<const R&>::overload == call_free,
  161. typename call_traits<const R&>::result_type
  162. >::type
  163. operator()(const R& r) const
  164. BOOST_ASIO_NOEXCEPT_IF((
  165. call_traits<const R&>::is_noexcept))
  166. {
  167. return start(r);
  168. }
  169. #endif // defined(BOOST_ASIO_HAS_MOVE)
  170. };
  171. template <typename T = impl>
  172. struct static_instance
  173. {
  174. static const T instance;
  175. };
  176. template <typename T>
  177. const T static_instance<T>::instance = {};
  178. } // namespace boost_asio_execution_start_fn
  179. namespace boost {
  180. namespace asio {
  181. namespace execution {
  182. namespace {
  183. static BOOST_ASIO_CONSTEXPR const boost_asio_execution_start_fn::impl&
  184. start = boost_asio_execution_start_fn::static_instance<>::instance;
  185. } // namespace
  186. template <typename R>
  187. struct can_start :
  188. integral_constant<bool,
  189. boost_asio_execution_start_fn::call_traits<R>::overload !=
  190. boost_asio_execution_start_fn::ill_formed>
  191. {
  192. };
  193. #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  194. template <typename R>
  195. constexpr bool can_start_v = can_start<R>::value;
  196. #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  197. template <typename R>
  198. struct is_nothrow_start :
  199. integral_constant<bool,
  200. boost_asio_execution_start_fn::call_traits<R>::is_noexcept>
  201. {
  202. };
  203. #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  204. template <typename R>
  205. constexpr bool is_nothrow_start_v
  206. = is_nothrow_start<R>::value;
  207. #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  208. } // namespace execution
  209. } // namespace asio
  210. } // namespace boost
  211. #endif // defined(GENERATING_DOCUMENTATION)
  212. #include <boost/asio/detail/pop_options.hpp>
  213. #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
  214. #endif // BOOST_ASIO_EXECUTION_START_HPP