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
6// Copyright Peter Dimov 2017-2021
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>
16#include <boost/system/detail/is_same.hpp>
17#include <boost/system/detail/errc.hpp>
18#include <boost/system/detail/append_int.hpp>
19#include <boost/system/is_error_condition_enum.hpp>
20#include <boost/system/detail/config.hpp>
21#include <boost/config.hpp>
22
23namespace boost
24{
25
26namespace system
27{
28
29// class error_condition
30
31// error_conditions are portable, error_codes are system or library specific
32
33namespace detail
34{
35
36struct 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
44class error_condition
45{
46private:
47
48 int val_;
49 error_category const * cat_;
50
51private:
52
53 boost::ulong_long_type cat_id() const noexcept
54 {
55 return cat_? cat_->id_: detail::generic_category_id;
56 }
57
58public:
59
60 // constructors:
61
62 BOOST_SYSTEM_CONSTEXPR error_condition() noexcept:
63 val_( 0 ), cat_( 0 )
64 {
65 }
66
67 BOOST_SYSTEM_CONSTEXPR error_condition( int val, const error_category & cat ) noexcept:
68 val_( val ), cat_( &cat )
69 {
70 }
71
72 BOOST_SYSTEM_CONSTEXPR explicit error_condition( boost::system::detail::generic_value_tag vt ) noexcept:
73 val_( vt.value ), cat_( 0 )
74 {
75 }
76
77 template<class ErrorConditionEnum> BOOST_SYSTEM_CONSTEXPR error_condition( ErrorConditionEnum e,
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) noexcept
81 {
82 *this = make_error_condition( e );
83 }
84
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) noexcept:
87 val_( e ), cat_( 0 )
88 {
89 }
90
91 // modifiers:
92
93 BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) 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 ) noexcept
102 {
103 *this = error_condition( val );
104 return *this;
105 }
106
107 BOOST_SYSTEM_CONSTEXPR void clear() noexcept
108 {
109 val_ = 0;
110 cat_ = 0;
111 }
112
113 // observers:
114
115 BOOST_SYSTEM_CONSTEXPR int value() const noexcept
116 {
117 return val_;
118 }
119
120 BOOST_SYSTEM_CONSTEXPR const error_category & category() const noexcept
121 {
122 return cat_? *cat_: generic_category();
123 }
124
125 std::string message() const
126 {
127 if( cat_ )
128 {
129 return cat_->message( ev: value() );
130 }
131 else
132 {
133 return detail::generic_error_category_message( ev: value() );
134 }
135 }
136
137 char const * message( char * buffer, std::size_t len ) const noexcept
138 {
139 if( cat_ )
140 {
141 return cat_->message( ev: value(), buffer, len );
142 }
143 else
144 {
145 return detail::generic_error_category_message( ev: value(), buffer, len );
146 }
147 }
148
149 BOOST_SYSTEM_CONSTEXPR bool failed() const noexcept
150 {
151 if( cat_ )
152 {
153 return detail::failed_impl( ev: val_, cat: *cat_ );
154 }
155 else
156 {
157 return val_ != 0;
158 }
159 }
160
161 BOOST_SYSTEM_CONSTEXPR explicit operator bool() const noexcept // true if error
162 {
163 return failed();
164 }
165
166 // relationals:
167 // the more symmetrical non-member syntax allows enum
168 // conversions work for both rhs and lhs.
169
170 BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_condition & lhs, const error_condition & rhs ) noexcept
171 {
172 if( lhs.val_ != rhs.val_ )
173 {
174 return false;
175 }
176 else if( lhs.cat_ == 0 )
177 {
178 return rhs.cat_id() == detail::generic_category_id;
179 }
180 else if( rhs.cat_ == 0 )
181 {
182 return lhs.cat_id() == detail::generic_category_id;
183 }
184 else
185 {
186 return *lhs.cat_ == *rhs.cat_;
187 }
188 }
189
190 BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_condition & lhs, const error_condition & rhs ) noexcept
191 {
192 error_category const& lcat = lhs.category();
193 error_category const& rcat = rhs.category();
194 return lcat < rcat || ( lcat == rcat && lhs.val_ < rhs.val_ );
195 }
196
197 BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( const error_condition & lhs, const error_condition & rhs ) noexcept
198 {
199 return !( lhs == rhs );
200 }
201
202 operator std::error_condition () const
203 {
204// This condition must be the same as the one in error_category_impl.hpp
205#if defined(BOOST_SYSTEM_AVOID_STD_GENERIC_CATEGORY)
206
207 return std::error_condition( value(), category() );
208
209#else
210
211 if( cat_ )
212 {
213 return std::error_condition( val_, *cat_ );
214 }
215 else
216 {
217 return std::error_condition( val_, std::generic_category() );
218 }
219
220#endif
221 }
222
223 inline friend bool operator==( std::error_code const & lhs, error_condition const & rhs ) noexcept
224 {
225 return lhs == static_cast< std::error_condition >( rhs );
226 }
227
228 inline friend bool operator==( error_condition const & lhs, std::error_code const & rhs ) noexcept
229 {
230 return static_cast< std::error_condition >( lhs ) == rhs;
231 }
232
233 inline friend bool operator!=( std::error_code const & lhs, error_condition const & rhs ) noexcept
234 {
235 return !( lhs == rhs );
236 }
237
238 inline friend bool operator!=( error_condition const & lhs, std::error_code const & rhs ) noexcept
239 {
240 return !( lhs == rhs );
241 }
242
243 //
244
245 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
246 BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( error_condition const & lhs, E rhs ) noexcept
247 {
248 return lhs == make_error_condition( rhs );
249 }
250
251 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
252 BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( E lhs, error_condition const & rhs ) noexcept
253 {
254 return make_error_condition( lhs ) == rhs;
255 }
256
257 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
258 BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( error_condition const & lhs, E rhs ) noexcept
259 {
260 return !( lhs == rhs );
261 }
262
263 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
264 BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( E lhs, error_condition const & rhs ) noexcept
265 {
266 return !( lhs == rhs );
267 }
268
269 //
270
271 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
272 inline friend bool operator==( error_condition const & lhs, E rhs ) noexcept
273 {
274 return lhs == make_error_code( rhs );
275 }
276
277 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
278 inline friend bool operator==( E lhs, error_condition const & rhs ) noexcept
279 {
280 return make_error_code( lhs ) == rhs;
281 }
282
283 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
284 inline friend bool operator!=( error_condition const & lhs, E rhs ) noexcept
285 {
286 return !( lhs == rhs );
287 }
288
289 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
290 inline friend bool operator!=( E lhs, error_condition const & rhs ) noexcept
291 {
292 return !( lhs == rhs );
293 }
294
295 std::string to_string() const
296 {
297 std::string r( "cond:" );
298
299 if( cat_ )
300 {
301 r += cat_->name();
302 }
303 else
304 {
305 r += "generic";
306 }
307
308 detail::append_int( s&: r, v: value() );
309
310 return r;
311 }
312
313 template<class Ch, class Tr>
314 inline friend std::basic_ostream<Ch, Tr>&
315 operator<< (std::basic_ostream<Ch, Tr>& os, error_condition const & en)
316 {
317 os << en.to_string();
318 return os;
319 }
320};
321
322} // namespace system
323
324} // namespace boost
325
326#endif // #ifndef BOOST_SYSTEM_DETAIL_ERROR_CONDITION_HPP_INCLUDED
327

source code of boost/libs/system/include/boost/system/detail/error_condition.hpp