set_value.hpp 15 KB

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