]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
1 | // |
2 | // execution/set_done.hpp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
1e59de90 | 5 | // Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
20effc67 TL |
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_DONE_HPP | |
12 | #define BOOST_ASIO_EXECUTION_SET_DONE_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/traits/set_done_member.hpp> | |
21 | #include <boost/asio/traits/set_done_free.hpp> | |
22 | ||
23 | #include <boost/asio/detail/push_options.hpp> | |
24 | ||
25 | #if defined(GENERATING_DOCUMENTATION) | |
26 | ||
27 | namespace boost { | |
28 | namespace asio { | |
29 | namespace execution { | |
30 | ||
31 | /// A customisation point that delivers a done notification to a receiver. | |
32 | /** | |
33 | * The name <tt>execution::set_done</tt> denotes a customisation point object. | |
34 | * The expression <tt>execution::set_done(R)</tt> for some subexpression | |
35 | * <tt>R</tt> is expression-equivalent to: | |
36 | * | |
37 | * @li <tt>R.set_done()</tt>, if that expression is valid. If the function | |
38 | * selected does not signal the receiver <tt>R</tt>'s done channel, the | |
39 | * program is ill-formed with no diagnostic required. | |
40 | * | |
41 | * @li Otherwise, <tt>set_done(R)</tt>, if that expression is valid, with | |
42 | * overload resolution performed in a context that includes the declaration | |
43 | * <tt>void set_done();</tt> and that does not include a declaration of | |
44 | * <tt>execution::set_done</tt>. If the function selected by overload | |
45 | * resolution does not signal the receiver <tt>R</tt>'s done channel, the | |
46 | * program is ill-formed with no diagnostic required. | |
47 | * | |
48 | * @li Otherwise, <tt>execution::set_done(R)</tt> is ill-formed. | |
49 | */ | |
50 | inline constexpr unspecified set_done = unspecified; | |
51 | ||
52 | /// A type trait that determines whether a @c set_done expression is | |
53 | /// well-formed. | |
54 | /** | |
55 | * Class template @c can_set_done is a trait that is derived from | |
56 | * @c true_type if the expression <tt>execution::set_done(std::declval<R>(), | |
57 | * std::declval<E>())</tt> is well formed; otherwise @c false_type. | |
58 | */ | |
59 | template <typename R> | |
60 | struct can_set_done : | |
61 | integral_constant<bool, automatically_determined> | |
62 | { | |
63 | }; | |
64 | ||
65 | } // namespace execution | |
66 | } // namespace asio | |
67 | } // namespace boost | |
68 | ||
69 | #else // defined(GENERATING_DOCUMENTATION) | |
70 | ||
1e59de90 | 71 | namespace boost_asio_execution_set_done_fn { |
20effc67 TL |
72 | |
73 | using boost::asio::decay; | |
74 | using boost::asio::declval; | |
75 | using boost::asio::enable_if; | |
76 | using boost::asio::traits::set_done_free; | |
77 | using boost::asio::traits::set_done_member; | |
78 | ||
79 | void set_done(); | |
80 | ||
81 | enum overload_type | |
82 | { | |
83 | call_member, | |
84 | call_free, | |
85 | ill_formed | |
86 | }; | |
87 | ||
1e59de90 | 88 | template <typename R, typename = void, typename = void> |
20effc67 TL |
89 | struct call_traits |
90 | { | |
91 | BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed); | |
92 | BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); | |
93 | typedef void result_type; | |
94 | }; | |
95 | ||
96 | template <typename R> | |
97 | struct call_traits<R, | |
98 | typename enable_if< | |
1e59de90 | 99 | set_done_member<R>::is_valid |
20effc67 TL |
100 | >::type> : |
101 | set_done_member<R> | |
102 | { | |
103 | BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); | |
104 | }; | |
105 | ||
106 | template <typename R> | |
107 | struct call_traits<R, | |
108 | typename enable_if< | |
1e59de90 TL |
109 | !set_done_member<R>::is_valid |
110 | >::type, | |
111 | typename enable_if< | |
112 | set_done_free<R>::is_valid | |
20effc67 TL |
113 | >::type> : |
114 | set_done_free<R> | |
115 | { | |
116 | BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); | |
117 | }; | |
118 | ||
119 | struct impl | |
120 | { | |
121 | #if defined(BOOST_ASIO_HAS_MOVE) | |
122 | template <typename R> | |
123 | BOOST_ASIO_CONSTEXPR typename enable_if< | |
124 | call_traits<R>::overload == call_member, | |
125 | typename call_traits<R>::result_type | |
126 | >::type | |
127 | operator()(R&& r) const | |
128 | BOOST_ASIO_NOEXCEPT_IF(( | |
129 | call_traits<R>::is_noexcept)) | |
130 | { | |
131 | return BOOST_ASIO_MOVE_CAST(R)(r).set_done(); | |
132 | } | |
133 | ||
134 | template <typename R> | |
135 | BOOST_ASIO_CONSTEXPR typename enable_if< | |
136 | call_traits<R>::overload == call_free, | |
137 | typename call_traits<R>::result_type | |
138 | >::type | |
139 | operator()(R&& r) const | |
140 | BOOST_ASIO_NOEXCEPT_IF(( | |
141 | call_traits<R>::is_noexcept)) | |
142 | { | |
143 | return set_done(BOOST_ASIO_MOVE_CAST(R)(r)); | |
144 | } | |
145 | #else // defined(BOOST_ASIO_HAS_MOVE) | |
146 | template <typename R> | |
147 | BOOST_ASIO_CONSTEXPR typename enable_if< | |
148 | call_traits<R&>::overload == call_member, | |
149 | typename call_traits<R&>::result_type | |
150 | >::type | |
151 | operator()(R& r) const | |
152 | BOOST_ASIO_NOEXCEPT_IF(( | |
153 | call_traits<R&>::is_noexcept)) | |
154 | { | |
155 | return r.set_done(); | |
156 | } | |
157 | ||
158 | template <typename R> | |
159 | BOOST_ASIO_CONSTEXPR typename enable_if< | |
160 | call_traits<const R&>::overload == call_member, | |
161 | typename call_traits<const R&>::result_type | |
162 | >::type | |
163 | operator()(const R& r) const | |
164 | BOOST_ASIO_NOEXCEPT_IF(( | |
165 | call_traits<const R&>::is_noexcept)) | |
166 | { | |
167 | return r.set_done(); | |
168 | } | |
169 | ||
170 | template <typename R> | |
171 | BOOST_ASIO_CONSTEXPR typename enable_if< | |
172 | call_traits<R&>::overload == call_free, | |
173 | typename call_traits<R&>::result_type | |
174 | >::type | |
175 | operator()(R& r) const | |
176 | BOOST_ASIO_NOEXCEPT_IF(( | |
177 | call_traits<R&>::is_noexcept)) | |
178 | { | |
179 | return set_done(r); | |
180 | } | |
181 | ||
182 | template <typename R> | |
183 | BOOST_ASIO_CONSTEXPR typename enable_if< | |
184 | call_traits<const R&>::overload == call_free, | |
185 | typename call_traits<const R&>::result_type | |
186 | >::type | |
187 | operator()(const R& r) const | |
188 | BOOST_ASIO_NOEXCEPT_IF(( | |
189 | call_traits<const R&>::is_noexcept)) | |
190 | { | |
191 | return set_done(r); | |
192 | } | |
193 | #endif // defined(BOOST_ASIO_HAS_MOVE) | |
194 | }; | |
195 | ||
196 | template <typename T = impl> | |
197 | struct static_instance | |
198 | { | |
199 | static const T instance; | |
200 | }; | |
201 | ||
202 | template <typename T> | |
203 | const T static_instance<T>::instance = {}; | |
204 | ||
1e59de90 | 205 | } // namespace boost_asio_execution_set_done_fn |
20effc67 TL |
206 | namespace boost { |
207 | namespace asio { | |
208 | namespace execution { | |
209 | namespace { | |
210 | ||
1e59de90 TL |
211 | static BOOST_ASIO_CONSTEXPR const boost_asio_execution_set_done_fn::impl& |
212 | set_done = boost_asio_execution_set_done_fn::static_instance<>::instance; | |
20effc67 TL |
213 | |
214 | } // namespace | |
215 | ||
216 | template <typename R> | |
217 | struct can_set_done : | |
218 | integral_constant<bool, | |
1e59de90 TL |
219 | boost_asio_execution_set_done_fn::call_traits<R>::overload != |
220 | boost_asio_execution_set_done_fn::ill_formed> | |
20effc67 TL |
221 | { |
222 | }; | |
223 | ||
224 | #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) | |
225 | ||
226 | template <typename R> | |
227 | constexpr bool can_set_done_v = can_set_done<R>::value; | |
228 | ||
229 | #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) | |
230 | ||
231 | template <typename R> | |
232 | struct is_nothrow_set_done : | |
233 | integral_constant<bool, | |
1e59de90 | 234 | boost_asio_execution_set_done_fn::call_traits<R>::is_noexcept> |
20effc67 TL |
235 | { |
236 | }; | |
237 | ||
238 | #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) | |
239 | ||
240 | template <typename R> | |
241 | constexpr bool is_nothrow_set_done_v | |
242 | = is_nothrow_set_done<R>::value; | |
243 | ||
244 | #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) | |
245 | ||
246 | } // namespace execution | |
247 | } // namespace asio | |
248 | } // namespace boost | |
249 | ||
250 | #endif // defined(GENERATING_DOCUMENTATION) | |
251 | ||
252 | #include <boost/asio/detail/pop_options.hpp> | |
253 | ||
254 | #endif // BOOST_ASIO_EXECUTION_SET_DONE_HPP |