start.hpp 5.8 KB

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