• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // execution/set_error.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_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 
71 namespace asio_execution_set_error_fn {
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 
88 template <typename R, typename E, typename = void>
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<
99     (
100       set_error_member<R, E>::is_valid
101     )
102   >::type> :
103   set_error_member<R, E>
104 {
105   BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);
106 };
107 
108 template <typename R, typename E>
109 struct call_traits<R, void(E),
110   typename enable_if<
111     (
112       !set_error_member<R, E>::is_valid
113       &&
114       set_error_free<R, E>::is_valid
115     )
116   >::type> :
117   set_error_free<R, E>
118 {
119   BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);
120 };
121 
122 struct impl
123 {
124 #if defined(BOOST_ASIO_HAS_MOVE)
125   template <typename R, typename E>
126   BOOST_ASIO_CONSTEXPR typename enable_if<
127     call_traits<R, void(E)>::overload == call_member,
128     typename call_traits<R, void(E)>::result_type
129   >::type
operator ()asio_execution_set_error_fn::impl130   operator()(R&& r, E&& e) const
131     BOOST_ASIO_NOEXCEPT_IF((
132       call_traits<R, void(E)>::is_noexcept))
133   {
134     return BOOST_ASIO_MOVE_CAST(R)(r).set_error(BOOST_ASIO_MOVE_CAST(E)(e));
135   }
136 
137   template <typename R, typename E>
138   BOOST_ASIO_CONSTEXPR typename enable_if<
139     call_traits<R, void(E)>::overload == call_free,
140     typename call_traits<R, void(E)>::result_type
141   >::type
operator ()asio_execution_set_error_fn::impl142   operator()(R&& r, E&& e) const
143     BOOST_ASIO_NOEXCEPT_IF((
144       call_traits<R, void(E)>::is_noexcept))
145   {
146     return set_error(BOOST_ASIO_MOVE_CAST(R)(r), BOOST_ASIO_MOVE_CAST(E)(e));
147   }
148 #else // defined(BOOST_ASIO_HAS_MOVE)
149   template <typename R, typename E>
150   BOOST_ASIO_CONSTEXPR typename enable_if<
151     call_traits<R&, void(const E&)>::overload == call_member,
152     typename call_traits<R&, void(const E&)>::result_type
153   >::type
154   operator()(R& r, const E& e) const
155     BOOST_ASIO_NOEXCEPT_IF((
156       call_traits<R&, void(const E&)>::is_noexcept))
157   {
158     return r.set_error(e);
159   }
160 
161   template <typename R, typename E>
162   BOOST_ASIO_CONSTEXPR typename enable_if<
163     call_traits<const R&, void(const E&)>::overload == call_member,
164     typename call_traits<const R&, void(const E&)>::result_type
165   >::type
166   operator()(const R& r, const E& e) const
167     BOOST_ASIO_NOEXCEPT_IF((
168       call_traits<const R&, void(const E&)>::is_noexcept))
169   {
170     return r.set_error(e);
171   }
172 
173   template <typename R, typename E>
174   BOOST_ASIO_CONSTEXPR typename enable_if<
175     call_traits<R&, void(const E&)>::overload == call_free,
176     typename call_traits<R&, void(const E&)>::result_type
177   >::type
178   operator()(R& r, const E& e) const
179     BOOST_ASIO_NOEXCEPT_IF((
180       call_traits<R&, void(const E&)>::is_noexcept))
181   {
182     return set_error(r, e);
183   }
184 
185   template <typename R, typename E>
186   BOOST_ASIO_CONSTEXPR typename enable_if<
187     call_traits<const R&, void(const E&)>::overload == call_free,
188     typename call_traits<const R&, void(const E&)>::result_type
189   >::type
190   operator()(const R& r, const E& e) const
191     BOOST_ASIO_NOEXCEPT_IF((
192       call_traits<const R&, void(const E&)>::is_noexcept))
193   {
194     return set_error(r, e);
195   }
196 #endif // defined(BOOST_ASIO_HAS_MOVE)
197 };
198 
199 template <typename T = impl>
200 struct static_instance
201 {
202   static const T instance;
203 };
204 
205 template <typename T>
206 const T static_instance<T>::instance = {};
207 
208 } // namespace asio_execution_set_error_fn
209 namespace boost {
210 namespace asio {
211 namespace execution {
212 namespace {
213 
214 static BOOST_ASIO_CONSTEXPR const asio_execution_set_error_fn::impl&
215   set_error = asio_execution_set_error_fn::static_instance<>::instance;
216 
217 } // namespace
218 
219 template <typename R, typename E>
220 struct can_set_error :
221   integral_constant<bool,
222     asio_execution_set_error_fn::call_traits<R, void(E)>::overload !=
223       asio_execution_set_error_fn::ill_formed>
224 {
225 };
226 
227 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
228 
229 template <typename R, typename E>
230 constexpr bool can_set_error_v = can_set_error<R, E>::value;
231 
232 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
233 
234 template <typename R, typename E>
235 struct is_nothrow_set_error :
236   integral_constant<bool,
237     asio_execution_set_error_fn::call_traits<R, void(E)>::is_noexcept>
238 {
239 };
240 
241 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
242 
243 template <typename R, typename E>
244 constexpr bool is_nothrow_set_error_v
245   = is_nothrow_set_error<R, E>::value;
246 
247 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
248 
249 } // namespace execution
250 } // namespace asio
251 } // namespace boost
252 
253 #endif // defined(GENERATING_DOCUMENTATION)
254 
255 #include <boost/asio/detail/pop_options.hpp>
256 
257 #endif // BOOST_ASIO_EXECUTION_SET_ERROR_HPP
258