1 // -*- C++ -*- 2 //===---------------------------- system_error ----------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 #ifndef _LIBCPP_SYSTEM_ERROR 12 #define _LIBCPP_SYSTEM_ERROR 13 14 /* 15 system_error synopsis 16 17 namespace std 18 { 19 20 class error_category 21 { 22 public: 23 virtual ~error_category() noexcept; 24 25 constexpr error_category(); 26 error_category(const error_category&) = delete; 27 error_category& operator=(const error_category&) = delete; 28 29 virtual const char* name() const noexcept = 0; 30 virtual error_condition default_error_condition(int ev) const noexcept; 31 virtual bool equivalent(int code, const error_condition& condition) const noexcept; 32 virtual bool equivalent(const error_code& code, int condition) const noexcept; 33 virtual string message(int ev) const = 0; 34 35 bool operator==(const error_category& rhs) const noexcept; 36 bool operator!=(const error_category& rhs) const noexcept; 37 bool operator<(const error_category& rhs) const noexcept; 38 }; 39 40 const error_category& generic_category() noexcept; 41 const error_category& system_category() noexcept; 42 43 template <class T> struct is_error_code_enum 44 : public false_type {}; 45 46 template <class T> struct is_error_condition_enum 47 : public false_type {}; 48 49 template <class _Tp> 50 inline constexpr size_t is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; // C++17 51 52 template <class _Tp> 53 inline constexpr size_t is_error_code_enum_v = is_error_code_enum<_Tp>::value; // C++17 54 55 class error_code 56 { 57 public: 58 // constructors: 59 error_code() noexcept; 60 error_code(int val, const error_category& cat) noexcept; 61 template <class ErrorCodeEnum> 62 error_code(ErrorCodeEnum e) noexcept; 63 64 // modifiers: 65 void assign(int val, const error_category& cat) noexcept; 66 template <class ErrorCodeEnum> 67 error_code& operator=(ErrorCodeEnum e) noexcept; 68 void clear() noexcept; 69 70 // observers: 71 int value() const noexcept; 72 const error_category& category() const noexcept; 73 error_condition default_error_condition() const noexcept; 74 string message() const; 75 explicit operator bool() const noexcept; 76 }; 77 78 // non-member functions: 79 bool operator<(const error_code& lhs, const error_code& rhs) noexcept; 80 template <class charT, class traits> 81 basic_ostream<charT,traits>& 82 operator<<(basic_ostream<charT,traits>& os, const error_code& ec); 83 84 class error_condition 85 { 86 public: 87 // constructors: 88 error_condition() noexcept; 89 error_condition(int val, const error_category& cat) noexcept; 90 template <class ErrorConditionEnum> 91 error_condition(ErrorConditionEnum e) noexcept; 92 93 // modifiers: 94 void assign(int val, const error_category& cat) noexcept; 95 template <class ErrorConditionEnum> 96 error_condition& operator=(ErrorConditionEnum e) noexcept; 97 void clear() noexcept; 98 99 // observers: 100 int value() const noexcept; 101 const error_category& category() const noexcept; 102 string message() const noexcept; 103 explicit operator bool() const noexcept; 104 }; 105 106 bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept; 107 108 class system_error 109 : public runtime_error 110 { 111 public: 112 system_error(error_code ec, const string& what_arg); 113 system_error(error_code ec, const char* what_arg); 114 system_error(error_code ec); 115 system_error(int ev, const error_category& ecat, const string& what_arg); 116 system_error(int ev, const error_category& ecat, const char* what_arg); 117 system_error(int ev, const error_category& ecat); 118 119 const error_code& code() const noexcept; 120 const char* what() const noexcept; 121 }; 122 123 template <> struct is_error_condition_enum<errc> 124 : true_type { } 125 126 error_code make_error_code(errc e) noexcept; 127 error_condition make_error_condition(errc e) noexcept; 128 129 // Comparison operators: 130 bool operator==(const error_code& lhs, const error_code& rhs) noexcept; 131 bool operator==(const error_code& lhs, const error_condition& rhs) noexcept; 132 bool operator==(const error_condition& lhs, const error_code& rhs) noexcept; 133 bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept; 134 bool operator!=(const error_code& lhs, const error_code& rhs) noexcept; 135 bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept; 136 bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept; 137 bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept; 138 139 template <> struct hash<std::error_code>; 140 template <> struct hash<std::error_condition>; 141 142 } // std 143 144 */ 145 146 #include <__errc> 147 #include <type_traits> 148 #include <stdexcept> 149 #include <__functional_base> 150 #include <string> 151 152 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 153 #pragma GCC system_header 154 #endif 155 156 _LIBCPP_BEGIN_NAMESPACE_STD 157 158 // is_error_code_enum 159 160 template <class _Tp> 161 struct _LIBCPP_TEMPLATE_VIS is_error_code_enum 162 : public false_type {}; 163 164 #if _LIBCPP_STD_VER > 14 165 template <class _Tp> 166 _LIBCPP_INLINE_VAR constexpr size_t is_error_code_enum_v = is_error_code_enum<_Tp>::value; 167 #endif 168 169 // is_error_condition_enum 170 171 template <class _Tp> 172 struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum 173 : public false_type {}; 174 175 #if _LIBCPP_STD_VER > 14 176 template <class _Tp> 177 _LIBCPP_INLINE_VAR constexpr size_t is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; 178 #endif 179 180 template <> 181 struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc> 182 : true_type { }; 183 184 #ifdef _LIBCPP_HAS_NO_STRONG_ENUMS 185 template <> 186 struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc::__lx> 187 : true_type { }; 188 #endif 189 190 class _LIBCPP_TYPE_VIS error_condition; 191 class _LIBCPP_TYPE_VIS error_code; 192 193 // class error_category 194 195 class _LIBCPP_HIDDEN __do_message; 196 197 class _LIBCPP_TYPE_VIS error_category 198 { 199 public: 200 virtual ~error_category() _NOEXCEPT; 201 202 #if defined(_LIBCPP_BUILDING_LIBRARY) && \ 203 defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) 204 error_category() _NOEXCEPT; 205 #else 206 _LIBCPP_INLINE_VISIBILITY 207 _LIBCPP_CONSTEXPR_AFTER_CXX11 error_category() _NOEXCEPT _LIBCPP_DEFAULT 208 #endif 209 private: 210 error_category(const error_category&);// = delete; 211 error_category& operator=(const error_category&);// = delete; 212 213 public: 214 virtual const char* name() const _NOEXCEPT = 0; 215 virtual error_condition default_error_condition(int __ev) const _NOEXCEPT; 216 virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT; 217 virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT; 218 virtual string message(int __ev) const = 0; 219 220 _LIBCPP_INLINE_VISIBILITY 221 bool operator==(const error_category& __rhs) const _NOEXCEPT {return this == &__rhs;} 222 223 _LIBCPP_INLINE_VISIBILITY 224 bool operator!=(const error_category& __rhs) const _NOEXCEPT {return !(*this == __rhs);} 225 226 _LIBCPP_INLINE_VISIBILITY 227 bool operator< (const error_category& __rhs) const _NOEXCEPT {return this < &__rhs;} 228 229 friend class _LIBCPP_HIDDEN __do_message; 230 }; 231 232 class _LIBCPP_HIDDEN __do_message 233 : public error_category 234 { 235 public: 236 virtual string message(int ev) const; 237 }; 238 239 _LIBCPP_FUNC_VIS const error_category& generic_category() _NOEXCEPT; 240 _LIBCPP_FUNC_VIS const error_category& system_category() _NOEXCEPT; 241 242 class _LIBCPP_TYPE_VIS error_condition 243 { 244 int __val_; 245 const error_category* __cat_; 246 public: 247 _LIBCPP_INLINE_VISIBILITY 248 error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {} 249 250 _LIBCPP_INLINE_VISIBILITY 251 error_condition(int __val, const error_category& __cat) _NOEXCEPT 252 : __val_(__val), __cat_(&__cat) {} 253 254 template <class _Ep> 255 _LIBCPP_INLINE_VISIBILITY 256 error_condition(_Ep __e, 257 typename enable_if<is_error_condition_enum<_Ep>::value>::type* = 0 258 ) _NOEXCEPT 259 {*this = make_error_condition(__e);} 260 261 _LIBCPP_INLINE_VISIBILITY 262 void assign(int __val, const error_category& __cat) _NOEXCEPT 263 { 264 __val_ = __val; 265 __cat_ = &__cat; 266 } 267 268 template <class _Ep> 269 _LIBCPP_INLINE_VISIBILITY 270 typename enable_if 271 < 272 is_error_condition_enum<_Ep>::value, 273 error_condition& 274 >::type 275 operator=(_Ep __e) _NOEXCEPT 276 {*this = make_error_condition(__e); return *this;} 277 278 _LIBCPP_INLINE_VISIBILITY 279 void clear() _NOEXCEPT 280 { 281 __val_ = 0; 282 __cat_ = &generic_category(); 283 } 284 285 _LIBCPP_INLINE_VISIBILITY 286 int value() const _NOEXCEPT {return __val_;} 287 288 _LIBCPP_INLINE_VISIBILITY 289 const error_category& category() const _NOEXCEPT {return *__cat_;} 290 string message() const; 291 292 _LIBCPP_INLINE_VISIBILITY 293 _LIBCPP_EXPLICIT 294 operator bool() const _NOEXCEPT {return __val_ != 0;} 295 }; 296 297 inline _LIBCPP_INLINE_VISIBILITY 298 error_condition 299 make_error_condition(errc __e) _NOEXCEPT 300 { 301 return error_condition(static_cast<int>(__e), generic_category()); 302 } 303 304 inline _LIBCPP_INLINE_VISIBILITY 305 bool 306 operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT 307 { 308 return __x.category() < __y.category() 309 || (__x.category() == __y.category() && __x.value() < __y.value()); 310 } 311 312 // error_code 313 314 class _LIBCPP_TYPE_VIS error_code 315 { 316 int __val_; 317 const error_category* __cat_; 318 public: 319 _LIBCPP_INLINE_VISIBILITY 320 error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {} 321 322 _LIBCPP_INLINE_VISIBILITY 323 error_code(int __val, const error_category& __cat) _NOEXCEPT 324 : __val_(__val), __cat_(&__cat) {} 325 326 template <class _Ep> 327 _LIBCPP_INLINE_VISIBILITY 328 error_code(_Ep __e, 329 typename enable_if<is_error_code_enum<_Ep>::value>::type* = 0 330 ) _NOEXCEPT 331 {*this = make_error_code(__e);} 332 333 _LIBCPP_INLINE_VISIBILITY 334 void assign(int __val, const error_category& __cat) _NOEXCEPT 335 { 336 __val_ = __val; 337 __cat_ = &__cat; 338 } 339 340 template <class _Ep> 341 _LIBCPP_INLINE_VISIBILITY 342 typename enable_if 343 < 344 is_error_code_enum<_Ep>::value, 345 error_code& 346 >::type 347 operator=(_Ep __e) _NOEXCEPT 348 {*this = make_error_code(__e); return *this;} 349 350 _LIBCPP_INLINE_VISIBILITY 351 void clear() _NOEXCEPT 352 { 353 __val_ = 0; 354 __cat_ = &system_category(); 355 } 356 357 _LIBCPP_INLINE_VISIBILITY 358 int value() const _NOEXCEPT {return __val_;} 359 360 _LIBCPP_INLINE_VISIBILITY 361 const error_category& category() const _NOEXCEPT {return *__cat_;} 362 363 _LIBCPP_INLINE_VISIBILITY 364 error_condition default_error_condition() const _NOEXCEPT 365 {return __cat_->default_error_condition(__val_);} 366 367 string message() const; 368 369 _LIBCPP_INLINE_VISIBILITY 370 _LIBCPP_EXPLICIT 371 operator bool() const _NOEXCEPT {return __val_ != 0;} 372 }; 373 374 inline _LIBCPP_INLINE_VISIBILITY 375 error_code 376 make_error_code(errc __e) _NOEXCEPT 377 { 378 return error_code(static_cast<int>(__e), generic_category()); 379 } 380 381 inline _LIBCPP_INLINE_VISIBILITY 382 bool 383 operator<(const error_code& __x, const error_code& __y) _NOEXCEPT 384 { 385 return __x.category() < __y.category() 386 || (__x.category() == __y.category() && __x.value() < __y.value()); 387 } 388 389 inline _LIBCPP_INLINE_VISIBILITY 390 bool 391 operator==(const error_code& __x, const error_code& __y) _NOEXCEPT 392 { 393 return __x.category() == __y.category() && __x.value() == __y.value(); 394 } 395 396 inline _LIBCPP_INLINE_VISIBILITY 397 bool 398 operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT 399 { 400 return __x.category().equivalent(__x.value(), __y) 401 || __y.category().equivalent(__x, __y.value()); 402 } 403 404 inline _LIBCPP_INLINE_VISIBILITY 405 bool 406 operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT 407 { 408 return __y == __x; 409 } 410 411 inline _LIBCPP_INLINE_VISIBILITY 412 bool 413 operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT 414 { 415 return __x.category() == __y.category() && __x.value() == __y.value(); 416 } 417 418 inline _LIBCPP_INLINE_VISIBILITY 419 bool 420 operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT 421 {return !(__x == __y);} 422 423 inline _LIBCPP_INLINE_VISIBILITY 424 bool 425 operator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT 426 {return !(__x == __y);} 427 428 inline _LIBCPP_INLINE_VISIBILITY 429 bool 430 operator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT 431 {return !(__x == __y);} 432 433 inline _LIBCPP_INLINE_VISIBILITY 434 bool 435 operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT 436 {return !(__x == __y);} 437 438 template <> 439 struct _LIBCPP_TEMPLATE_VIS hash<error_code> 440 : public unary_function<error_code, size_t> 441 { 442 _LIBCPP_INLINE_VISIBILITY 443 size_t operator()(const error_code& __ec) const _NOEXCEPT 444 { 445 return static_cast<size_t>(__ec.value()); 446 } 447 }; 448 449 template <> 450 struct _LIBCPP_TEMPLATE_VIS hash<error_condition> 451 : public unary_function<error_condition, size_t> 452 { 453 _LIBCPP_INLINE_VISIBILITY 454 size_t operator()(const error_condition& __ec) const _NOEXCEPT 455 { 456 return static_cast<size_t>(__ec.value()); 457 } 458 }; 459 460 // system_error 461 462 class _LIBCPP_TYPE_VIS system_error 463 : public runtime_error 464 { 465 error_code __ec_; 466 public: 467 system_error(error_code __ec, const string& __what_arg); 468 system_error(error_code __ec, const char* __what_arg); 469 system_error(error_code __ec); 470 system_error(int __ev, const error_category& __ecat, const string& __what_arg); 471 system_error(int __ev, const error_category& __ecat, const char* __what_arg); 472 system_error(int __ev, const error_category& __ecat); 473 ~system_error() _NOEXCEPT; 474 475 _LIBCPP_INLINE_VISIBILITY 476 const error_code& code() const _NOEXCEPT {return __ec_;} 477 478 private: 479 static string __init(const error_code&, string); 480 }; 481 482 _LIBCPP_NORETURN _LIBCPP_FUNC_VIS 483 void __throw_system_error(int ev, const char* what_arg); 484 485 _LIBCPP_END_NAMESPACE_STD 486 487 #endif // _LIBCPP_SYSTEM_ERROR 488