set_done.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. //
  2. // execution/set_done.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_SET_DONE_HPP
  11. #define ASIO_EXECUTION_SET_DONE_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/set_done_member.hpp"
  18. #include "asio/traits/set_done_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 delivers a done notification to a receiver.
  24. /**
  25. * The name <tt>execution::set_done</tt> denotes a customisation point object.
  26. * The expression <tt>execution::set_done(R)</tt> for some subexpression
  27. * <tt>R</tt> is expression-equivalent to:
  28. *
  29. * @li <tt>R.set_done()</tt>, if that expression is valid. If the function
  30. * selected does not signal the receiver <tt>R</tt>'s done channel, the
  31. * program is ill-formed with no diagnostic required.
  32. *
  33. * @li Otherwise, <tt>set_done(R)</tt>, if that expression is valid, with
  34. * overload resolution performed in a context that includes the declaration
  35. * <tt>void set_done();</tt> and that does not include a declaration of
  36. * <tt>execution::set_done</tt>. If the function selected by overload
  37. * resolution does not signal the receiver <tt>R</tt>'s done channel, the
  38. * program is ill-formed with no diagnostic required.
  39. *
  40. * @li Otherwise, <tt>execution::set_done(R)</tt> is ill-formed.
  41. */
  42. inline constexpr unspecified set_done = unspecified;
  43. /// A type trait that determines whether a @c set_done expression is
  44. /// well-formed.
  45. /**
  46. * Class template @c can_set_done is a trait that is derived from
  47. * @c true_type if the expression <tt>execution::set_done(std::declval<R>(),
  48. * std::declval<E>())</tt> is well formed; otherwise @c false_type.
  49. */
  50. template <typename R>
  51. struct can_set_done :
  52. integral_constant<bool, automatically_determined>
  53. {
  54. };
  55. } // namespace execution
  56. } // namespace asio
  57. #else // defined(GENERATING_DOCUMENTATION)
  58. namespace asio_execution_set_done_fn {
  59. using asio::decay;
  60. using asio::declval;
  61. using asio::enable_if;
  62. using asio::traits::set_done_free;
  63. using asio::traits::set_done_member;
  64. void set_done();
  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. ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);
  75. 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. set_done_member<R>::is_valid
  82. >::type> :
  83. set_done_member<R>
  84. {
  85. ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);
  86. };
  87. template <typename R>
  88. struct call_traits<R,
  89. typename enable_if<
  90. !set_done_member<R>::is_valid
  91. >::type,
  92. typename enable_if<
  93. set_done_free<R>::is_valid
  94. >::type> :
  95. set_done_free<R>
  96. {
  97. ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);
  98. };
  99. struct impl
  100. {
  101. #if defined(ASIO_HAS_MOVE)
  102. template <typename R>
  103. 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. ASIO_NOEXCEPT_IF((
  109. call_traits<R>::is_noexcept))
  110. {
  111. return ASIO_MOVE_CAST(R)(r).set_done();
  112. }
  113. template <typename R>
  114. 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. ASIO_NOEXCEPT_IF((
  120. call_traits<R>::is_noexcept))
  121. {
  122. return set_done(ASIO_MOVE_CAST(R)(r));
  123. }
  124. #else // defined(ASIO_HAS_MOVE)
  125. template <typename R>
  126. 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. ASIO_NOEXCEPT_IF((
  132. call_traits<R&>::is_noexcept))
  133. {
  134. return r.set_done();
  135. }
  136. template <typename R>
  137. 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. ASIO_NOEXCEPT_IF((
  143. call_traits<const R&>::is_noexcept))
  144. {
  145. return r.set_done();
  146. }
  147. template <typename R>
  148. 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. ASIO_NOEXCEPT_IF((
  154. call_traits<R&>::is_noexcept))
  155. {
  156. return set_done(r);
  157. }
  158. template <typename R>
  159. 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. ASIO_NOEXCEPT_IF((
  165. call_traits<const R&>::is_noexcept))
  166. {
  167. return set_done(r);
  168. }
  169. #endif // defined(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 asio_execution_set_done_fn
  179. namespace asio {
  180. namespace execution {
  181. namespace {
  182. static ASIO_CONSTEXPR const asio_execution_set_done_fn::impl&
  183. set_done = asio_execution_set_done_fn::static_instance<>::instance;
  184. } // namespace
  185. template <typename R>
  186. struct can_set_done :
  187. integral_constant<bool,
  188. asio_execution_set_done_fn::call_traits<R>::overload !=
  189. asio_execution_set_done_fn::ill_formed>
  190. {
  191. };
  192. #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
  193. template <typename R>
  194. constexpr bool can_set_done_v = can_set_done<R>::value;
  195. #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
  196. template <typename R>
  197. struct is_nothrow_set_done :
  198. integral_constant<bool,
  199. asio_execution_set_done_fn::call_traits<R>::is_noexcept>
  200. {
  201. };
  202. #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
  203. template <typename R>
  204. constexpr bool is_nothrow_set_done_v
  205. = is_nothrow_set_done<R>::value;
  206. #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
  207. } // namespace execution
  208. } // namespace asio
  209. #endif // defined(GENERATING_DOCUMENTATION)
  210. #include "asio/detail/pop_options.hpp"
  211. #endif // ASIO_EXECUTION_SET_DONE_HPP