libstdc++
|
00001 // <system_error> -*- C++ -*- 00002 00003 // Copyright (C) 2007-2019 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file include/system_error 00026 * This is a Standard C++ Library header. 00027 */ 00028 00029 #ifndef _GLIBCXX_SYSTEM_ERROR 00030 #define _GLIBCXX_SYSTEM_ERROR 1 00031 00032 #pragma GCC system_header 00033 00034 #if __cplusplus < 201103L 00035 # include <bits/c++0x_warning.h> 00036 #else 00037 00038 #include <bits/c++config.h> 00039 #include <bits/error_constants.h> 00040 #include <iosfwd> 00041 #include <stdexcept> 00042 00043 namespace std _GLIBCXX_VISIBILITY(default) 00044 { 00045 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00046 00047 class error_code; 00048 class error_condition; 00049 class system_error; 00050 00051 /// is_error_code_enum 00052 template<typename _Tp> 00053 struct is_error_code_enum : public false_type { }; 00054 00055 /// is_error_condition_enum 00056 template<typename _Tp> 00057 struct is_error_condition_enum : public false_type { }; 00058 00059 template<> 00060 struct is_error_condition_enum<errc> 00061 : public true_type { }; 00062 00063 #if __cplusplus > 201402L 00064 template <typename _Tp> 00065 inline constexpr bool is_error_code_enum_v = 00066 is_error_code_enum<_Tp>::value; 00067 template <typename _Tp> 00068 inline constexpr bool is_error_condition_enum_v = 00069 is_error_condition_enum<_Tp>::value; 00070 #endif // C++17 00071 inline namespace _V2 { 00072 00073 /// error_category 00074 class error_category 00075 { 00076 public: 00077 constexpr error_category() noexcept = default; 00078 00079 virtual ~error_category(); 00080 00081 error_category(const error_category&) = delete; 00082 error_category& operator=(const error_category&) = delete; 00083 00084 virtual const char* 00085 name() const noexcept = 0; 00086 00087 // We need two different virtual functions here, one returning a 00088 // COW string and one returning an SSO string. Their positions in the 00089 // vtable must be consistent for dynamic dispatch to work, but which one 00090 // the name "message()" finds depends on which ABI the caller is using. 00091 #if _GLIBCXX_USE_CXX11_ABI 00092 private: 00093 _GLIBCXX_DEFAULT_ABI_TAG 00094 virtual __cow_string 00095 _M_message(int) const; 00096 00097 public: 00098 _GLIBCXX_DEFAULT_ABI_TAG 00099 virtual string 00100 message(int) const = 0; 00101 #else 00102 virtual string 00103 message(int) const = 0; 00104 00105 private: 00106 virtual __sso_string 00107 _M_message(int) const; 00108 #endif 00109 00110 public: 00111 virtual error_condition 00112 default_error_condition(int __i) const noexcept; 00113 00114 virtual bool 00115 equivalent(int __i, const error_condition& __cond) const noexcept; 00116 00117 virtual bool 00118 equivalent(const error_code& __code, int __i) const noexcept; 00119 00120 bool 00121 operator<(const error_category& __other) const noexcept 00122 { return less<const error_category*>()(this, &__other); } 00123 00124 bool 00125 operator==(const error_category& __other) const noexcept 00126 { return this == &__other; } 00127 00128 bool 00129 operator!=(const error_category& __other) const noexcept 00130 { return this != &__other; } 00131 }; 00132 00133 // DR 890. 00134 _GLIBCXX_CONST const error_category& system_category() noexcept; 00135 _GLIBCXX_CONST const error_category& generic_category() noexcept; 00136 00137 } // end inline namespace 00138 00139 error_code make_error_code(errc) noexcept; 00140 00141 template<typename _Tp> 00142 struct hash; 00143 00144 /// error_code 00145 // Implementation-specific error identification 00146 struct error_code 00147 { 00148 error_code() noexcept 00149 : _M_value(0), _M_cat(&system_category()) { } 00150 00151 error_code(int __v, const error_category& __cat) noexcept 00152 : _M_value(__v), _M_cat(&__cat) { } 00153 00154 template<typename _ErrorCodeEnum, typename = typename 00155 enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type> 00156 error_code(_ErrorCodeEnum __e) noexcept 00157 { *this = make_error_code(__e); } 00158 00159 void 00160 assign(int __v, const error_category& __cat) noexcept 00161 { 00162 _M_value = __v; 00163 _M_cat = &__cat; 00164 } 00165 00166 void 00167 clear() noexcept 00168 { assign(0, system_category()); } 00169 00170 // DR 804. 00171 template<typename _ErrorCodeEnum> 00172 typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value, 00173 error_code&>::type 00174 operator=(_ErrorCodeEnum __e) noexcept 00175 { return *this = make_error_code(__e); } 00176 00177 int 00178 value() const noexcept { return _M_value; } 00179 00180 const error_category& 00181 category() const noexcept { return *_M_cat; } 00182 00183 error_condition 00184 default_error_condition() const noexcept; 00185 00186 _GLIBCXX_DEFAULT_ABI_TAG 00187 string 00188 message() const 00189 { return category().message(value()); } 00190 00191 explicit operator bool() const noexcept 00192 { return _M_value != 0; } 00193 00194 // DR 804. 00195 private: 00196 friend class hash<error_code>; 00197 00198 int _M_value; 00199 const error_category* _M_cat; 00200 }; 00201 00202 // 19.4.2.6 non-member functions 00203 inline error_code 00204 make_error_code(errc __e) noexcept 00205 { return error_code(static_cast<int>(__e), generic_category()); } 00206 00207 inline bool 00208 operator<(const error_code& __lhs, const error_code& __rhs) noexcept 00209 { 00210 return (__lhs.category() < __rhs.category() 00211 || (__lhs.category() == __rhs.category() 00212 && __lhs.value() < __rhs.value())); 00213 } 00214 00215 template<typename _CharT, typename _Traits> 00216 basic_ostream<_CharT, _Traits>& 00217 operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e) 00218 { return (__os << __e.category().name() << ':' << __e.value()); } 00219 00220 error_condition make_error_condition(errc) noexcept; 00221 00222 /// error_condition 00223 // Portable error identification 00224 struct error_condition 00225 { 00226 error_condition() noexcept 00227 : _M_value(0), _M_cat(&generic_category()) { } 00228 00229 error_condition(int __v, const error_category& __cat) noexcept 00230 : _M_value(__v), _M_cat(&__cat) { } 00231 00232 template<typename _ErrorConditionEnum, typename = typename 00233 enable_if<is_error_condition_enum<_ErrorConditionEnum>::value>::type> 00234 error_condition(_ErrorConditionEnum __e) noexcept 00235 { *this = make_error_condition(__e); } 00236 00237 void 00238 assign(int __v, const error_category& __cat) noexcept 00239 { 00240 _M_value = __v; 00241 _M_cat = &__cat; 00242 } 00243 00244 // DR 804. 00245 template<typename _ErrorConditionEnum> 00246 typename enable_if<is_error_condition_enum 00247 <_ErrorConditionEnum>::value, error_condition&>::type 00248 operator=(_ErrorConditionEnum __e) noexcept 00249 { return *this = make_error_condition(__e); } 00250 00251 void 00252 clear() noexcept 00253 { assign(0, generic_category()); } 00254 00255 // 19.4.3.4 observers 00256 int 00257 value() const noexcept { return _M_value; } 00258 00259 const error_category& 00260 category() const noexcept { return *_M_cat; } 00261 00262 _GLIBCXX_DEFAULT_ABI_TAG 00263 string 00264 message() const 00265 { return category().message(value()); } 00266 00267 explicit operator bool() const noexcept 00268 { return _M_value != 0; } 00269 00270 // DR 804. 00271 private: 00272 int _M_value; 00273 const error_category* _M_cat; 00274 }; 00275 00276 // 19.4.3.6 non-member functions 00277 inline error_condition 00278 make_error_condition(errc __e) noexcept 00279 { return error_condition(static_cast<int>(__e), generic_category()); } 00280 00281 inline bool 00282 operator<(const error_condition& __lhs, 00283 const error_condition& __rhs) noexcept 00284 { 00285 return (__lhs.category() < __rhs.category() 00286 || (__lhs.category() == __rhs.category() 00287 && __lhs.value() < __rhs.value())); 00288 } 00289 00290 // 19.4.4 Comparison operators 00291 inline bool 00292 operator==(const error_code& __lhs, const error_code& __rhs) noexcept 00293 { return (__lhs.category() == __rhs.category() 00294 && __lhs.value() == __rhs.value()); } 00295 00296 inline bool 00297 operator==(const error_code& __lhs, const error_condition& __rhs) noexcept 00298 { 00299 return (__lhs.category().equivalent(__lhs.value(), __rhs) 00300 || __rhs.category().equivalent(__lhs, __rhs.value())); 00301 } 00302 00303 inline bool 00304 operator==(const error_condition& __lhs, const error_code& __rhs) noexcept 00305 { 00306 return (__rhs.category().equivalent(__rhs.value(), __lhs) 00307 || __lhs.category().equivalent(__rhs, __lhs.value())); 00308 } 00309 00310 inline bool 00311 operator==(const error_condition& __lhs, 00312 const error_condition& __rhs) noexcept 00313 { 00314 return (__lhs.category() == __rhs.category() 00315 && __lhs.value() == __rhs.value()); 00316 } 00317 00318 inline bool 00319 operator!=(const error_code& __lhs, const error_code& __rhs) noexcept 00320 { return !(__lhs == __rhs); } 00321 00322 inline bool 00323 operator!=(const error_code& __lhs, const error_condition& __rhs) noexcept 00324 { return !(__lhs == __rhs); } 00325 00326 inline bool 00327 operator!=(const error_condition& __lhs, const error_code& __rhs) noexcept 00328 { return !(__lhs == __rhs); } 00329 00330 inline bool 00331 operator!=(const error_condition& __lhs, 00332 const error_condition& __rhs) noexcept 00333 { return !(__lhs == __rhs); } 00334 00335 00336 /** 00337 * @brief Thrown to indicate error code of underlying system. 00338 * 00339 * @ingroup exceptions 00340 */ 00341 class system_error : public std::runtime_error 00342 { 00343 private: 00344 error_code _M_code; 00345 00346 public: 00347 system_error(error_code __ec = error_code()) 00348 : runtime_error(__ec.message()), _M_code(__ec) { } 00349 00350 system_error(error_code __ec, const string& __what) 00351 : runtime_error(__what + ": " + __ec.message()), _M_code(__ec) { } 00352 00353 system_error(error_code __ec, const char* __what) 00354 : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { } 00355 00356 system_error(int __v, const error_category& __ecat, const char* __what) 00357 : system_error(error_code(__v, __ecat), __what) { } 00358 00359 system_error(int __v, const error_category& __ecat) 00360 : runtime_error(error_code(__v, __ecat).message()), 00361 _M_code(__v, __ecat) { } 00362 00363 system_error(int __v, const error_category& __ecat, const string& __what) 00364 : runtime_error(__what + ": " + error_code(__v, __ecat).message()), 00365 _M_code(__v, __ecat) { } 00366 00367 #if __cplusplus >= 201103L 00368 system_error (const system_error &) = default; 00369 system_error &operator= (const system_error &) = default; 00370 #endif 00371 00372 virtual ~system_error() noexcept; 00373 00374 const error_code& 00375 code() const noexcept { return _M_code; } 00376 }; 00377 00378 _GLIBCXX_END_NAMESPACE_VERSION 00379 } // namespace 00380 00381 #include <bits/functional_hash.h> 00382 00383 namespace std _GLIBCXX_VISIBILITY(default) 00384 { 00385 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00386 00387 #ifndef _GLIBCXX_COMPATIBILITY_CXX0X 00388 // DR 1182. 00389 /// std::hash specialization for error_code. 00390 template<> 00391 struct hash<error_code> 00392 : public __hash_base<size_t, error_code> 00393 { 00394 size_t 00395 operator()(const error_code& __e) const noexcept 00396 { 00397 const size_t __tmp = std::_Hash_impl::hash(__e._M_value); 00398 return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp); 00399 } 00400 }; 00401 #endif // _GLIBCXX_COMPATIBILITY_CXX0X 00402 00403 #if __cplusplus > 201402L 00404 // DR 2686. 00405 /// std::hash specialization for error_condition. 00406 template<> 00407 struct hash<error_condition> 00408 : public __hash_base<size_t, error_condition> 00409 { 00410 size_t 00411 operator()(const error_condition& __e) const noexcept 00412 { 00413 const size_t __tmp = std::_Hash_impl::hash(__e.value()); 00414 return std::_Hash_impl::__hash_combine(__e.category(), __tmp); 00415 } 00416 }; 00417 #endif 00418 00419 _GLIBCXX_END_NAMESPACE_VERSION 00420 } // namespace 00421 00422 #endif // C++11 00423 00424 #endif // _GLIBCXX_SYSTEM_ERROR