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