]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
1 | #ifndef BOOST_SYSTEM_DETAIL_ERROR_CONDITION_HPP_INCLUDED |
2 | #define BOOST_SYSTEM_DETAIL_ERROR_CONDITION_HPP_INCLUDED | |
3 | ||
4 | // Copyright Beman Dawes 2006, 2007 | |
5 | // Copyright Christoper Kohlhoff 2007 | |
1e59de90 | 6 | // Copyright Peter Dimov 2017-2021 |
20effc67 TL |
7 | // |
8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
10 | // | |
11 | // See library home page at http://www.boost.org/libs/system | |
12 | ||
13 | #include <boost/system/detail/error_category.hpp> | |
14 | #include <boost/system/detail/generic_category.hpp> | |
15 | #include <boost/system/detail/enable_if.hpp> | |
1e59de90 TL |
16 | #include <boost/system/detail/is_same.hpp> |
17 | #include <boost/system/detail/errc.hpp> | |
18 | #include <boost/system/detail/append_int.hpp> | |
20effc67 TL |
19 | #include <boost/system/is_error_condition_enum.hpp> |
20 | #include <boost/system/detail/config.hpp> | |
21 | #include <boost/config.hpp> | |
22 | ||
23 | namespace boost | |
24 | { | |
25 | ||
26 | namespace system | |
27 | { | |
28 | ||
29 | // class error_condition | |
30 | ||
31 | // error_conditions are portable, error_codes are system or library specific | |
32 | ||
1e59de90 TL |
33 | namespace detail |
34 | { | |
35 | ||
36 | struct generic_value_tag | |
37 | { | |
38 | int value; | |
39 | BOOST_SYSTEM_CONSTEXPR explicit generic_value_tag( int v ): value( v ) {} | |
40 | }; | |
41 | ||
42 | } // namespace detail | |
43 | ||
20effc67 TL |
44 | class error_condition |
45 | { | |
46 | private: | |
47 | ||
48 | int val_; | |
49 | error_category const * cat_; | |
50 | ||
1e59de90 TL |
51 | private: |
52 | ||
53 | boost::ulong_long_type cat_id() const BOOST_NOEXCEPT | |
54 | { | |
55 | return cat_? cat_->id_: detail::generic_category_id; | |
56 | } | |
57 | ||
20effc67 TL |
58 | public: |
59 | ||
60 | // constructors: | |
61 | ||
62 | BOOST_SYSTEM_CONSTEXPR error_condition() BOOST_NOEXCEPT: | |
1e59de90 | 63 | val_( 0 ), cat_( 0 ) |
20effc67 TL |
64 | { |
65 | } | |
66 | ||
67 | BOOST_SYSTEM_CONSTEXPR error_condition( int val, const error_category & cat ) BOOST_NOEXCEPT: | |
68 | val_( val ), cat_( &cat ) | |
69 | { | |
70 | } | |
71 | ||
1e59de90 TL |
72 | BOOST_SYSTEM_CONSTEXPR explicit error_condition( boost::system::detail::generic_value_tag vt ) BOOST_NOEXCEPT: |
73 | val_( vt.value ), cat_( 0 ) | |
74 | { | |
75 | } | |
76 | ||
20effc67 | 77 | template<class ErrorConditionEnum> BOOST_SYSTEM_CONSTEXPR error_condition( ErrorConditionEnum e, |
1e59de90 TL |
78 | typename detail::enable_if< |
79 | is_error_condition_enum<ErrorConditionEnum>::value && !boost::system::detail::is_same<ErrorConditionEnum, errc::errc_t>::value | |
80 | >::type* = 0) BOOST_NOEXCEPT | |
20effc67 TL |
81 | { |
82 | *this = make_error_condition( e ); | |
83 | } | |
84 | ||
1e59de90 TL |
85 | template<class ErrorConditionEnum> BOOST_SYSTEM_CONSTEXPR error_condition( ErrorConditionEnum e, |
86 | typename detail::enable_if<boost::system::detail::is_same<ErrorConditionEnum, errc::errc_t>::value>::type* = 0) BOOST_NOEXCEPT: | |
87 | val_( e ), cat_( 0 ) | |
88 | { | |
89 | } | |
90 | ||
20effc67 TL |
91 | // modifiers: |
92 | ||
93 | BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT | |
94 | { | |
95 | val_ = val; | |
96 | cat_ = &cat; | |
97 | } | |
98 | ||
99 | template<typename ErrorConditionEnum> | |
100 | BOOST_SYSTEM_CONSTEXPR typename detail::enable_if<is_error_condition_enum<ErrorConditionEnum>::value, error_condition>::type & | |
101 | operator=( ErrorConditionEnum val ) BOOST_NOEXCEPT | |
102 | { | |
1e59de90 | 103 | *this = error_condition( val ); |
20effc67 TL |
104 | return *this; |
105 | } | |
106 | ||
107 | BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT | |
108 | { | |
109 | val_ = 0; | |
1e59de90 | 110 | cat_ = 0; |
20effc67 TL |
111 | } |
112 | ||
113 | // observers: | |
114 | ||
115 | BOOST_SYSTEM_CONSTEXPR int value() const BOOST_NOEXCEPT | |
116 | { | |
117 | return val_; | |
118 | } | |
119 | ||
120 | BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_NOEXCEPT | |
121 | { | |
1e59de90 | 122 | return cat_? *cat_: generic_category(); |
20effc67 TL |
123 | } |
124 | ||
125 | std::string message() const | |
126 | { | |
1e59de90 TL |
127 | if( cat_ ) |
128 | { | |
129 | return cat_->message( value() ); | |
130 | } | |
131 | else | |
132 | { | |
133 | return detail::generic_error_category_message( value() ); | |
134 | } | |
20effc67 TL |
135 | } |
136 | ||
1e59de90 | 137 | char const * message( char * buffer, std::size_t len ) const BOOST_NOEXCEPT |
20effc67 | 138 | { |
1e59de90 TL |
139 | if( cat_ ) |
140 | { | |
141 | return cat_->message( value(), buffer, len ); | |
142 | } | |
143 | else | |
144 | { | |
145 | return detail::generic_error_category_message( value(), buffer, len ); | |
146 | } | |
20effc67 TL |
147 | } |
148 | ||
1e59de90 | 149 | BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT |
20effc67 | 150 | { |
1e59de90 TL |
151 | if( cat_ ) |
152 | { | |
153 | return detail::failed_impl( val_, *cat_ ); | |
154 | } | |
155 | else | |
156 | { | |
157 | return val_ != 0; | |
158 | } | |
20effc67 TL |
159 | } |
160 | ||
161 | #if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) | |
162 | ||
163 | BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error | |
164 | { | |
1e59de90 | 165 | return failed(); |
20effc67 TL |
166 | } |
167 | ||
168 | #else | |
169 | ||
170 | typedef void (*unspecified_bool_type)(); | |
171 | static void unspecified_bool_true() {} | |
172 | ||
173 | BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error | |
174 | { | |
1e59de90 | 175 | return failed()? unspecified_bool_true: 0; |
20effc67 TL |
176 | } |
177 | ||
178 | BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error | |
179 | { | |
1e59de90 | 180 | return !failed(); |
20effc67 TL |
181 | } |
182 | ||
183 | #endif | |
184 | ||
185 | // relationals: | |
186 | // the more symmetrical non-member syntax allows enum | |
187 | // conversions work for both rhs and lhs. | |
188 | ||
189 | BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT | |
190 | { | |
1e59de90 TL |
191 | if( lhs.val_ != rhs.val_ ) |
192 | { | |
193 | return false; | |
194 | } | |
195 | else if( lhs.cat_ == 0 ) | |
196 | { | |
197 | return rhs.cat_id() == detail::generic_category_id; | |
198 | } | |
199 | else if( rhs.cat_ == 0 ) | |
200 | { | |
201 | return lhs.cat_id() == detail::generic_category_id; | |
202 | } | |
203 | else | |
204 | { | |
205 | return *lhs.cat_ == *rhs.cat_; | |
206 | } | |
20effc67 TL |
207 | } |
208 | ||
209 | BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT | |
210 | { | |
1e59de90 TL |
211 | error_category const& lcat = lhs.category(); |
212 | error_category const& rcat = rhs.category(); | |
213 | return lcat < rcat || ( lcat == rcat && lhs.val_ < rhs.val_ ); | |
214 | } | |
215 | ||
216 | BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT | |
217 | { | |
218 | return !( lhs == rhs ); | |
20effc67 TL |
219 | } |
220 | ||
221 | #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) | |
222 | ||
223 | operator std::error_condition () const | |
224 | { | |
1e59de90 TL |
225 | // This condition must be the same as the one in error_category_impl.hpp |
226 | #if defined(BOOST_SYSTEM_AVOID_STD_GENERIC_CATEGORY) | |
227 | ||
20effc67 | 228 | return std::error_condition( value(), category() ); |
1e59de90 TL |
229 | |
230 | #else | |
231 | ||
232 | if( cat_ ) | |
233 | { | |
234 | return std::error_condition( val_, *cat_ ); | |
235 | } | |
236 | else | |
237 | { | |
238 | return std::error_condition( val_, std::generic_category() ); | |
239 | } | |
240 | ||
241 | #endif | |
242 | } | |
243 | ||
244 | inline friend bool operator==( std::error_code const & lhs, error_condition const & rhs ) BOOST_NOEXCEPT | |
245 | { | |
246 | return lhs == static_cast< std::error_condition >( rhs ); | |
247 | } | |
248 | ||
249 | inline friend bool operator==( error_condition const & lhs, std::error_code const & rhs ) BOOST_NOEXCEPT | |
250 | { | |
251 | return static_cast< std::error_condition >( lhs ) == rhs; | |
252 | } | |
253 | ||
254 | inline friend bool operator!=( std::error_code const & lhs, error_condition const & rhs ) BOOST_NOEXCEPT | |
255 | { | |
256 | return !( lhs == rhs ); | |
257 | } | |
258 | ||
259 | inline friend bool operator!=( error_condition const & lhs, std::error_code const & rhs ) BOOST_NOEXCEPT | |
260 | { | |
261 | return !( lhs == rhs ); | |
20effc67 TL |
262 | } |
263 | ||
264 | #endif | |
20effc67 | 265 | |
1e59de90 TL |
266 | std::string to_string() const |
267 | { | |
268 | std::string r( "cond:" ); | |
269 | ||
270 | if( cat_ ) | |
271 | { | |
272 | r += cat_->name(); | |
273 | } | |
274 | else | |
275 | { | |
276 | r += "generic"; | |
277 | } | |
278 | ||
279 | detail::append_int( r, value() ); | |
280 | ||
281 | return r; | |
282 | } | |
283 | ||
284 | template<class Ch, class Tr> | |
285 | inline friend std::basic_ostream<Ch, Tr>& | |
286 | operator<< (std::basic_ostream<Ch, Tr>& os, error_condition const & en) | |
287 | { | |
288 | os << en.to_string(); | |
289 | return os; | |
290 | } | |
291 | }; | |
20effc67 TL |
292 | |
293 | } // namespace system | |
294 | ||
295 | } // namespace boost | |
296 | ||
297 | #endif // #ifndef BOOST_SYSTEM_DETAIL_ERROR_CONDITION_HPP_INCLUDED |