set_value.hpp 15 KB

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