libstdc++
|
00001 // <system_error> -*- C++ -*- 00002 00003 // Copyright (C) 2007, 2008, 2009, 2010 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(); 00070 00071 public: 00072 virtual ~error_category() { } 00073 00074 error_category(const error_category&) = delete; 00075 error_category& operator=(const error_category&) = delete; 00076 00077 virtual const char* 00078 name() const = 0; 00079 00080 virtual string 00081 message(int) const = 0; 00082 00083 virtual error_condition 00084 default_error_condition(int __i) const; 00085 00086 virtual bool 00087 equivalent(int __i, const error_condition& __cond) const; 00088 00089 virtual bool 00090 equivalent(const error_code& __code, int __i) const; 00091 00092 bool 00093 operator<(const error_category& __other) const 00094 { return less<const error_category*>()(this, &__other); } 00095 00096 bool 00097 operator==(const error_category& __other) const 00098 { return this == &__other; } 00099 00100 bool 00101 operator!=(const error_category& __other) const 00102 { return this != &__other; } 00103 }; 00104 00105 inline error_category::error_category() = default; 00106 00107 // DR 890. 00108 _GLIBCXX_CONST const error_category& system_category() throw(); 00109 _GLIBCXX_CONST const error_category& generic_category() throw(); 00110 00111 error_code make_error_code(errc); 00112 00113 template<typename _Tp> 00114 struct hash; 00115 00116 /// error_code 00117 // Implementation-specific error identification 00118 struct error_code 00119 { 00120 error_code() 00121 : _M_value(0), _M_cat(&system_category()) { } 00122 00123 error_code(int __v, const error_category& __cat) 00124 : _M_value(__v), _M_cat(&__cat) { } 00125 00126 template<typename _ErrorCodeEnum> 00127 error_code(_ErrorCodeEnum __e, 00128 typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type* = 0) 00129 { *this = make_error_code(__e); } 00130 00131 void 00132 assign(int __v, const error_category& __cat) 00133 { 00134 _M_value = __v; 00135 _M_cat = &__cat; 00136 } 00137 00138 void 00139 clear() 00140 { assign(0, system_category()); } 00141 00142 // DR 804. 00143 template<typename _ErrorCodeEnum> 00144 typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value, 00145 error_code&>::type 00146 operator=(_ErrorCodeEnum __e) 00147 { return *this = make_error_code(__e); } 00148 00149 int 00150 value() const { return _M_value; } 00151 00152 const error_category& 00153 category() const { return *_M_cat; } 00154 00155 error_condition 00156 default_error_condition() const; 00157 00158 string 00159 message() const 00160 { return category().message(value()); } 00161 00162 explicit operator bool() const 00163 { return _M_value != 0 ? true : false; } 00164 00165 // DR 804. 00166 private: 00167 friend class hash<error_code>; 00168 00169 int _M_value; 00170 const error_category* _M_cat; 00171 }; 00172 00173 // 19.4.2.6 non-member functions 00174 inline error_code 00175 make_error_code(errc __e) 00176 { return error_code(static_cast<int>(__e), generic_category()); } 00177 00178 inline bool 00179 operator<(const error_code& __lhs, const error_code& __rhs) 00180 { 00181 return (__lhs.category() < __rhs.category() 00182 || (__lhs.category() == __rhs.category() 00183 && __lhs.value() < __rhs.value())); 00184 } 00185 00186 template<typename _CharT, typename _Traits> 00187 basic_ostream<_CharT, _Traits>& 00188 operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e) 00189 { return (__os << __e.category().name() << ':' << __e.value()); } 00190 00191 error_condition make_error_condition(errc); 00192 00193 /// error_condition 00194 // Portable error identification 00195 struct error_condition 00196 { 00197 error_condition() 00198 : _M_value(0), _M_cat(&generic_category()) { } 00199 00200 error_condition(int __v, const error_category& __cat) 00201 : _M_value(__v), _M_cat(&__cat) { } 00202 00203 template<typename _ErrorConditionEnum> 00204 error_condition(_ErrorConditionEnum __e, 00205 typename enable_if<is_error_condition_enum 00206 <_ErrorConditionEnum>::value>::type* = 0) 00207 { *this = make_error_condition(__e); } 00208 00209 void 00210 assign(int __v, const error_category& __cat) 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) 00221 { return *this = make_error_condition(__e); } 00222 00223 void 00224 clear() 00225 { assign(0, generic_category()); } 00226 00227 // 19.4.3.4 observers 00228 int 00229 value() const { return _M_value; } 00230 00231 const error_category& 00232 category() const { return *_M_cat; } 00233 00234 string 00235 message() const 00236 { return category().message(value()); } 00237 00238 explicit operator bool() const 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) 00250 { return error_condition(static_cast<int>(__e), generic_category()); } 00251 00252 inline bool 00253 operator<(const error_condition& __lhs, const error_condition& __rhs) 00254 { 00255 return (__lhs.category() < __rhs.category() 00256 || (__lhs.category() == __rhs.category() 00257 && __lhs.value() < __rhs.value())); 00258 } 00259 00260 // 19.4.4 Comparison operators 00261 inline bool 00262 operator==(const error_code& __lhs, const error_code& __rhs) 00263 { return (__lhs.category() == __rhs.category() 00264 && __lhs.value() == __rhs.value()); } 00265 00266 inline bool 00267 operator==(const error_code& __lhs, const error_condition& __rhs) 00268 { 00269 return (__lhs.category().equivalent(__lhs.value(), __rhs) 00270 || __rhs.category().equivalent(__lhs, __rhs.value())); 00271 } 00272 00273 inline bool 00274 operator==(const error_condition& __lhs, const error_code& __rhs) 00275 { 00276 return (__rhs.category().equivalent(__rhs.value(), __lhs) 00277 || __lhs.category().equivalent(__rhs, __lhs.value())); 00278 } 00279 00280 inline bool 00281 operator==(const error_condition& __lhs, const error_condition& __rhs) 00282 { 00283 return (__lhs.category() == __rhs.category() 00284 && __lhs.value() == __rhs.value()); 00285 } 00286 00287 inline bool 00288 operator!=(const error_code& __lhs, const error_code& __rhs) 00289 { return !(__lhs == __rhs); } 00290 00291 inline bool 00292 operator!=(const error_code& __lhs, const error_condition& __rhs) 00293 { return !(__lhs == __rhs); } 00294 00295 inline bool 00296 operator!=(const error_condition& __lhs, const error_code& __rhs) 00297 { return !(__lhs == __rhs); } 00298 00299 inline bool 00300 operator!=(const error_condition& __lhs, const error_condition& __rhs) 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() throw(); 00341 00342 const error_code& 00343 code() const throw() { 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 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