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