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