]>
Commit | Line | Data |
---|---|---|
0646d8a3 BK |
1 | // <system_error> -*- C++ -*- |
2 | ||
e9599233 | 3 | // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. |
0646d8a3 BK |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free | |
6 | // software; you can redistribute it and/or modify it under the | |
7 | // terms of the GNU General Public License as published by the | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
0646d8a3 BK |
9 | // any later version. |
10 | ||
11 | // This library is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | ||
748086b7 JJ |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version | |
18 | // 3.1, as published by the Free Software Foundation. | |
19 | ||
20 | // You should have received a copy of the GNU General Public License and | |
21 | // a copy of the GCC Runtime Library Exception along with this program; | |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | // <http://www.gnu.org/licenses/>. | |
0646d8a3 | 24 | |
f910786b | 25 | /** @file include/system_error |
0646d8a3 BK |
26 | * This is a Standard C++ Library header. |
27 | */ | |
28 | ||
29 | #ifndef _GLIBCXX_SYSTEM_ERROR | |
30 | #define _GLIBCXX_SYSTEM_ERROR 1 | |
31 | ||
32 | #pragma GCC system_header | |
33 | ||
734f5023 | 34 | #if __cplusplus < 201103L |
ab65a4c7 | 35 | # include <bits/c++0x_warning.h> |
57317d2a | 36 | #else |
0646d8a3 BK |
37 | |
38 | #include <bits/c++config.h> | |
e4bf5dfc | 39 | #include <bits/error_constants.h> |
0646d8a3 BK |
40 | #include <iosfwd> |
41 | #include <stdexcept> | |
42 | ||
12ffa228 BK |
43 | namespace std _GLIBCXX_VISIBILITY(default) |
44 | { | |
45 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
0646d8a3 | 46 | |
0646d8a3 | 47 | class error_code; |
70593ad2 | 48 | class error_condition; |
0646d8a3 | 49 | class error_category; |
70593ad2 BK |
50 | class system_error; |
51 | ||
52 | /// is_error_code_enum | |
c9faf465 | 53 | template<typename _Tp> |
70593ad2 BK |
54 | struct is_error_code_enum : public false_type { }; |
55 | ||
70593ad2 | 56 | /// is_error_condition_enum |
c9faf465 | 57 | template<typename _Tp> |
70593ad2 BK |
58 | struct is_error_condition_enum : public false_type { }; |
59 | ||
60 | template<> | |
92010a79 | 61 | struct is_error_condition_enum<errc> |
70593ad2 | 62 | : public true_type { }; |
0646d8a3 | 63 | |
0646d8a3 | 64 | |
939759fc | 65 | /// error_category |
92010a79 | 66 | class error_category |
0646d8a3 | 67 | { |
92010a79 | 68 | protected: |
cd88bb8c | 69 | error_category() noexcept; |
92010a79 CF |
70 | |
71 | public: | |
cd88bb8c | 72 | virtual ~error_category() noexcept; |
92010a79 CF |
73 | |
74 | error_category(const error_category&) = delete; | |
75 | error_category& operator=(const error_category&) = delete; | |
0646d8a3 | 76 | |
70593ad2 | 77 | virtual const char* |
cd88bb8c | 78 | name() const noexcept = 0; |
70593ad2 BK |
79 | |
80 | virtual string | |
81 | message(int) const = 0; | |
82 | ||
83 | virtual error_condition | |
cd88bb8c | 84 | default_error_condition(int __i) const noexcept; |
70593ad2 BK |
85 | |
86 | virtual bool | |
cd88bb8c | 87 | equivalent(int __i, const error_condition& __cond) const noexcept; |
70593ad2 BK |
88 | |
89 | virtual bool | |
cd88bb8c | 90 | equivalent(const error_code& __code, int __i) const noexcept; |
70593ad2 BK |
91 | |
92 | bool | |
cd88bb8c | 93 | operator<(const error_category& __other) const noexcept |
70593ad2 BK |
94 | { return less<const error_category*>()(this, &__other); } |
95 | ||
0646d8a3 | 96 | bool |
cd88bb8c | 97 | operator==(const error_category& __other) const noexcept |
0646d8a3 BK |
98 | { return this == &__other; } |
99 | ||
100 | bool | |
cd88bb8c | 101 | operator!=(const error_category& __other) const noexcept |
0646d8a3 | 102 | { return this != &__other; } |
0646d8a3 BK |
103 | }; |
104 | ||
92010a79 | 105 | // DR 890. |
cd88bb8c PC |
106 | _GLIBCXX_CONST const error_category& system_category() noexcept; |
107 | _GLIBCXX_CONST const error_category& generic_category() noexcept; | |
70593ad2 | 108 | |
cd88bb8c | 109 | error_code make_error_code(errc) noexcept; |
bb81f9a0 | 110 | |
5c8db18a PC |
111 | template<typename _Tp> |
112 | struct hash; | |
113 | ||
939759fc | 114 | /// error_code |
70593ad2 | 115 | // Implementation-specific error identification |
0646d8a3 BK |
116 | struct error_code |
117 | { | |
cd88bb8c | 118 | error_code() noexcept |
bb81f9a0 | 119 | : _M_value(0), _M_cat(&system_category()) { } |
0646d8a3 | 120 | |
cd88bb8c | 121 | error_code(int __v, const error_category& __cat) noexcept |
0646d8a3 BK |
122 | : _M_value(__v), _M_cat(&__cat) { } |
123 | ||
cd88bb8c PC |
124 | template<typename _ErrorCodeEnum, typename = typename |
125 | enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type> | |
126 | error_code(_ErrorCodeEnum __e) noexcept | |
bb81f9a0 | 127 | { *this = make_error_code(__e); } |
0646d8a3 BK |
128 | |
129 | void | |
cd88bb8c | 130 | assign(int __v, const error_category& __cat) noexcept |
0646d8a3 BK |
131 | { |
132 | _M_value = __v; | |
133 | _M_cat = &__cat; | |
134 | } | |
135 | ||
136 | void | |
cd88bb8c | 137 | clear() noexcept |
9b3003d5 | 138 | { assign(0, system_category()); } |
70593ad2 | 139 | |
4661c8fd | 140 | // DR 804. |
70593ad2 | 141 | template<typename _ErrorCodeEnum> |
4661c8fd PC |
142 | typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value, |
143 | error_code&>::type | |
cd88bb8c | 144 | operator=(_ErrorCodeEnum __e) noexcept |
bb81f9a0 | 145 | { return *this = make_error_code(__e); } |
0646d8a3 BK |
146 | |
147 | int | |
cd88bb8c | 148 | value() const noexcept { return _M_value; } |
0646d8a3 BK |
149 | |
150 | const error_category& | |
cd88bb8c | 151 | category() const noexcept { return *_M_cat; } |
0646d8a3 | 152 | |
70593ad2 | 153 | error_condition |
cd88bb8c | 154 | default_error_condition() const noexcept; |
70593ad2 BK |
155 | |
156 | string | |
157 | message() const | |
158 | { return category().message(value()); } | |
0646d8a3 | 159 | |
cd88bb8c | 160 | explicit operator bool() const noexcept |
d29d4507 | 161 | { return _M_value != 0 ? true : false; } |
0646d8a3 | 162 | |
4661c8fd | 163 | // DR 804. |
0646d8a3 | 164 | private: |
5c8db18a PC |
165 | friend class hash<error_code>; |
166 | ||
0646d8a3 BK |
167 | int _M_value; |
168 | const error_category* _M_cat; | |
169 | }; | |
170 | ||
92010a79 CF |
171 | // 19.4.2.6 non-member functions |
172 | inline error_code | |
cd88bb8c | 173 | make_error_code(errc __e) noexcept |
9b3003d5 | 174 | { return error_code(static_cast<int>(__e), generic_category()); } |
92010a79 | 175 | |
4661c8fd | 176 | inline bool |
cd88bb8c | 177 | operator<(const error_code& __lhs, const error_code& __rhs) noexcept |
4661c8fd PC |
178 | { |
179 | return (__lhs.category() < __rhs.category() | |
180 | || (__lhs.category() == __rhs.category() | |
181 | && __lhs.value() < __rhs.value())); | |
182 | } | |
70593ad2 | 183 | |
4661c8fd PC |
184 | template<typename _CharT, typename _Traits> |
185 | basic_ostream<_CharT, _Traits>& | |
186 | operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e) | |
187 | { return (__os << __e.category().name() << ':' << __e.value()); } | |
70593ad2 | 188 | |
cd88bb8c | 189 | error_condition make_error_condition(errc) noexcept; |
70593ad2 BK |
190 | |
191 | /// error_condition | |
192 | // Portable error identification | |
193 | struct error_condition | |
194 | { | |
cd88bb8c | 195 | error_condition() noexcept |
bb81f9a0 | 196 | : _M_value(0), _M_cat(&generic_category()) { } |
70593ad2 | 197 | |
cd88bb8c | 198 | error_condition(int __v, const error_category& __cat) noexcept |
4661c8fd | 199 | : _M_value(__v), _M_cat(&__cat) { } |
70593ad2 | 200 | |
cd88bb8c PC |
201 | template<typename _ErrorConditionEnum, typename = typename |
202 | enable_if<is_error_condition_enum<_ErrorConditionEnum>::value>::type> | |
203 | error_condition(_ErrorConditionEnum __e) noexcept | |
bb81f9a0 | 204 | { *this = make_error_condition(__e); } |
70593ad2 | 205 | |
4661c8fd | 206 | void |
cd88bb8c | 207 | assign(int __v, const error_category& __cat) noexcept |
4661c8fd PC |
208 | { |
209 | _M_value = __v; | |
210 | _M_cat = &__cat; | |
211 | } | |
70593ad2 | 212 | |
4661c8fd PC |
213 | // DR 804. |
214 | template<typename _ErrorConditionEnum> | |
215 | typename enable_if<is_error_condition_enum | |
216 | <_ErrorConditionEnum>::value, error_condition&>::type | |
cd88bb8c | 217 | operator=(_ErrorConditionEnum __e) noexcept |
bb81f9a0 | 218 | { return *this = make_error_condition(__e); } |
70593ad2 BK |
219 | |
220 | void | |
cd88bb8c | 221 | clear() noexcept |
9b3003d5 | 222 | { assign(0, generic_category()); } |
70593ad2 BK |
223 | |
224 | // 19.4.3.4 observers | |
cd88bb8c PC |
225 | int |
226 | value() const noexcept { return _M_value; } | |
70593ad2 | 227 | |
4661c8fd | 228 | const error_category& |
cd88bb8c | 229 | category() const noexcept { return *_M_cat; } |
70593ad2 BK |
230 | |
231 | string | |
232 | message() const | |
233 | { return category().message(value()); } | |
234 | ||
cd88bb8c | 235 | explicit operator bool() const noexcept |
d29d4507 | 236 | { return _M_value != 0 ? true : false; } |
70593ad2 | 237 | |
4661c8fd | 238 | // DR 804. |
70593ad2 BK |
239 | private: |
240 | int _M_value; | |
4661c8fd | 241 | const error_category* _M_cat; |
70593ad2 BK |
242 | }; |
243 | ||
92010a79 CF |
244 | // 19.4.3.6 non-member functions |
245 | inline error_condition | |
cd88bb8c | 246 | make_error_condition(errc __e) noexcept |
9b3003d5 | 247 | { return error_condition(static_cast<int>(__e), generic_category()); } |
92010a79 | 248 | |
70593ad2 | 249 | inline bool |
cd88bb8c PC |
250 | operator<(const error_condition& __lhs, |
251 | const error_condition& __rhs) noexcept | |
4661c8fd PC |
252 | { |
253 | return (__lhs.category() < __rhs.category() | |
254 | || (__lhs.category() == __rhs.category() | |
255 | && __lhs.value() < __rhs.value())); | |
256 | } | |
257 | ||
70593ad2 | 258 | // 19.4.4 Comparison operators |
4661c8fd | 259 | inline bool |
cd88bb8c | 260 | operator==(const error_code& __lhs, const error_code& __rhs) noexcept |
4661c8fd PC |
261 | { return (__lhs.category() == __rhs.category() |
262 | && __lhs.value() == __rhs.value()); } | |
70593ad2 | 263 | |
4661c8fd | 264 | inline bool |
cd88bb8c | 265 | operator==(const error_code& __lhs, const error_condition& __rhs) noexcept |
70593ad2 | 266 | { |
4661c8fd PC |
267 | return (__lhs.category().equivalent(__lhs.value(), __rhs) |
268 | || __rhs.category().equivalent(__lhs, __rhs.value())); | |
70593ad2 BK |
269 | } |
270 | ||
4661c8fd | 271 | inline bool |
cd88bb8c | 272 | operator==(const error_condition& __lhs, const error_code& __rhs) noexcept |
70593ad2 | 273 | { |
4661c8fd PC |
274 | return (__rhs.category().equivalent(__rhs.value(), __lhs) |
275 | || __lhs.category().equivalent(__rhs, __lhs.value())); | |
70593ad2 BK |
276 | } |
277 | ||
4661c8fd | 278 | inline bool |
cd88bb8c PC |
279 | operator==(const error_condition& __lhs, |
280 | const error_condition& __rhs) noexcept | |
4661c8fd PC |
281 | { |
282 | return (__lhs.category() == __rhs.category() | |
283 | && __lhs.value() == __rhs.value()); | |
284 | } | |
70593ad2 | 285 | |
4661c8fd | 286 | inline bool |
cd88bb8c | 287 | operator!=(const error_code& __lhs, const error_code& __rhs) noexcept |
4661c8fd | 288 | { return !(__lhs == __rhs); } |
70593ad2 | 289 | |
4661c8fd | 290 | inline bool |
cd88bb8c | 291 | operator!=(const error_code& __lhs, const error_condition& __rhs) noexcept |
4661c8fd | 292 | { return !(__lhs == __rhs); } |
70593ad2 | 293 | |
4661c8fd | 294 | inline bool |
cd88bb8c | 295 | operator!=(const error_condition& __lhs, const error_code& __rhs) noexcept |
4661c8fd PC |
296 | { return !(__lhs == __rhs); } |
297 | ||
298 | inline bool | |
cd88bb8c PC |
299 | operator!=(const error_condition& __lhs, |
300 | const error_condition& __rhs) noexcept | |
4661c8fd | 301 | { return !(__lhs == __rhs); } |
70593ad2 | 302 | |
70593ad2 | 303 | |
5b9daa7e BK |
304 | /** |
305 | * @brief Thrown to indicate error code of underlying system. | |
306 | * | |
307 | * @ingroup exceptions | |
308 | */ | |
0646d8a3 BK |
309 | class system_error : public std::runtime_error |
310 | { | |
311 | private: | |
312 | error_code _M_code; | |
313 | ||
314 | public: | |
4514bed6 | 315 | system_error(error_code __ec = error_code()) |
b5fbd147 | 316 | : runtime_error(__ec.message()), _M_code(__ec) { } |
4514bed6 | 317 | |
70593ad2 | 318 | system_error(error_code __ec, const string& __what) |
b5fbd147 PC |
319 | : runtime_error(__what + ": " + __ec.message()), _M_code(__ec) { } |
320 | ||
92010a79 CF |
321 | /* |
322 | * TODO: Add const char* ctors to all exceptions. | |
323 | * | |
324 | * system_error(error_code __ec, const char* __what) | |
b5fbd147 | 325 | * : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { } |
92010a79 CF |
326 | * |
327 | * system_error(int __v, const error_category& __ecat, const char* __what) | |
b5fbd147 PC |
328 | * : runtime_error(__what + (": " + __ec.message())), |
329 | * _M_code(error_code(__v, __ecat)) { } | |
92010a79 | 330 | */ |
0646d8a3 | 331 | |
70593ad2 | 332 | system_error(int __v, const error_category& __ecat) |
b5fbd147 PC |
333 | : runtime_error(error_code(__v, __ecat).message()), |
334 | _M_code(__v, __ecat) { } | |
70593ad2 BK |
335 | |
336 | system_error(int __v, const error_category& __ecat, const string& __what) | |
b5fbd147 PC |
337 | : runtime_error(__what + ": " + error_code(__v, __ecat).message()), |
338 | _M_code(__v, __ecat) { } | |
0646d8a3 | 339 | |
8535715d | 340 | virtual ~system_error() noexcept; |
0646d8a3 BK |
341 | |
342 | const error_code& | |
cd88bb8c | 343 | code() const noexcept { return _M_code; } |
0646d8a3 BK |
344 | }; |
345 | ||
12ffa228 BK |
346 | _GLIBCXX_END_NAMESPACE_VERSION |
347 | } // namespace | |
0646d8a3 | 348 | |
15d81a3c PC |
349 | #ifndef _GLIBCXX_COMPATIBILITY_CXX0X |
350 | ||
351 | #include <bits/functional_hash.h> | |
352 | ||
12ffa228 BK |
353 | namespace std _GLIBCXX_VISIBILITY(default) |
354 | { | |
355 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
15d81a3c PC |
356 | |
357 | // DR 1182. | |
358 | /// std::hash specialization for error_code. | |
359 | template<> | |
360 | struct hash<error_code> | |
5d64ee19 | 361 | : public __hash_base<size_t, error_code> |
15d81a3c PC |
362 | { |
363 | size_t | |
72f1c34b | 364 | operator()(const error_code& __e) const noexcept |
15d81a3c | 365 | { |
e7f72940 MA |
366 | const size_t __tmp = std::_Hash_impl::hash(__e._M_value); |
367 | return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp); | |
15d81a3c PC |
368 | } |
369 | }; | |
370 | ||
12ffa228 BK |
371 | _GLIBCXX_END_NAMESPACE_VERSION |
372 | } // namespace | |
15d81a3c PC |
373 | |
374 | #endif // _GLIBCXX_COMPATIBILITY_CXX0X | |
375 | ||
734f5023 | 376 | #endif // C++11 |
57317d2a PC |
377 | |
378 | #endif // _GLIBCXX_SYSTEM_ERROR |