libstdc++
|
00001 // <system_error> -*- C++ -*- 00002 00003 // Copyright (C) 2007, 2008, 2009 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 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 <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 _GLIBCXX_BEGIN_NAMESPACE(std) 00044 00045 class error_code; 00046 class error_condition; 00047 class error_category; 00048 class system_error; 00049 00050 /// is_error_code_enum 00051 template<typename _Tp> 00052 struct is_error_code_enum : public false_type { }; 00053 00054 /// is_error_condition_enum 00055 template<typename _Tp> 00056 struct is_error_condition_enum : public false_type { }; 00057 00058 template<> 00059 struct is_error_condition_enum<errc> 00060 : public true_type { }; 00061 00062 00063 /// error_category 00064 class error_category 00065 { 00066 protected: 00067 error_category() = default; 00068 00069 public: 00070 virtual ~error_category() { } 00071 00072 error_category(const error_category&) = delete; 00073 error_category& operator=(const error_category&) = delete; 00074 00075 virtual const char* 00076 name() const = 0; 00077 00078 virtual string 00079 message(int) const = 0; 00080 00081 virtual error_condition 00082 default_error_condition(int __i) const; 00083 00084 virtual bool 00085 equivalent(int __i, const error_condition& __cond) const; 00086 00087 virtual bool 00088 equivalent(const error_code& __code, int __i) const; 00089 00090 bool 00091 operator<(const error_category& __other) const 00092 { return less<const error_category*>()(this, &__other); } 00093 00094 bool 00095 operator==(const error_category& __other) const 00096 { return this == &__other; } 00097 00098 bool 00099 operator!=(const error_category& __other) const 00100 { return this != &__other; } 00101 }; 00102 00103 // DR 890. 00104 const error_category& system_category(); 00105 const error_category& generic_category(); 00106 00107 error_code make_error_code(errc); 00108 00109 /// error_code 00110 // Implementation-specific error identification 00111 struct error_code 00112 { 00113 error_code() 00114 : _M_value(0), _M_cat(&system_category()) { } 00115 00116 error_code(int __v, const error_category& __cat) 00117 : _M_value(__v), _M_cat(&__cat) { } 00118 00119 template<typename _ErrorCodeEnum> 00120 error_code(_ErrorCodeEnum __e, 00121 typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type* = 0) 00122 { *this = make_error_code(__e); } 00123 00124 void 00125 assign(int __v, const error_category& __cat) 00126 { 00127 _M_value = __v; 00128 _M_cat = &__cat; 00129 } 00130 00131 void 00132 clear() 00133 { assign(0, system_category()); } 00134 00135 // DR 804. 00136 template<typename _ErrorCodeEnum> 00137 typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value, 00138 error_code&>::type 00139 operator=(_ErrorCodeEnum __e) 00140 { return *this = make_error_code(__e); } 00141 00142 int 00143 value() const { return _M_value; } 00144 00145 const error_category& 00146 category() const { return *_M_cat; } 00147 00148 error_condition 00149 default_error_condition() const; 00150 00151 string 00152 message() const 00153 { return category().message(value()); } 00154 00155 // Safe bool idiom. 00156 // explicit operator bool() const throw() 00157 // { return _M_value != 0; } 00158 typedef void (*__bool_type)(); 00159 00160 static void __not_bool_type() { } 00161 00162 operator __bool_type() const 00163 { return _M_value != 0 ? &__not_bool_type : false; } 00164 00165 // DR 804. 00166 private: 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) 00174 { return error_code(static_cast<int>(__e), generic_category()); } 00175 00176 inline bool 00177 operator<(const error_code& __lhs, const error_code& __rhs) 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); 00190 00191 /// error_condition 00192 // Portable error identification 00193 struct error_condition 00194 { 00195 error_condition() 00196 : _M_value(0), _M_cat(&generic_category()) { } 00197 00198 error_condition(int __v, const error_category& __cat) 00199 : _M_value(__v), _M_cat(&__cat) { } 00200 00201 template<typename _ErrorConditionEnum> 00202 error_condition(_ErrorConditionEnum __e, 00203 typename enable_if<is_error_condition_enum 00204 <_ErrorConditionEnum>::value>::type* = 0) 00205 { *this = make_error_condition(__e); } 00206 00207 void 00208 assign(int __v, const error_category& __cat) 00209 { 00210 _M_value = __v; 00211 _M_cat = &__cat; 00212 } 00213 00214 // DR 804. 00215 template<typename _ErrorConditionEnum> 00216 typename enable_if<is_error_condition_enum 00217 <_ErrorConditionEnum>::value, error_condition&>::type 00218 operator=(_ErrorConditionEnum __e) 00219 { return *this = make_error_condition(__e); } 00220 00221 void 00222 clear() 00223 { assign(0, generic_category()); } 00224 00225 // 19.4.3.4 observers 00226 int 00227 value() const { return _M_value; } 00228 00229 const error_category& 00230 category() const { return *_M_cat; } 00231 00232 string 00233 message() const 00234 { return category().message(value()); } 00235 00236 // Safe bool idiom. 00237 // explicit operator bool() const throw() 00238 // { return _M_value != 0; } 00239 typedef void (*__bool_type)(); 00240 00241 static void __not_bool_type() { } 00242 00243 operator __bool_type() const 00244 { return _M_value != 0 ? &__not_bool_type : false; } 00245 00246 // DR 804. 00247 private: 00248 int _M_value; 00249 const error_category* _M_cat; 00250 }; 00251 00252 // 19.4.3.6 non-member functions 00253 inline error_condition 00254 make_error_condition(errc __e) 00255 { return error_condition(static_cast<int>(__e), generic_category()); } 00256 00257 inline bool 00258 operator<(const error_condition& __lhs, const error_condition& __rhs) 00259 { 00260 return (__lhs.category() < __rhs.category() 00261 || (__lhs.category() == __rhs.category() 00262 && __lhs.value() < __rhs.value())); 00263 } 00264 00265 // 19.4.4 Comparison operators 00266 inline bool 00267 operator==(const error_code& __lhs, const error_code& __rhs) 00268 { return (__lhs.category() == __rhs.category() 00269 && __lhs.value() == __rhs.value()); } 00270 00271 inline bool 00272 operator==(const error_code& __lhs, const error_condition& __rhs) 00273 { 00274 return (__lhs.category().equivalent(__lhs.value(), __rhs) 00275 || __rhs.category().equivalent(__lhs, __rhs.value())); 00276 } 00277 00278 inline bool 00279 operator==(const error_condition& __lhs, const error_code& __rhs) 00280 { 00281 return (__rhs.category().equivalent(__rhs.value(), __lhs) 00282 || __lhs.category().equivalent(__rhs, __lhs.value())); 00283 } 00284 00285 inline bool 00286 operator==(const error_condition& __lhs, const error_condition& __rhs) 00287 { 00288 return (__lhs.category() == __rhs.category() 00289 && __lhs.value() == __rhs.value()); 00290 } 00291 00292 inline bool 00293 operator!=(const error_code& __lhs, const error_code& __rhs) 00294 { return !(__lhs == __rhs); } 00295 00296 inline bool 00297 operator!=(const error_code& __lhs, const error_condition& __rhs) 00298 { return !(__lhs == __rhs); } 00299 00300 inline bool 00301 operator!=(const error_condition& __lhs, const error_code& __rhs) 00302 { return !(__lhs == __rhs); } 00303 00304 inline bool 00305 operator!=(const error_condition& __lhs, const error_condition& __rhs) 00306 { return !(__lhs == __rhs); } 00307 00308 00309 /** 00310 * @brief Thrown to indicate error code of underlying system. 00311 * 00312 * @ingroup exceptions 00313 */ 00314 class system_error : public std::runtime_error 00315 { 00316 private: 00317 error_code _M_code; 00318 00319 public: 00320 system_error(error_code __ec = error_code()) 00321 : runtime_error(""), _M_code(__ec) { } 00322 00323 system_error(error_code __ec, const string& __what) 00324 : runtime_error(__what), _M_code(__ec) { } 00325 00326 /* 00327 * TODO: Add const char* ctors to all exceptions. 00328 * 00329 * system_error(error_code __ec, const char* __what) 00330 * : runtime_error(__what), _M_code(__ec) { } 00331 * 00332 * system_error(int __v, const error_category& __ecat, const char* __what) 00333 * : runtime_error(__what), _M_code(error_code(__v, __ecat)) { } 00334 */ 00335 00336 system_error(int __v, const error_category& __ecat) 00337 : runtime_error(""), _M_code(error_code(__v, __ecat)) { } 00338 00339 system_error(int __v, const error_category& __ecat, const string& __what) 00340 : runtime_error(__what), _M_code(error_code(__v, __ecat)) { } 00341 00342 virtual ~system_error() throw(); 00343 00344 const error_code& 00345 code() const throw() { return _M_code; } 00346 }; 00347 00348 _GLIBCXX_END_NAMESPACE 00349 00350 #endif // __GXX_EXPERIMENTAL_CXX0X__ 00351 00352 #endif // _GLIBCXX_SYSTEM_ERROR 00353