set_value.hpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. //
  2. // execution/set_value.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_VALUE_HPP
  11. #define ASIO_EXECUTION_SET_VALUE_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/detail/variadic_templates.hpp"
  18. #include "asio/traits/set_value_member.hpp"
  19. #include "asio/traits/set_value_free.hpp"
  20. #include "asio/detail/push_options.hpp"
  21. #if defined(GENERATING_DOCUMENTATION)
  22. namespace asio {
  23. namespace execution {
  24. /// A customisation point that delivers a value to a receiver.
  25. /**
  26. * The name <tt>execution::set_value</tt> denotes a customisation point object.
  27. * The expression <tt>execution::set_value(R, Vs...)</tt> for some
  28. * subexpressions <tt>R</tt> and <tt>Vs...</tt> is expression-equivalent to:
  29. *
  30. * @li <tt>R.set_value(Vs...)</tt>, if that expression is valid. If the
  31. * function selected does not send the value(s) <tt>Vs...</tt> to the receiver
  32. * <tt>R</tt>'s value channel, the program is ill-formed with no diagnostic
  33. * required.
  34. *
  35. * @li Otherwise, <tt>set_value(R, Vs...)</tt>, if that expression is valid,
  36. * with overload resolution performed in a context that includes the
  37. * declaration <tt>void set_value();</tt> and that does not include a
  38. * declaration of <tt>execution::set_value</tt>. If the function selected by
  39. * overload resolution does not send the value(s) <tt>Vs...</tt> to the
  40. * receiver <tt>R</tt>'s value channel, the program is ill-formed with no
  41. * diagnostic required.
  42. *
  43. * @li Otherwise, <tt>execution::set_value(R, Vs...)</tt> is ill-formed.
  44. */
  45. inline constexpr unspecified set_value = unspecified;
  46. /// A type trait that determines whether a @c set_value expression is
  47. /// well-formed.
  48. /**
  49. * Class template @c can_set_value is a trait that is derived from
  50. * @c true_type if the expression <tt>execution::set_value(std::declval<R>(),
  51. * std::declval<Vs>()...)</tt> is well formed; otherwise @c false_type.
  52. */
  53. template <typename R, typename... Vs>
  54. struct can_set_value :
  55. integral_constant<bool, automatically_determined>
  56. {
  57. };
  58. } // namespace execution
  59. } // namespace asio
  60. #else // defined(GENERATING_DOCUMENTATION)
  61. namespace asio_execution_set_value_fn {
  62. using asio::decay;
  63. using asio::declval;
  64. using asio::enable_if;
  65. using asio::traits::set_value_free;
  66. using asio::traits::set_value_member;
  67. void set_value();
  68. enum overload_type
  69. {
  70. call_member,
  71. call_free,
  72. ill_formed
  73. };
  74. template <typename R, typename Vs, typename = void, typename = void>
  75. struct call_traits
  76. {
  77. ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);
  78. ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
  79. typedef void result_type;
  80. };
  81. template <typename R, typename Vs>
  82. struct call_traits<R, Vs,
  83. typename enable_if<
  84. set_value_member<R, Vs>::is_valid
  85. >::type> :
  86. set_value_member<R, Vs>
  87. {
  88. ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);
  89. };
  90. template <typename R, typename Vs>
  91. struct call_traits<R, Vs,
  92. typename enable_if<
  93. !set_value_member<R, Vs>::is_valid
  94. >::type,
  95. typename enable_if<
  96. set_value_free<R, Vs>::is_valid
  97. >::type> :
  98. set_value_free<R, Vs>
  99. {
  100. ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);
  101. };
  102. struct impl
  103. {
  104. #if defined(ASIO_HAS_MOVE)
  105. #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
  106. template <typename R, typename... Vs>
  107. ASIO_CONSTEXPR typename enable_if<
  108. call_traits<R, void(Vs...)>::overload == call_member,
  109. typename call_traits<R, void(Vs...)>::result_type
  110. >::type
  111. operator()(R&& r, Vs&&... v) const
  112. ASIO_NOEXCEPT_IF((
  113. call_traits<R, void(Vs...)>::is_noexcept))
  114. {
  115. return ASIO_MOVE_CAST(R)(r).set_value(ASIO_MOVE_CAST(Vs)(v)...);
  116. }
  117. template <typename R, typename... Vs>
  118. ASIO_CONSTEXPR typename enable_if<
  119. call_traits<R, void(Vs...)>::overload == call_free,
  120. typename call_traits<R, void(Vs...)>::result_type
  121. >::type
  122. operator()(R&& r, Vs&&... v) const
  123. ASIO_NOEXCEPT_IF((
  124. call_traits<R, void(Vs...)>::is_noexcept))
  125. {
  126. return set_value(ASIO_MOVE_CAST(R)(r),
  127. ASIO_MOVE_CAST(Vs)(v)...);
  128. }
  129. #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  130. template <typename R>
  131. ASIO_CONSTEXPR typename enable_if<
  132. call_traits<R, void()>::overload == call_member,
  133. typename call_traits<R, void()>::result_type
  134. >::type
  135. operator()(R&& r) const
  136. ASIO_NOEXCEPT_IF((
  137. call_traits<R, void()>::is_noexcept))
  138. {
  139. return ASIO_MOVE_CAST(R)(r).set_value();
  140. }
  141. template <typename R>
  142. ASIO_CONSTEXPR typename enable_if<
  143. call_traits<R, void()>::overload == call_free,
  144. typename call_traits<R, void()>::result_type
  145. >::type
  146. operator()(R&& r) const
  147. ASIO_NOEXCEPT_IF((
  148. call_traits<R, void()>::is_noexcept))
  149. {
  150. return set_value(ASIO_MOVE_CAST(R)(r));
  151. }
  152. #define ASIO_PRIVATE_SET_VALUE_CALL_DEF(n) \
  153. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  154. ASIO_CONSTEXPR typename enable_if< \
  155. call_traits<R, \
  156. void(ASIO_VARIADIC_TARGS(n))>::overload == call_member, \
  157. typename call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::result_type \
  158. >::type \
  159. operator()(R&& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \
  160. ASIO_NOEXCEPT_IF(( \
  161. call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \
  162. { \
  163. return ASIO_MOVE_CAST(R)(r).set_value( \
  164. ASIO_VARIADIC_MOVE_ARGS(n)); \
  165. } \
  166. \
  167. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  168. ASIO_CONSTEXPR typename enable_if< \
  169. call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::overload == call_free, \
  170. typename call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::result_type \
  171. >::type \
  172. operator()(R&& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \
  173. ASIO_NOEXCEPT_IF(( \
  174. call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \
  175. { \
  176. return set_value(ASIO_MOVE_CAST(R)(r), \
  177. ASIO_VARIADIC_MOVE_ARGS(n)); \
  178. } \
  179. /**/
  180. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_CALL_DEF)
  181. #undef ASIO_PRIVATE_SET_VALUE_CALL_DEF
  182. #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  183. #else // defined(ASIO_HAS_MOVE)
  184. #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
  185. template <typename R, typename... Vs>
  186. ASIO_CONSTEXPR typename enable_if<
  187. call_traits<R&, void(const Vs&...)>::overload == call_member,
  188. typename call_traits<R&, void(const Vs&...)>::result_type
  189. >::type
  190. operator()(R& r, const Vs&... v) const
  191. ASIO_NOEXCEPT_IF((
  192. call_traits<R&, void(const Vs&...)>::is_noexcept))
  193. {
  194. return r.set_value(v...);
  195. }
  196. template <typename R, typename... Vs>
  197. ASIO_CONSTEXPR typename enable_if<
  198. call_traits<const R&, void(const Vs&...)>::overload == call_member,
  199. typename call_traits<const R&, void(const Vs&...)>::result_type
  200. >::type
  201. operator()(const R& r, const Vs&... v) const
  202. ASIO_NOEXCEPT_IF((
  203. call_traits<const R&, void(const Vs&...)>::is_noexcept))
  204. {
  205. return r.set_value(v...);
  206. }
  207. template <typename R, typename... Vs>
  208. ASIO_CONSTEXPR typename enable_if<
  209. call_traits<R&, void(const Vs&...)>::overload == call_free,
  210. typename call_traits<R&, void(const Vs&...)>::result_type
  211. >::type
  212. operator()(R& r, const Vs&... v) const
  213. ASIO_NOEXCEPT_IF((
  214. call_traits<R&, void(const Vs&...)>::is_noexcept))
  215. {
  216. return set_value(r, v...);
  217. }
  218. template <typename R, typename... Vs>
  219. ASIO_CONSTEXPR typename enable_if<
  220. call_traits<const R&, void(const Vs&...)>::overload == call_free,
  221. typename call_traits<const R&, void(const Vs&...)>::result_type
  222. >::type
  223. operator()(const R& r, const Vs&... v) const
  224. ASIO_NOEXCEPT_IF((
  225. call_traits<const R&, void(const Vs&...)>::is_noexcept))
  226. {
  227. return set_value(r, v...);
  228. }
  229. #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  230. template <typename R>
  231. ASIO_CONSTEXPR typename enable_if<
  232. call_traits<R&, void()>::overload == call_member,
  233. typename call_traits<R&, void()>::result_type
  234. >::type
  235. operator()(R& r) const
  236. ASIO_NOEXCEPT_IF((
  237. call_traits<R&, void()>::is_noexcept))
  238. {
  239. return r.set_value();
  240. }
  241. template <typename R>
  242. ASIO_CONSTEXPR typename enable_if<
  243. call_traits<const R&, void()>::overload == call_member,
  244. typename call_traits<const R&, void()>::result_type
  245. >::type
  246. operator()(const R& r) const
  247. ASIO_NOEXCEPT_IF((
  248. call_traits<const R&, void()>::is_noexcept))
  249. {
  250. return r.set_value();
  251. }
  252. template <typename R>
  253. ASIO_CONSTEXPR typename enable_if<
  254. call_traits<R&, void()>::overload == call_free,
  255. typename call_traits<R&, void()>::result_type
  256. >::type
  257. operator()(R& r) const
  258. ASIO_NOEXCEPT_IF((
  259. call_traits<R&, void()>::is_noexcept))
  260. {
  261. return set_value(r);
  262. }
  263. template <typename R>
  264. ASIO_CONSTEXPR typename enable_if<
  265. call_traits<const R&, void()>::overload == call_free,
  266. typename call_traits<const R&, void()>::result_type
  267. >::type
  268. operator()(const R& r) const
  269. ASIO_NOEXCEPT_IF((
  270. call_traits<const R&, void()>::is_noexcept))
  271. {
  272. return set_value(r);
  273. }
  274. #define ASIO_PRIVATE_SET_VALUE_CALL_DEF(n) \
  275. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  276. ASIO_CONSTEXPR typename enable_if< \
  277. call_traits<R&, \
  278. void(ASIO_VARIADIC_TARGS(n))>::overload == call_member, \
  279. typename call_traits<R&, void(ASIO_VARIADIC_TARGS(n))>::result_type \
  280. >::type \
  281. operator()(R& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \
  282. ASIO_NOEXCEPT_IF(( \
  283. call_traits<R&, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \
  284. { \
  285. return r.set_value(ASIO_VARIADIC_MOVE_ARGS(n)); \
  286. } \
  287. \
  288. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  289. ASIO_CONSTEXPR typename enable_if< \
  290. call_traits<const R&, \
  291. void(ASIO_VARIADIC_TARGS(n))>::overload == call_member, \
  292. typename call_traits<const R&, \
  293. void(ASIO_VARIADIC_TARGS(n))>::result_type \
  294. >::type \
  295. operator()(const R& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \
  296. ASIO_NOEXCEPT_IF(( \
  297. call_traits<const R&, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \
  298. { \
  299. return r.set_value(ASIO_VARIADIC_MOVE_ARGS(n)); \
  300. } \
  301. \
  302. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  303. ASIO_CONSTEXPR typename enable_if< \
  304. call_traits<R&, \
  305. void(ASIO_VARIADIC_TARGS(n))>::overload == call_free, \
  306. typename call_traits<R&, void(ASIO_VARIADIC_TARGS(n))>::result_type \
  307. >::type \
  308. operator()(R& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \
  309. ASIO_NOEXCEPT_IF(( \
  310. call_traits<R&, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \
  311. { \
  312. return set_value(r, ASIO_VARIADIC_MOVE_ARGS(n)); \
  313. } \
  314. \
  315. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  316. ASIO_CONSTEXPR typename enable_if< \
  317. call_traits<const R&, \
  318. void(ASIO_VARIADIC_TARGS(n))>::overload == call_free, \
  319. typename call_traits<const R&, \
  320. void(ASIO_VARIADIC_TARGS(n))>::result_type \
  321. >::type \
  322. operator()(const R& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \
  323. ASIO_NOEXCEPT_IF(( \
  324. call_traits<const R&, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \
  325. { \
  326. return set_value(r, ASIO_VARIADIC_MOVE_ARGS(n)); \
  327. } \
  328. /**/
  329. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_CALL_DEF)
  330. #undef ASIO_PRIVATE_SET_VALUE_CALL_DEF
  331. #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  332. #endif // defined(ASIO_HAS_MOVE)
  333. };
  334. template <typename T = impl>
  335. struct static_instance
  336. {
  337. static const T instance;
  338. };
  339. template <typename T>
  340. const T static_instance<T>::instance = {};
  341. } // namespace asio_execution_set_value_fn
  342. namespace asio {
  343. namespace execution {
  344. namespace {
  345. static ASIO_CONSTEXPR const asio_execution_set_value_fn::impl&
  346. set_value = asio_execution_set_value_fn::static_instance<>::instance;
  347. } // namespace
  348. #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
  349. template <typename R, typename... Vs>
  350. struct can_set_value :
  351. integral_constant<bool,
  352. asio_execution_set_value_fn::call_traits<R, void(Vs...)>::overload !=
  353. asio_execution_set_value_fn::ill_formed>
  354. {
  355. };
  356. #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
  357. template <typename R, typename... Vs>
  358. constexpr bool can_set_value_v = can_set_value<R, Vs...>::value;
  359. #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
  360. template <typename R, typename... Vs>
  361. struct is_nothrow_set_value :
  362. integral_constant<bool,
  363. asio_execution_set_value_fn::call_traits<R, void(Vs...)>::is_noexcept>
  364. {
  365. };
  366. #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
  367. template <typename R, typename... Vs>
  368. constexpr bool is_nothrow_set_value_v
  369. = is_nothrow_set_value<R, Vs...>::value;
  370. #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
  371. #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  372. template <typename R, typename = void,
  373. typename = void, typename = void, typename = void, typename = void,
  374. typename = void, typename = void, typename = void, typename = void>
  375. struct can_set_value;
  376. template <typename R, typename = void,
  377. typename = void, typename = void, typename = void, typename = void,
  378. typename = void, typename = void, typename = void, typename = void>
  379. struct is_nothrow_set_value;
  380. template <typename R>
  381. struct can_set_value<R> :
  382. integral_constant<bool,
  383. asio_execution_set_value_fn::call_traits<R, void()>::overload !=
  384. asio_execution_set_value_fn::ill_formed>
  385. {
  386. };
  387. template <typename R>
  388. struct is_nothrow_set_value<R> :
  389. integral_constant<bool,
  390. asio_execution_set_value_fn::call_traits<R, void()>::is_noexcept>
  391. {
  392. };
  393. #define ASIO_PRIVATE_SET_VALUE_TRAITS_DEF(n) \
  394. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  395. struct can_set_value<R, ASIO_VARIADIC_TARGS(n)> : \
  396. integral_constant<bool, \
  397. asio_execution_set_value_fn::call_traits<R, \
  398. void(ASIO_VARIADIC_TARGS(n))>::overload != \
  399. asio_execution_set_value_fn::ill_formed> \
  400. { \
  401. }; \
  402. \
  403. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  404. struct is_nothrow_set_value<R, ASIO_VARIADIC_TARGS(n)> : \
  405. integral_constant<bool, \
  406. asio_execution_set_value_fn::call_traits<R, \
  407. void(ASIO_VARIADIC_TARGS(n))>::is_noexcept> \
  408. { \
  409. }; \
  410. /**/
  411. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_TRAITS_DEF)
  412. #undef ASIO_PRIVATE_SET_VALUE_TRAITS_DEF
  413. #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  414. } // namespace execution
  415. } // namespace asio
  416. #endif // defined(GENERATING_DOCUMENTATION)
  417. #include "asio/detail/pop_options.hpp"
  418. #endif // ASIO_EXECUTION_SET_VALUE_HPP