1 // <system_error> -*- C++ -*- 2 3 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file system_error 26 * This is a Standard C++ Library header. 27 */ 28 29 #ifndef _GLIBCXX_SYSTEM_ERROR 30 #define _GLIBCXX_SYSTEM_ERROR 1 31 32 #pragma GCC system_header 33 34 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 35 # include <c++0x_warning.h> 36 #else 37 38 #include <bits/c++config.h> 39 #include <bits/error_constants.h> 40 #include <iosfwd> 41 #include <stdexcept> 42 43 _GLIBCXX_BEGIN_NAMESPACE(std) 44 45 class error_code; 46 class error_condition; 47 class error_category; 48 class system_error; 49 50 /// is_error_code_enum 51 template<typename _Tp> 52 struct is_error_code_enum : public false_type { }; 53 54 /// is_error_condition_enum 55 template<typename _Tp> 56 struct is_error_condition_enum : public false_type { }; 57 58 template<> 59 struct is_error_condition_enum<errc> 60 : public true_type { }; 61 62 63 /// error_category 64 class error_category 65 { 66 protected: 67 error_category() = default; 68 69 public: 70 virtual ~error_category() { } 71 72 error_category(const error_category&) = delete; 73 error_category& operator=(const error_category&) = delete; 74 75 virtual const char* 76 name() const = 0; 77 78 virtual string 79 message(int) const = 0; 80 81 virtual error_condition 82 default_error_condition(int __i) const; 83 84 virtual bool 85 equivalent(int __i, const error_condition& __cond) const; 86 87 virtual bool 88 equivalent(const error_code& __code, int __i) const; 89 90 bool 91 operator<(const error_category& __other) const 92 { return less<const error_category*>()(this, &__other); } 93 94 bool 95 operator==(const error_category& __other) const 96 { return this == &__other; } 97 98 bool 99 operator!=(const error_category& __other) const 100 { return this != &__other; } 101 }; 102 103 // DR 890. 104 const error_category& system_category(); 105 const error_category& generic_category(); 106 107 error_code make_error_code(errc); 108 109 /// error_code 110 // Implementation-specific error identification 111 struct error_code 112 { 113 error_code() 114 : _M_value(0), _M_cat(&system_category()) { } 115 116 error_code(int __v, const error_category& __cat) 117 : _M_value(__v), _M_cat(&__cat) { } 118 119 template<typename _ErrorCodeEnum> 120 error_code(_ErrorCodeEnum __e, 121 typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type* = 0) 122 { *this = make_error_code(__e); } 123 124 void 125 assign(int __v, const error_category& __cat) 126 { 127 _M_value = __v; 128 _M_cat = &__cat; 129 } 130 131 void 132 clear() 133 { assign(0, system_category()); } 134 135 // DR 804. 136 template<typename _ErrorCodeEnum> 137 typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value, 138 error_code&>::type 139 operator=(_ErrorCodeEnum __e) 140 { return *this = make_error_code(__e); } 141 142 int 143 value() const { return _M_value; } 144 145 const error_category& 146 category() const { return *_M_cat; } 147 148 error_condition 149 default_error_condition() const; 150 151 string 152 message() const 153 { return category().message(value()); } 154 155 // Safe bool idiom. 156 // explicit operator bool() const throw() 157 // { return _M_value != 0; } 158 typedef void (*__bool_type)(); 159 160 static void __not_bool_type() { } 161 162 operator __bool_type() const 163 { return _M_value != 0 ? &__not_bool_type : false; } 164 165 // DR 804. 166 private: 167 int _M_value; 168 const error_category* _M_cat; 169 }; 170 171 // 19.4.2.6 non-member functions 172 inline error_code 173 make_error_code(errc __e) 174 { return error_code(static_cast<int>(__e), generic_category()); } 175 176 inline bool 177 operator<(const error_code& __lhs, const error_code& __rhs) 178 { 179 return (__lhs.category() < __rhs.category() 180 || (__lhs.category() == __rhs.category() 181 && __lhs.value() < __rhs.value())); 182 } 183 184 template<typename _CharT, typename _Traits> 185 basic_ostream<_CharT, _Traits>& 186 operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e) 187 { return (__os << __e.category().name() << ':' << __e.value()); } 188 189 error_condition make_error_condition(errc); 190 191 /// error_condition 192 // Portable error identification 193 struct error_condition 194 { 195 error_condition() 196 : _M_value(0), _M_cat(&generic_category()) { } 197 198 error_condition(int __v, const error_category& __cat) 199 : _M_value(__v), _M_cat(&__cat) { } 200 201 template<typename _ErrorConditionEnum> 202 error_condition(_ErrorConditionEnum __e, 203 typename enable_if<is_error_condition_enum 204 <_ErrorConditionEnum>::value>::type* = 0) 205 { *this = make_error_condition(__e); } 206 207 void 208 assign(int __v, const error_category& __cat) 209 { 210 _M_value = __v; 211 _M_cat = &__cat; 212 } 213 214 // DR 804. 215 template<typename _ErrorConditionEnum> 216 typename enable_if<is_error_condition_enum 217 <_ErrorConditionEnum>::value, error_condition&>::type 218 operator=(_ErrorConditionEnum __e) 219 { return *this = make_error_condition(__e); } 220 221 void 222 clear() 223 { assign(0, generic_category()); } 224 225 // 19.4.3.4 observers 226 int 227 value() const { return _M_value; } 228 229 const error_category& 230 category() const { return *_M_cat; } 231 232 string 233 message() const 234 { return category().message(value()); } 235 236 // Safe bool idiom. 237 // explicit operator bool() const throw() 238 // { return _M_value != 0; } 239 typedef void (*__bool_type)(); 240 241 static void __not_bool_type() { } 242 243 operator __bool_type() const 244 { return _M_value != 0 ? &__not_bool_type : false; } 245 246 // DR 804. 247 private: 248 int _M_value; 249 const error_category* _M_cat; 250 }; 251 252 // 19.4.3.6 non-member functions 253 inline error_condition 254 make_error_condition(errc __e) 255 { return error_condition(static_cast<int>(__e), generic_category()); } 256 257 inline bool 258 operator<(const error_condition& __lhs, const error_condition& __rhs) 259 { 260 return (__lhs.category() < __rhs.category() 261 || (__lhs.category() == __rhs.category() 262 && __lhs.value() < __rhs.value())); 263 } 264 265 // 19.4.4 Comparison operators 266 inline bool 267 operator==(const error_code& __lhs, const error_code& __rhs) 268 { return (__lhs.category() == __rhs.category() 269 && __lhs.value() == __rhs.value()); } 270 271 inline bool 272 operator==(const error_code& __lhs, const error_condition& __rhs) 273 { 274 return (__lhs.category().equivalent(__lhs.value(), __rhs) 275 || __rhs.category().equivalent(__lhs, __rhs.value())); 276 } 277 278 inline bool 279 operator==(const error_condition& __lhs, const error_code& __rhs) 280 { 281 return (__rhs.category().equivalent(__rhs.value(), __lhs) 282 || __lhs.category().equivalent(__rhs, __lhs.value())); 283 } 284 285 inline bool 286 operator==(const error_condition& __lhs, const error_condition& __rhs) 287 { 288 return (__lhs.category() == __rhs.category() 289 && __lhs.value() == __rhs.value()); 290 } 291 292 inline bool 293 operator!=(const error_code& __lhs, const error_code& __rhs) 294 { return !(__lhs == __rhs); } 295 296 inline bool 297 operator!=(const error_code& __lhs, const error_condition& __rhs) 298 { return !(__lhs == __rhs); } 299 300 inline bool 301 operator!=(const error_condition& __lhs, const error_code& __rhs) 302 { return !(__lhs == __rhs); } 303 304 inline bool 305 operator!=(const error_condition& __lhs, const error_condition& __rhs) 306 { return !(__lhs == __rhs); } 307 308 309 /** 310 * @brief Thrown to indicate error code of underlying system. 311 * 312 * @ingroup exceptions 313 */ 314 class system_error : public std::runtime_error 315 { 316 private: 317 error_code _M_code; 318 319 public: 320 system_error(error_code __ec = error_code()) 321 : runtime_error(""), _M_code(__ec) { } 322 323 system_error(error_code __ec, const string& __what) 324 : runtime_error(__what), _M_code(__ec) { } 325 326 /* 327 * TODO: Add const char* ctors to all exceptions. 328 * 329 * system_error(error_code __ec, const char* __what) 330 * : runtime_error(__what), _M_code(__ec) { } 331 * 332 * system_error(int __v, const error_category& __ecat, const char* __what) 333 * : runtime_error(__what), _M_code(error_code(__v, __ecat)) { } 334 */ 335 336 system_error(int __v, const error_category& __ecat) 337 : runtime_error(""), _M_code(error_code(__v, __ecat)) { } 338 339 system_error(int __v, const error_category& __ecat, const string& __what) 340 : runtime_error(__what), _M_code(error_code(__v, __ecat)) { } 341 342 virtual ~system_error() throw(); 343 344 const error_code& 345 code() const throw() { return _M_code; } 346 }; 347 348 _GLIBCXX_END_NAMESPACE 349 350 #endif // __GXX_EXPERIMENTAL_CXX0X__ 351 352 #endif // _GLIBCXX_SYSTEM_ERROR 353 354