start.hpp 6.1 KB

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