1// <system_error> -*- C++ -*- 
2 
3// Copyright (C) 2007-2019 Free Software Foundation, Inc. 
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 
8// Free Software Foundation; either version 3, or (at your option) 
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 
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/>. 
24 
25/** @file include/system_error 
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 
34#if __cplusplus < 201103L 
35# include <bits/c++0x_warning.h> 
36#else 
37 
38#include <bits/c++config.h> 
39#include <bits/error_constants.h> 
40#include <iosfwd> 
41#include <stdexcept> 
42 
43namespace std _GLIBCXX_VISIBILITY(default
44
45_GLIBCXX_BEGIN_NAMESPACE_VERSION 
46 
47 class error_code
48 class error_condition
49 class system_error
50 
51 /// is_error_code_enum 
52 template<typename _Tp> 
53 struct is_error_code_enum : public false_type { }; 
54 
55 /// is_error_condition_enum 
56 template<typename _Tp> 
57 struct is_error_condition_enum : public false_type { }; 
58 
59 template<> 
60 struct is_error_condition_enum<errc
61 : public true_type { }; 
62 
63#if __cplusplus > 201402L 
64 template <typename _Tp> 
65 inline constexpr bool is_error_code_enum_v
66 is_error_code_enum<_Tp>::value; 
67 template <typename _Tp> 
68 inline constexpr bool is_error_condition_enum_v
69 is_error_condition_enum<_Tp>::value; 
70#endif // C++17 
71 inline namespace _V2
72 
73 /// error_category 
74 class error_category 
75
76 public
77 constexpr error_category() noexcept = default
78 
79 virtual ~error_category(); 
80 
81 error_category(const error_category&) = delete
82 error_category& operator=(const error_category&) = delete
83 
84 virtual const char
85 name() const noexcept = 0
86 
87 // We need two different virtual functions here, one returning a 
88 // COW string and one returning an SSO string. Their positions in the 
89 // vtable must be consistent for dynamic dispatch to work, but which one 
90 // the name "message()" finds depends on which ABI the caller is using. 
91#if _GLIBCXX_USE_CXX11_ABI 
92 private
93 _GLIBCXX_DEFAULT_ABI_TAG 
94 virtual __cow_string 
95 _M_message(int) const
96 
97 public
98 _GLIBCXX_DEFAULT_ABI_TAG 
99 virtual string 
100 message(int) const = 0
101#else 
102 virtual string 
103 message(int) const = 0
104 
105 private
106 virtual __sso_string 
107 _M_message(int) const
108#endif 
109 
110 public
111 virtual error_condition 
112 default_error_condition(int __i) const noexcept
113 
114 virtual bool 
115 equivalent(int __i, const error_condition& __cond) const noexcept
116 
117 virtual bool 
118 equivalent(const error_code& __code, int __i) const noexcept
119 
120 bool 
121 operator<(const error_category& __other) const noexcept 
122 { return less<const error_category*>()(this, &__other); } 
123 
124 bool 
125 operator==(const error_category& __other) const noexcept 
126 { return this == &__other; } 
127 
128 bool 
129 operator!=(const error_category& __other) const noexcept 
130 { return this != &__other; } 
131 }; 
132 
133 // DR 890. 
134 _GLIBCXX_CONST const error_category& system_category() noexcept
135 _GLIBCXX_CONST const error_category& generic_category() noexcept
136 
137 } // end inline namespace 
138 
139 error_code make_error_code(errc) noexcept
140 
141 template<typename _Tp> 
142 struct hash
143 
144 /// error_code 
145 // Implementation-specific error identification 
146 struct error_code 
147
148 error_code() noexcept 
149 : _M_value(0), _M_cat(&system_category()) { } 
150 
151 error_code(int __v, const error_category& __cat) noexcept 
152 : _M_value(__v), _M_cat(&__cat) { } 
153 
154 template<typename _ErrorCodeEnum, typename = typename 
155 enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type> 
156 error_code(_ErrorCodeEnum __e) noexcept 
157 { *this = make_error_code(__e); } 
158 
159 void 
160 assign(int __v, const error_category& __cat) noexcept 
161
162 _M_value = __v
163 _M_cat = &__cat
164
165 
166 void 
167 clear() noexcept 
168 { assign(0, system_category()); } 
169 
170 // DR 804. 
171 template<typename _ErrorCodeEnum> 
172 typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value, 
173 error_code&>::type 
174 operator=(_ErrorCodeEnum __e) noexcept 
175 { return *this = make_error_code(__e); } 
176 
177 int 
178 value() const noexcept { return _M_value; } 
179 
180 const error_category
181 category() const noexcept { return *_M_cat; } 
182 
183 error_condition 
184 default_error_condition() const noexcept
185 
186 _GLIBCXX_DEFAULT_ABI_TAG 
187 string 
188 message() const 
189 { return category().message(value()); } 
190 
191 explicit operator bool() const noexcept 
192 { return _M_value != 0; } 
193 
194 // DR 804. 
195 private
196 friend class hash<error_code>; 
197 
198 int _M_value
199 const error_category* _M_cat
200 }; 
201 
202 // 19.4.2.6 non-member functions 
203 inline error_code 
204 make_error_code(errc __e) noexcept 
205 { return error_code(static_cast<int>(__e), generic_category()); } 
206 
207 inline bool 
208 operator<(const error_code& __lhs, const error_code& __rhs) noexcept 
209
210 return (__lhs.category() < __rhs.category() 
211 || (__lhs.category() == __rhs.category() 
212 && __lhs.value() < __rhs.value())); 
213
214 
215 template<typename _CharT, typename _Traits> 
216 basic_ostream<_CharT, _Traits>& 
217 operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e
218 { return (__os << __e.category().name() << ':' << __e.value()); } 
219 
220 error_condition make_error_condition(errc) noexcept
221 
222 /// error_condition 
223 // Portable error identification 
224 struct error_condition 
225
226 error_condition() noexcept 
227 : _M_value(0), _M_cat(&generic_category()) { } 
228 
229 error_condition(int __v, const error_category& __cat) noexcept 
230 : _M_value(__v), _M_cat(&__cat) { } 
231 
232 template<typename _ErrorConditionEnum, typename = typename 
233 enable_if<is_error_condition_enum<_ErrorConditionEnum>::value>::type> 
234 error_condition(_ErrorConditionEnum __e) noexcept 
235 { *this = make_error_condition(__e); } 
236 
237 void 
238 assign(int __v, const error_category& __cat) noexcept 
239
240 _M_value = __v
241 _M_cat = &__cat
242
243 
244 // DR 804. 
245 template<typename _ErrorConditionEnum> 
246 typename enable_if<is_error_condition_enum 
247 <_ErrorConditionEnum>::value, error_condition&>::type 
248 operator=(_ErrorConditionEnum __e) noexcept 
249 { return *this = make_error_condition(__e); } 
250 
251 void 
252 clear() noexcept 
253 { assign(0, generic_category()); } 
254 
255 // 19.4.3.4 observers 
256 int 
257 value() const noexcept { return _M_value; } 
258 
259 const error_category
260 category() const noexcept { return *_M_cat; } 
261 
262 _GLIBCXX_DEFAULT_ABI_TAG 
263 string 
264 message() const 
265 { return category().message(value()); } 
266 
267 explicit operator bool() const noexcept 
268 { return _M_value != 0; } 
269 
270 // DR 804. 
271 private
272 int _M_value
273 const error_category* _M_cat
274 }; 
275 
276 // 19.4.3.6 non-member functions 
277 inline error_condition 
278 make_error_condition(errc __e) noexcept 
279 { return error_condition(static_cast<int>(__e), generic_category()); } 
280 
281 inline bool 
282 operator<(const error_condition& __lhs
283 const error_condition& __rhs) noexcept 
284
285 return (__lhs.category() < __rhs.category() 
286 || (__lhs.category() == __rhs.category() 
287 && __lhs.value() < __rhs.value())); 
288
289 
290 // 19.4.4 Comparison operators 
291 inline bool 
292 operator==(const error_code& __lhs, const error_code& __rhs) noexcept 
293 { return (__lhs.category() == __rhs.category() 
294 && __lhs.value() == __rhs.value()); } 
295 
296 inline bool 
297 operator==(const error_code& __lhs, const error_condition& __rhs) noexcept 
298
299 return (__lhs.category().equivalent(__lhs.value(), __rhs
300 || __rhs.category().equivalent(__lhs, __rhs.value())); 
301
302 
303 inline bool 
304 operator==(const error_condition& __lhs, const error_code& __rhs) noexcept 
305
306 return (__rhs.category().equivalent(__rhs.value(), __lhs
307 || __lhs.category().equivalent(__rhs, __lhs.value())); 
308
309 
310 inline bool 
311 operator==(const error_condition& __lhs
312 const error_condition& __rhs) noexcept 
313
314 return (__lhs.category() == __rhs.category() 
315 && __lhs.value() == __rhs.value()); 
316
317 
318 inline bool 
319 operator!=(const error_code& __lhs, const error_code& __rhs) noexcept 
320 { return !(__lhs == __rhs); } 
321 
322 inline bool 
323 operator!=(const error_code& __lhs, const error_condition& __rhs) noexcept 
324 { return !(__lhs == __rhs); } 
325 
326 inline bool 
327 operator!=(const error_condition& __lhs, const error_code& __rhs) noexcept 
328 { return !(__lhs == __rhs); } 
329 
330 inline bool 
331 operator!=(const error_condition& __lhs
332 const error_condition& __rhs) noexcept 
333 { return !(__lhs == __rhs); } 
334 
335 
336 /** 
337 * @brief Thrown to indicate error code of underlying system. 
338 * 
339 * @ingroup exceptions 
340 */ 
341 class system_error : public std::runtime_error 
342
343 private
344 error_code _M_code
345 
346 public
347 system_error(error_code __ec = error_code()) 
348 : runtime_error(__ec.message()), _M_code(__ec) { } 
349 
350 system_error(error_code __ec, const string& __what
351 : runtime_error(__what + ": " + __ec.message()), _M_code(__ec) { } 
352 
353 system_error(error_code __ec, const char* __what
354 : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { } 
355 
356 system_error(int __v, const error_category& __ecat, const char* __what
357 : system_error(error_code(__v, __ecat), __what) { } 
358 
359 system_error(int __v, const error_category& __ecat
360 : runtime_error(error_code(__v, __ecat).message()), 
361 _M_code(__v, __ecat) { } 
362 
363 system_error(int __v, const error_category& __ecat, const string& __what
364 : runtime_error(__what + ": " + error_code(__v, __ecat).message()), 
365 _M_code(__v, __ecat) { } 
366 
367#if __cplusplus >= 201103L 
368 system_error (const system_error &) = default
369 system_error &operator= (const system_error &) = default
370#endif 
371 
372 virtual ~system_error() noexcept
373 
374 const error_code
375 code() const noexcept { return _M_code; } 
376 }; 
377 
378_GLIBCXX_END_NAMESPACE_VERSION 
379} // namespace 
380 
381#include <bits/functional_hash.h> 
382 
383namespace std _GLIBCXX_VISIBILITY(default
384
385_GLIBCXX_BEGIN_NAMESPACE_VERSION 
386 
387#ifndef _GLIBCXX_COMPATIBILITY_CXX0X 
388 // DR 1182. 
389 /// std::hash specialization for error_code. 
390 template<> 
391 struct hash<error_code
392 : public __hash_base<size_t, error_code> 
393
394 size_t 
395 operator()(const error_code& __e) const noexcept 
396
397 const size_t __tmp = std::_Hash_impl::hash(__e._M_value); 
398 return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp); 
399
400 }; 
401#endif // _GLIBCXX_COMPATIBILITY_CXX0X 
402 
403#if __cplusplus > 201402L 
404 // DR 2686. 
405 /// std::hash specialization for error_condition. 
406 template<> 
407 struct hash<error_condition
408 : public __hash_base<size_t, error_condition> 
409
410 size_t 
411 operator()(const error_condition& __e) const noexcept 
412
413 const size_t __tmp = std::_Hash_impl::hash(__e.value()); 
414 return std::_Hash_impl::__hash_combine(__e.category(), __tmp); 
415
416 }; 
417#endif 
418 
419_GLIBCXX_END_NAMESPACE_VERSION 
420} // namespace 
421 
422#endif // C++11 
423 
424#endif // _GLIBCXX_SYSTEM_ERROR 
425