libstdc++
|
00001 // <system_error> -*- C++ -*- 00002 00003 // Copyright (C) 2007-2015 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 inline namespace _V2 { 00064 00065 /// error_category 00066 class error_category 00067 { 00068 public: 00069 constexpr error_category() noexcept = default; 00070 00071 virtual ~error_category(); 00072 00073 error_category(const error_category&) = delete; 00074 error_category& operator=(const error_category&) = delete; 00075 00076 virtual const char* 00077 name() const noexcept = 0; 00078 00079 // We need two different virtual functions here, one returning a 00080 // COW string and one returning an SSO string. Their positions in the 00081 // vtable must be consistent for dynamic dispatch to work, but which one 00082 // the name "message()" finds depends on which ABI the caller is using. 00083 #if _GLIBCXX_USE_CXX11_ABI 00084 private: 00085 _GLIBCXX_DEFAULT_ABI_TAG 00086 virtual __cow_string 00087 _M_message(int) const; 00088 00089 public: 00090 _GLIBCXX_DEFAULT_ABI_TAG 00091 virtual string 00092 message(int) const = 0; 00093 #else 00094 virtual string 00095 message(int) const = 0; 00096 00097 private: 00098 virtual __sso_string 00099 _M_message(int) const; 00100 #endif 00101 00102 public: 00103 virtual error_condition 00104 default_error_condition(int __i) const noexcept; 00105 00106 virtual bool 00107 equivalent(int __i, const error_condition& __cond) const noexcept; 00108 00109 virtual bool 00110 equivalent(const error_code& __code, int __i) const noexcept; 00111 00112 bool 00113 operator<(const error_category& __other) const noexcept 00114 { return less<const error_category*>()(this, &__other); } 00115 00116 bool 00117 operator==(const error_category& __other) const noexcept 00118 { return this == &__other; } 00119 00120 bool 00121 operator!=(const error_category& __other) const noexcept 00122 { return this != &__other; } 00123 }; 00124 00125 // DR 890. 00126 _GLIBCXX_CONST const error_category& system_category() noexcept; 00127 _GLIBCXX_CONST const error_category& generic_category() noexcept; 00128 00129 } // end inline namespace 00130 00131 error_code make_error_code(errc) noexcept; 00132 00133 template<typename _Tp> 00134 struct hash; 00135 00136 /// error_code 00137 // Implementation-specific error identification 00138 struct error_code 00139 { 00140 error_code() noexcept 00141 : _M_value(0), _M_cat(&system_category()) { } 00142 00143 error_code(int __v, const error_category& __cat) noexcept 00144 : _M_value(__v), _M_cat(&__cat) { } 00145 00146 template<typename _ErrorCodeEnum, typename = typename 00147 enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type> 00148 error_code(_ErrorCodeEnum __e) noexcept 00149 { *this = make_error_code(__e); } 00150 00151 void 00152 assign(int __v, const error_category& __cat) noexcept 00153 { 00154 _M_value = __v; 00155 _M_cat = &__cat; 00156 } 00157 00158 void 00159 clear() noexcept 00160 { assign(0, system_category()); } 00161 00162 // DR 804. 00163 template<typename _ErrorCodeEnum> 00164 typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value, 00165 error_code&>::type 00166 operator=(_ErrorCodeEnum __e) noexcept 00167 { return *this = make_error_code(__e); } 00168 00169 int 00170 value() const noexcept { return _M_value; } 00171 00172 const error_category& 00173 category() const noexcept { return *_M_cat; } 00174 00175 error_condition 00176 default_error_condition() const noexcept; 00177 00178 _GLIBCXX_DEFAULT_ABI_TAG 00179 string 00180 message() const 00181 { return category().message(value()); } 00182 00183 explicit operator bool() const noexcept 00184 { return _M_value != 0 ? true : false; } 00185 00186 // DR 804. 00187 private: 00188 friend class hash<error_code>; 00189 00190 int _M_value; 00191 const error_category* _M_cat; 00192 }; 00193 00194 // 19.4.2.6 non-member functions 00195 inline error_code 00196 make_error_code(errc __e) noexcept 00197 { return error_code(static_cast<int>(__e), generic_category()); } 00198 00199 inline bool 00200 operator<(const error_code& __lhs, const error_code& __rhs) noexcept 00201 { 00202 return (__lhs.category() < __rhs.category() 00203 || (__lhs.category() == __rhs.category() 00204 && __lhs.value() < __rhs.value())); 00205 } 00206 00207 template<typename _CharT, typename _Traits> 00208 basic_ostream<_CharT, _Traits>& 00209 operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e) 00210 { return (__os << __e.category().name() << ':' << __e.value()); } 00211 00212 error_condition make_error_condition(errc) noexcept; 00213 00214 /// error_condition 00215 // Portable error identification 00216 struct error_condition 00217 { 00218 error_condition() noexcept 00219 : _M_value(0), _M_cat(&generic_category()) { } 00220 00221 error_condition(int __v, const error_category& __cat) noexcept 00222 : _M_value(__v), _M_cat(&__cat) { } 00223 00224 template<typename _ErrorConditionEnum, typename = typename 00225 enable_if<is_error_condition_enum<_ErrorConditionEnum>::value>::type> 00226 error_condition(_ErrorConditionEnum __e) noexcept 00227 { *this = make_error_condition(__e); } 00228 00229 void 00230 assign(int __v, const error_category& __cat) noexcept 00231 { 00232 _M_value = __v; 00233 _M_cat = &__cat; 00234 } 00235 00236 // DR 804. 00237 template<typename _ErrorConditionEnum> 00238 typename enable_if<is_error_condition_enum 00239 <_ErrorConditionEnum>::value, error_condition&>::type 00240 operator=(_ErrorConditionEnum __e) noexcept 00241 { return *this = make_error_condition(__e); } 00242 00243 void 00244 clear() noexcept 00245 { assign(0, generic_category()); } 00246 00247 // 19.4.3.4 observers 00248 int 00249 value() const noexcept { return _M_value; } 00250 00251 const error_category& 00252 category() const noexcept { return *_M_cat; } 00253 00254 _GLIBCXX_DEFAULT_ABI_TAG 00255 string 00256 message() const 00257 { return category().message(value()); } 00258 00259 explicit operator bool() const noexcept 00260 { return _M_value != 0 ? true : false; } 00261 00262 // DR 804. 00263 private: 00264 int _M_value; 00265 const error_category* _M_cat; 00266 }; 00267 00268 // 19.4.3.6 non-member functions 00269 inline error_condition 00270 make_error_condition(errc __e) noexcept 00271 { return error_condition(static_cast<int>(__e), generic_category()); } 00272 00273 inline bool 00274 operator<(const error_condition& __lhs, 00275 const error_condition& __rhs) noexcept 00276 { 00277 return (__lhs.category() < __rhs.category() 00278 || (__lhs.category() == __rhs.category() 00279 && __lhs.value() < __rhs.value())); 00280 } 00281 00282 // 19.4.4 Comparison operators 00283 inline bool 00284 operator==(const error_code& __lhs, const error_code& __rhs) noexcept 00285 { return (__lhs.category() == __rhs.category() 00286 && __lhs.value() == __rhs.value()); } 00287 00288 inline bool 00289 operator==(const error_code& __lhs, const error_condition& __rhs) noexcept 00290 { 00291 return (__lhs.category().equivalent(__lhs.value(), __rhs) 00292 || __rhs.category().equivalent(__lhs, __rhs.value())); 00293 } 00294 00295 inline bool 00296 operator==(const error_condition& __lhs, const error_code& __rhs) noexcept 00297 { 00298 return (__rhs.category().equivalent(__rhs.value(), __lhs) 00299 || __lhs.category().equivalent(__rhs, __lhs.value())); 00300 } 00301 00302 inline bool 00303 operator==(const error_condition& __lhs, 00304 const error_condition& __rhs) noexcept 00305 { 00306 return (__lhs.category() == __rhs.category() 00307 && __lhs.value() == __rhs.value()); 00308 } 00309 00310 inline bool 00311 operator!=(const error_code& __lhs, const error_code& __rhs) noexcept 00312 { return !(__lhs == __rhs); } 00313 00314 inline bool 00315 operator!=(const error_code& __lhs, const error_condition& __rhs) noexcept 00316 { return !(__lhs == __rhs); } 00317 00318 inline bool 00319 operator!=(const error_condition& __lhs, const error_code& __rhs) noexcept 00320 { return !(__lhs == __rhs); } 00321 00322 inline bool 00323 operator!=(const error_condition& __lhs, 00324 const error_condition& __rhs) noexcept 00325 { return !(__lhs == __rhs); } 00326 00327 00328 /** 00329 * @brief Thrown to indicate error code of underlying system. 00330 * 00331 * @ingroup exceptions 00332 */ 00333 class system_error : public std::runtime_error 00334 { 00335 private: 00336 error_code _M_code; 00337 00338 public: 00339 system_error(error_code __ec = error_code()) 00340 : runtime_error(__ec.message()), _M_code(__ec) { } 00341 00342 system_error(error_code __ec, const string& __what) 00343 : runtime_error(__what + ": " + __ec.message()), _M_code(__ec) { } 00344 00345 system_error(error_code __ec, const char* __what) 00346 : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { } 00347 00348 system_error(int __v, const error_category& __ecat, const char* __what) 00349 : system_error(error_code(__v, __ecat), __what) { } 00350 00351 system_error(int __v, const error_category& __ecat) 00352 : runtime_error(error_code(__v, __ecat).message()), 00353 _M_code(__v, __ecat) { } 00354 00355 system_error(int __v, const error_category& __ecat, const string& __what) 00356 : runtime_error(__what + ": " + error_code(__v, __ecat).message()), 00357 _M_code(__v, __ecat) { } 00358 00359 virtual ~system_error() noexcept; 00360 00361 const error_code& 00362 code() const noexcept { return _M_code; } 00363 }; 00364 00365 _GLIBCXX_END_NAMESPACE_VERSION 00366 } // namespace 00367 00368 #ifndef _GLIBCXX_COMPATIBILITY_CXX0X 00369 00370 #include <bits/functional_hash.h> 00371 00372 namespace std _GLIBCXX_VISIBILITY(default) 00373 { 00374 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00375 00376 // DR 1182. 00377 /// std::hash specialization for error_code. 00378 template<> 00379 struct hash<error_code> 00380 : public __hash_base<size_t, error_code> 00381 { 00382 size_t 00383 operator()(const error_code& __e) const noexcept 00384 { 00385 const size_t __tmp = std::_Hash_impl::hash(__e._M_value); 00386 return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp); 00387 } 00388 }; 00389 00390 _GLIBCXX_END_NAMESPACE_VERSION 00391 } // namespace 00392 00393 #endif // _GLIBCXX_COMPATIBILITY_CXX0X 00394 00395 #endif // C++11 00396 00397 #endif // _GLIBCXX_SYSTEM_ERROR