]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
1 | // |
2 | // execution/set_error.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_ERROR_HPP | |
12 | #define BOOST_ASIO_EXECUTION_SET_ERROR_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_error_member.hpp> | |
21 | #include <boost/asio/traits/set_error_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 an error notification to a receiver. | |
32 | /** | |
33 | * The name <tt>execution::set_error</tt> denotes a customisation point object. | |
34 | * The expression <tt>execution::set_error(R, E)</tt> for some subexpressions | |
35 | * <tt>R</tt> and <tt>E</tt> are expression-equivalent to: | |
36 | * | |
37 | * @li <tt>R.set_error(E)</tt>, if that expression is valid. If the function | |
38 | * selected does not send the error <tt>E</tt> to the receiver <tt>R</tt>'s | |
39 | * error channel, the program is ill-formed with no diagnostic required. | |
40 | * | |
41 | * @li Otherwise, <tt>set_error(R, E)</tt>, if that expression is valid, with | |
42 | * overload resolution performed in a context that includes the declaration | |
43 | * <tt>void set_error();</tt> and that does not include a declaration of | |
44 | * <tt>execution::set_error</tt>. If the function selected by overload | |
45 | * resolution does not send the error <tt>E</tt> to the receiver <tt>R</tt>'s | |
46 | * error channel, the program is ill-formed with no diagnostic required. | |
47 | * | |
48 | * @li Otherwise, <tt>execution::set_error(R, E)</tt> is ill-formed. | |
49 | */ | |
50 | inline constexpr unspecified set_error = unspecified; | |
51 | ||
52 | /// A type trait that determines whether a @c set_error expression is | |
53 | /// well-formed. | |
54 | /** | |
55 | * Class template @c can_set_error is a trait that is derived from | |
56 | * @c true_type if the expression <tt>execution::set_error(std::declval<R>(), | |
57 | * std::declval<E>())</tt> is well formed; otherwise @c false_type. | |
58 | */ | |
59 | template <typename R, typename E> | |
60 | struct can_set_error : | |
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_error_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_error_free; | |
77 | using boost::asio::traits::set_error_member; | |
78 | ||
79 | void set_error(); | |
80 | ||
81 | enum overload_type | |
82 | { | |
83 | call_member, | |
84 | call_free, | |
85 | ill_formed | |
86 | }; | |
87 | ||
1e59de90 | 88 | template <typename R, typename E, 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, typename E> | |
97 | struct call_traits<R, void(E), | |
98 | typename enable_if< | |
1e59de90 | 99 | set_error_member<R, E>::is_valid |
20effc67 TL |
100 | >::type> : |
101 | set_error_member<R, E> | |
102 | { | |
103 | BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); | |
104 | }; | |
105 | ||
106 | template <typename R, typename E> | |
107 | struct call_traits<R, void(E), | |
108 | typename enable_if< | |
1e59de90 TL |
109 | !set_error_member<R, E>::is_valid |
110 | >::type, | |
111 | typename enable_if< | |
112 | set_error_free<R, E>::is_valid | |
20effc67 TL |
113 | >::type> : |
114 | set_error_free<R, E> | |
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, typename E> | |
123 | BOOST_ASIO_CONSTEXPR typename enable_if< | |
124 | call_traits<R, void(E)>::overload == call_member, | |
125 | typename call_traits<R, void(E)>::result_type | |
126 | >::type | |
127 | operator()(R&& r, E&& e) const | |
128 | BOOST_ASIO_NOEXCEPT_IF(( | |
129 | call_traits<R, void(E)>::is_noexcept)) | |
130 | { | |
131 | return BOOST_ASIO_MOVE_CAST(R)(r).set_error(BOOST_ASIO_MOVE_CAST(E)(e)); | |
132 | } | |
133 | ||
134 | template <typename R, typename E> | |
135 | BOOST_ASIO_CONSTEXPR typename enable_if< | |
136 | call_traits<R, void(E)>::overload == call_free, | |
137 | typename call_traits<R, void(E)>::result_type | |
138 | >::type | |
139 | operator()(R&& r, E&& e) const | |
140 | BOOST_ASIO_NOEXCEPT_IF(( | |
141 | call_traits<R, void(E)>::is_noexcept)) | |
142 | { | |
143 | return set_error(BOOST_ASIO_MOVE_CAST(R)(r), BOOST_ASIO_MOVE_CAST(E)(e)); | |
144 | } | |
145 | #else // defined(BOOST_ASIO_HAS_MOVE) | |
146 | template <typename R, typename E> | |
147 | BOOST_ASIO_CONSTEXPR typename enable_if< | |
148 | call_traits<R&, void(const E&)>::overload == call_member, | |
149 | typename call_traits<R&, void(const E&)>::result_type | |
150 | >::type | |
151 | operator()(R& r, const E& e) const | |
152 | BOOST_ASIO_NOEXCEPT_IF(( | |
153 | call_traits<R&, void(const E&)>::is_noexcept)) | |
154 | { | |
155 | return r.set_error(e); | |
156 | } | |
157 | ||
158 | template <typename R, typename E> | |
159 | BOOST_ASIO_CONSTEXPR typename enable_if< | |
160 | call_traits<const R&, void(const E&)>::overload == call_member, | |
161 | typename call_traits<const R&, void(const E&)>::result_type | |
162 | >::type | |
163 | operator()(const R& r, const E& e) const | |
164 | BOOST_ASIO_NOEXCEPT_IF(( | |
165 | call_traits<const R&, void(const E&)>::is_noexcept)) | |
166 | { | |
167 | return r.set_error(e); | |
168 | } | |
169 | ||
170 | template <typename R, typename E> | |
171 | BOOST_ASIO_CONSTEXPR typename enable_if< | |
172 | call_traits<R&, void(const E&)>::overload == call_free, | |
173 | typename call_traits<R&, void(const E&)>::result_type | |
174 | >::type | |
175 | operator()(R& r, const E& e) const | |
176 | BOOST_ASIO_NOEXCEPT_IF(( | |
177 | call_traits<R&, void(const E&)>::is_noexcept)) | |
178 | { | |
179 | return set_error(r, e); | |
180 | } | |
181 | ||
182 | template <typename R, typename E> | |
183 | BOOST_ASIO_CONSTEXPR typename enable_if< | |
184 | call_traits<const R&, void(const E&)>::overload == call_free, | |
185 | typename call_traits<const R&, void(const E&)>::result_type | |
186 | >::type | |
187 | operator()(const R& r, const E& e) const | |
188 | BOOST_ASIO_NOEXCEPT_IF(( | |
189 | call_traits<const R&, void(const E&)>::is_noexcept)) | |
190 | { | |
191 | return set_error(r, e); | |
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_error_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_error_fn::impl& |
212 | set_error = boost_asio_execution_set_error_fn::static_instance<>::instance; | |
20effc67 TL |
213 | |
214 | } // namespace | |
215 | ||
216 | template <typename R, typename E> | |
217 | struct can_set_error : | |
218 | integral_constant<bool, | |
1e59de90 TL |
219 | boost_asio_execution_set_error_fn::call_traits<R, void(E)>::overload != |
220 | boost_asio_execution_set_error_fn::ill_formed> | |
20effc67 TL |
221 | { |
222 | }; | |
223 | ||
224 | #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) | |
225 | ||
226 | template <typename R, typename E> | |
227 | constexpr bool can_set_error_v = can_set_error<R, E>::value; | |
228 | ||
229 | #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) | |
230 | ||
231 | template <typename R, typename E> | |
232 | struct is_nothrow_set_error : | |
233 | integral_constant<bool, | |
1e59de90 | 234 | boost_asio_execution_set_error_fn::call_traits<R, void(E)>::is_noexcept> |
20effc67 TL |
235 | { |
236 | }; | |
237 | ||
238 | #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) | |
239 | ||
240 | template <typename R, typename E> | |
241 | constexpr bool is_nothrow_set_error_v | |
242 | = is_nothrow_set_error<R, E>::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_ERROR_HPP |