1 // <system_error> -*- C++ -*-
3 // Copyright (C) 2007-2015 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25 /** @file include/system_error
26 * This is a Standard C++ Library header.
29 #ifndef _GLIBCXX_SYSTEM_ERROR
30 #define _GLIBCXX_SYSTEM_ERROR 1
32 #pragma GCC system_header
34 #if __cplusplus < 201103L
35 # include <bits/c++0x_warning.h>
38 #include <bits/c++config.h>
39 #include <bits/error_constants.h>
43 namespace std _GLIBCXX_VISIBILITY(default)
45 _GLIBCXX_BEGIN_NAMESPACE_VERSION
48 class error_condition;
51 /// is_error_code_enum
52 template<typename _Tp>
53 struct is_error_code_enum : public false_type { };
55 /// is_error_condition_enum
56 template<typename _Tp>
57 struct is_error_condition_enum : public false_type { };
60 struct is_error_condition_enum<errc>
61 : public true_type { };
63 inline namespace _V2 {
69 constexpr error_category() noexcept = default;
71 virtual ~error_category();
73 error_category(const error_category&) = delete;
74 error_category& operator=(const error_category&) = delete;
77 name() const noexcept = 0;
79 // We need two different virtual functions here, one returning a
80 // COW string and one returning an SSO string. Their positions in the
81 // vtable must be consistent for dynamic dispatch to work, but which one
82 // the name "message()" finds depends on which ABI the caller is using.
83 #if _GLIBCXX_USE_CXX11_ABI
85 _GLIBCXX_DEFAULT_ABI_TAG
87 _M_message(int) const;
90 _GLIBCXX_DEFAULT_ABI_TAG
92 message(int) const = 0;
95 message(int) const = 0;
99 _M_message(int) const;
103 virtual error_condition
104 default_error_condition(int __i) const noexcept;
107 equivalent(int __i, const error_condition& __cond) const noexcept;
110 equivalent(const error_code& __code, int __i) const noexcept;
113 operator<(const error_category& __other) const noexcept
114 { return less<const error_category*>()(this, &__other); }
117 operator==(const error_category& __other) const noexcept
118 { return this == &__other; }
121 operator!=(const error_category& __other) const noexcept
122 { return this != &__other; }
126 _GLIBCXX_CONST const error_category& system_category() noexcept;
127 _GLIBCXX_CONST const error_category& generic_category() noexcept;
129 } // end inline namespace
131 error_code make_error_code(errc) noexcept;
133 template<typename _Tp>
137 // Implementation-specific error identification
140 error_code() noexcept
141 : _M_value(0), _M_cat(&system_category()) { }
143 error_code(int __v, const error_category& __cat) noexcept
144 : _M_value(__v), _M_cat(&__cat) { }
146 template<typename _ErrorCodeEnum, typename = typename
147 enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type>
148 error_code(_ErrorCodeEnum __e) noexcept
149 { *this = make_error_code(__e); }
152 assign(int __v, const error_category& __cat) noexcept
160 { assign(0, system_category()); }
163 template<typename _ErrorCodeEnum>
164 typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value,
166 operator=(_ErrorCodeEnum __e) noexcept
167 { return *this = make_error_code(__e); }
170 value() const noexcept { return _M_value; }
172 const error_category&
173 category() const noexcept { return *_M_cat; }
176 default_error_condition() const noexcept;
178 _GLIBCXX_DEFAULT_ABI_TAG
181 { return category().message(value()); }
183 explicit operator bool() const noexcept
184 { return _M_value != 0 ? true : false; }
188 friend class hash<error_code>;
191 const error_category* _M_cat;
194 // 19.4.2.6 non-member functions
196 make_error_code(errc __e) noexcept
197 { return error_code(static_cast<int>(__e), generic_category()); }
200 operator<(const error_code& __lhs, const error_code& __rhs) noexcept
202 return (__lhs.category() < __rhs.category()
203 || (__lhs.category() == __rhs.category()
204 && __lhs.value() < __rhs.value()));
207 template<typename _CharT, typename _Traits>
208 basic_ostream<_CharT, _Traits>&
209 operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)
210 { return (__os << __e.category().name() << ':' << __e.value()); }
212 error_condition make_error_condition(errc) noexcept;
215 // Portable error identification
216 struct error_condition
218 error_condition() noexcept
219 : _M_value(0), _M_cat(&generic_category()) { }
221 error_condition(int __v, const error_category& __cat) noexcept
222 : _M_value(__v), _M_cat(&__cat) { }
224 template<typename _ErrorConditionEnum, typename = typename
225 enable_if<is_error_condition_enum<_ErrorConditionEnum>::value>::type>
226 error_condition(_ErrorConditionEnum __e) noexcept
227 { *this = make_error_condition(__e); }
230 assign(int __v, const error_category& __cat) noexcept
237 template<typename _ErrorConditionEnum>
238 typename enable_if<is_error_condition_enum
239 <_ErrorConditionEnum>::value, error_condition&>::type
240 operator=(_ErrorConditionEnum __e) noexcept
241 { return *this = make_error_condition(__e); }
245 { assign(0, generic_category()); }
247 // 19.4.3.4 observers
249 value() const noexcept { return _M_value; }
251 const error_category&
252 category() const noexcept { return *_M_cat; }
254 _GLIBCXX_DEFAULT_ABI_TAG
257 { return category().message(value()); }
259 explicit operator bool() const noexcept
260 { return _M_value != 0 ? true : false; }
265 const error_category* _M_cat;
268 // 19.4.3.6 non-member functions
269 inline error_condition
270 make_error_condition(errc __e) noexcept
271 { return error_condition(static_cast<int>(__e), generic_category()); }
274 operator<(const error_condition& __lhs,
275 const error_condition& __rhs) noexcept
277 return (__lhs.category() < __rhs.category()
278 || (__lhs.category() == __rhs.category()
279 && __lhs.value() < __rhs.value()));
282 // 19.4.4 Comparison operators
284 operator==(const error_code& __lhs, const error_code& __rhs) noexcept
285 { return (__lhs.category() == __rhs.category()
286 && __lhs.value() == __rhs.value()); }
289 operator==(const error_code& __lhs, const error_condition& __rhs) noexcept
291 return (__lhs.category().equivalent(__lhs.value(), __rhs)
292 || __rhs.category().equivalent(__lhs, __rhs.value()));
296 operator==(const error_condition& __lhs, const error_code& __rhs) noexcept
298 return (__rhs.category().equivalent(__rhs.value(), __lhs)
299 || __lhs.category().equivalent(__rhs, __lhs.value()));
303 operator==(const error_condition& __lhs,
304 const error_condition& __rhs) noexcept
306 return (__lhs.category() == __rhs.category()
307 && __lhs.value() == __rhs.value());
311 operator!=(const error_code& __lhs, const error_code& __rhs) noexcept
312 { return !(__lhs == __rhs); }
315 operator!=(const error_code& __lhs, const error_condition& __rhs) noexcept
316 { return !(__lhs == __rhs); }
319 operator!=(const error_condition& __lhs, const error_code& __rhs) noexcept
320 { return !(__lhs == __rhs); }
323 operator!=(const error_condition& __lhs,
324 const error_condition& __rhs) noexcept
325 { return !(__lhs == __rhs); }
329 * @brief Thrown to indicate error code of underlying system.
331 * @ingroup exceptions
333 class system_error : public std::runtime_error
339 system_error(error_code __ec = error_code())
340 : runtime_error(__ec.message()), _M_code(__ec) { }
342 system_error(error_code __ec, const string& __what)
343 : runtime_error(__what + ": " + __ec.message()), _M_code(__ec) { }
345 system_error(error_code __ec, const char* __what)
346 : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { }
348 system_error(int __v, const error_category& __ecat, const char* __what)
349 : system_error(error_code(__v, __ecat), __what) { }
351 system_error(int __v, const error_category& __ecat)
352 : runtime_error(error_code(__v, __ecat).message()),
353 _M_code(__v, __ecat) { }
355 system_error(int __v, const error_category& __ecat, const string& __what)
356 : runtime_error(__what + ": " + error_code(__v, __ecat).message()),
357 _M_code(__v, __ecat) { }
359 virtual ~system_error() noexcept;
362 code() const noexcept { return _M_code; }
365 _GLIBCXX_END_NAMESPACE_VERSION
368 #ifndef _GLIBCXX_COMPATIBILITY_CXX0X
370 #include <bits/functional_hash.h>
372 namespace std _GLIBCXX_VISIBILITY(default)
374 _GLIBCXX_BEGIN_NAMESPACE_VERSION
377 /// std::hash specialization for error_code.
379 struct hash<error_code>
380 : public __hash_base<size_t, error_code>
383 operator()(const error_code& __e) const noexcept
385 const size_t __tmp = std::_Hash_impl::hash(__e._M_value);
386 return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp);
390 _GLIBCXX_END_NAMESPACE_VERSION
393 #endif // _GLIBCXX_COMPATIBILITY_CXX0X
397 #endif // _GLIBCXX_SYSTEM_ERROR