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 enum class errc 124 { 125 address_family_not_supported, // EAFNOSUPPORT 126 address_in_use, // EADDRINUSE 127 address_not_available, // EADDRNOTAVAIL 128 already_connected, // EISCONN 129 argument_list_too_long, // E2BIG 130 argument_out_of_domain, // EDOM 131 bad_address, // EFAULT 132 bad_file_descriptor, // EBADF 133 bad_message, // EBADMSG 134 broken_pipe, // EPIPE 135 connection_aborted, // ECONNABORTED 136 connection_already_in_progress, // EALREADY 137 connection_refused, // ECONNREFUSED 138 connection_reset, // ECONNRESET 139 cross_device_link, // EXDEV 140 destination_address_required, // EDESTADDRREQ 141 device_or_resource_busy, // EBUSY 142 directory_not_empty, // ENOTEMPTY 143 executable_format_error, // ENOEXEC 144 file_exists, // EEXIST 145 file_too_large, // EFBIG 146 filename_too_long, // ENAMETOOLONG 147 function_not_supported, // ENOSYS 148 host_unreachable, // EHOSTUNREACH 149 identifier_removed, // EIDRM 150 illegal_byte_sequence, // EILSEQ 151 inappropriate_io_control_operation, // ENOTTY 152 interrupted, // EINTR 153 invalid_argument, // EINVAL 154 invalid_seek, // ESPIPE 155 io_error, // EIO 156 is_a_directory, // EISDIR 157 message_size, // EMSGSIZE 158 network_down, // ENETDOWN 159 network_reset, // ENETRESET 160 network_unreachable, // ENETUNREACH 161 no_buffer_space, // ENOBUFS 162 no_child_process, // ECHILD 163 no_link, // ENOLINK 164 no_lock_available, // ENOLCK 165 no_message_available, // ENODATA 166 no_message, // ENOMSG 167 no_protocol_option, // ENOPROTOOPT 168 no_space_on_device, // ENOSPC 169 no_stream_resources, // ENOSR 170 no_such_device_or_address, // ENXIO 171 no_such_device, // ENODEV 172 no_such_file_or_directory, // ENOENT 173 no_such_process, // ESRCH 174 not_a_directory, // ENOTDIR 175 not_a_socket, // ENOTSOCK 176 not_a_stream, // ENOSTR 177 not_connected, // ENOTCONN 178 not_enough_memory, // ENOMEM 179 not_supported, // ENOTSUP 180 operation_canceled, // ECANCELED 181 operation_in_progress, // EINPROGRESS 182 operation_not_permitted, // EPERM 183 operation_not_supported, // EOPNOTSUPP 184 operation_would_block, // EWOULDBLOCK 185 owner_dead, // EOWNERDEAD 186 permission_denied, // EACCES 187 protocol_error, // EPROTO 188 protocol_not_supported, // EPROTONOSUPPORT 189 read_only_file_system, // EROFS 190 resource_deadlock_would_occur, // EDEADLK 191 resource_unavailable_try_again, // EAGAIN 192 result_out_of_range, // ERANGE 193 state_not_recoverable, // ENOTRECOVERABLE 194 stream_timeout, // ETIME 195 text_file_busy, // ETXTBSY 196 timed_out, // ETIMEDOUT 197 too_many_files_open_in_system, // ENFILE 198 too_many_files_open, // EMFILE 199 too_many_links, // EMLINK 200 too_many_symbolic_link_levels, // ELOOP 201 value_too_large, // EOVERFLOW 202 wrong_protocol_type // EPROTOTYPE 203 }; 204 205 template <> struct is_error_condition_enum<errc> 206 : true_type { } 207 208 error_code make_error_code(errc e) noexcept; 209 error_condition make_error_condition(errc e) noexcept; 210 211 // Comparison operators: 212 bool operator==(const error_code& lhs, const error_code& rhs) noexcept; 213 bool operator==(const error_code& lhs, const error_condition& rhs) noexcept; 214 bool operator==(const error_condition& lhs, const error_code& rhs) noexcept; 215 bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept; 216 bool operator!=(const error_code& lhs, const error_code& rhs) noexcept; 217 bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept; 218 bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept; 219 bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept; 220 221 template <> struct hash<std::error_code>; 222 template <> struct hash<std::error_condition>; 223 224 } // std 225 226 */ 227 228 #include <__config> 229 #include <cerrno> 230 #include <type_traits> 231 #include <stdexcept> 232 #include <__functional_base> 233 #include <string> 234 235 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 236 #pragma GCC system_header 237 #endif 238 239 _LIBCPP_BEGIN_NAMESPACE_STD 240 241 // is_error_code_enum 242 243 template <class _Tp> 244 struct _LIBCPP_TEMPLATE_VIS is_error_code_enum 245 : public false_type {}; 246 247 #if _LIBCPP_STD_VER > 14 248 template <class _Tp> 249 _LIBCPP_INLINE_VAR constexpr size_t is_error_code_enum_v = is_error_code_enum<_Tp>::value; 250 #endif 251 252 // is_error_condition_enum 253 254 template <class _Tp> 255 struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum 256 : public false_type {}; 257 258 #if _LIBCPP_STD_VER > 14 259 template <class _Tp> 260 _LIBCPP_INLINE_VAR constexpr size_t is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; 261 #endif 262 263 // Some error codes are not present on all platforms, so we provide equivalents 264 // for them: 265 266 //enum class errc 267 _LIBCPP_DECLARE_STRONG_ENUM(errc) 268 { 269 address_family_not_supported = EAFNOSUPPORT, 270 address_in_use = EADDRINUSE, 271 address_not_available = EADDRNOTAVAIL, 272 already_connected = EISCONN, 273 argument_list_too_long = E2BIG, 274 argument_out_of_domain = EDOM, 275 bad_address = EFAULT, 276 bad_file_descriptor = EBADF, 277 bad_message = EBADMSG, 278 broken_pipe = EPIPE, 279 connection_aborted = ECONNABORTED, 280 connection_already_in_progress = EALREADY, 281 connection_refused = ECONNREFUSED, 282 connection_reset = ECONNRESET, 283 cross_device_link = EXDEV, 284 destination_address_required = EDESTADDRREQ, 285 device_or_resource_busy = EBUSY, 286 directory_not_empty = ENOTEMPTY, 287 executable_format_error = ENOEXEC, 288 file_exists = EEXIST, 289 file_too_large = EFBIG, 290 filename_too_long = ENAMETOOLONG, 291 function_not_supported = ENOSYS, 292 host_unreachable = EHOSTUNREACH, 293 identifier_removed = EIDRM, 294 illegal_byte_sequence = EILSEQ, 295 inappropriate_io_control_operation = ENOTTY, 296 interrupted = EINTR, 297 invalid_argument = EINVAL, 298 invalid_seek = ESPIPE, 299 io_error = EIO, 300 is_a_directory = EISDIR, 301 message_size = EMSGSIZE, 302 network_down = ENETDOWN, 303 network_reset = ENETRESET, 304 network_unreachable = ENETUNREACH, 305 no_buffer_space = ENOBUFS, 306 no_child_process = ECHILD, 307 no_link = ENOLINK, 308 no_lock_available = ENOLCK, 309 #ifdef ENODATA 310 no_message_available = ENODATA, 311 #else 312 no_message_available = ENOMSG, 313 #endif 314 no_message = ENOMSG, 315 no_protocol_option = ENOPROTOOPT, 316 no_space_on_device = ENOSPC, 317 #ifdef ENOSR 318 no_stream_resources = ENOSR, 319 #else 320 no_stream_resources = ENOMEM, 321 #endif 322 no_such_device_or_address = ENXIO, 323 no_such_device = ENODEV, 324 no_such_file_or_directory = ENOENT, 325 no_such_process = ESRCH, 326 not_a_directory = ENOTDIR, 327 not_a_socket = ENOTSOCK, 328 #ifdef ENOSTR 329 not_a_stream = ENOSTR, 330 #else 331 not_a_stream = EINVAL, 332 #endif 333 not_connected = ENOTCONN, 334 not_enough_memory = ENOMEM, 335 not_supported = ENOTSUP, 336 operation_canceled = ECANCELED, 337 operation_in_progress = EINPROGRESS, 338 operation_not_permitted = EPERM, 339 operation_not_supported = EOPNOTSUPP, 340 operation_would_block = EWOULDBLOCK, 341 owner_dead = EOWNERDEAD, 342 permission_denied = EACCES, 343 protocol_error = EPROTO, 344 protocol_not_supported = EPROTONOSUPPORT, 345 read_only_file_system = EROFS, 346 resource_deadlock_would_occur = EDEADLK, 347 resource_unavailable_try_again = EAGAIN, 348 result_out_of_range = ERANGE, 349 state_not_recoverable = ENOTRECOVERABLE, 350 #ifdef ETIME 351 stream_timeout = ETIME, 352 #else 353 stream_timeout = ETIMEDOUT, 354 #endif 355 text_file_busy = ETXTBSY, 356 timed_out = ETIMEDOUT, 357 too_many_files_open_in_system = ENFILE, 358 too_many_files_open = EMFILE, 359 too_many_links = EMLINK, 360 too_many_symbolic_link_levels = ELOOP, 361 value_too_large = EOVERFLOW, 362 wrong_protocol_type = EPROTOTYPE 363 }; 364 _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc) 365 366 template <> 367 struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc> 368 : true_type { }; 369 370 #ifdef _LIBCPP_HAS_NO_STRONG_ENUMS 371 template <> 372 struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc::__lx> 373 : true_type { }; 374 #endif 375 376 class _LIBCPP_TYPE_VIS error_condition; 377 class _LIBCPP_TYPE_VIS error_code; 378 379 // class error_category 380 381 class _LIBCPP_HIDDEN __do_message; 382 383 class _LIBCPP_TYPE_VIS error_category 384 { 385 public: 386 virtual ~error_category() _NOEXCEPT; 387 388 #if defined(_LIBCPP_BUILDING_SYSTEM_ERROR) && \ 389 defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) 390 error_category() _NOEXCEPT; 391 #else 392 _LIBCPP_ALWAYS_INLINE 393 _LIBCPP_CONSTEXPR_AFTER_CXX11 error_category() _NOEXCEPT _LIBCPP_DEFAULT 394 #endif 395 private: 396 error_category(const error_category&);// = delete; 397 error_category& operator=(const error_category&);// = delete; 398 399 public: 400 virtual const char* name() const _NOEXCEPT = 0; 401 virtual error_condition default_error_condition(int __ev) const _NOEXCEPT; 402 virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT; 403 virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT; 404 virtual string message(int __ev) const = 0; 405 406 _LIBCPP_ALWAYS_INLINE 407 bool operator==(const error_category& __rhs) const _NOEXCEPT {return this == &__rhs;} 408 409 _LIBCPP_ALWAYS_INLINE 410 bool operator!=(const error_category& __rhs) const _NOEXCEPT {return !(*this == __rhs);} 411 412 _LIBCPP_ALWAYS_INLINE 413 bool operator< (const error_category& __rhs) const _NOEXCEPT {return this < &__rhs;} 414 415 friend class _LIBCPP_HIDDEN __do_message; 416 }; 417 418 class _LIBCPP_HIDDEN __do_message 419 : public error_category 420 { 421 public: 422 virtual string message(int ev) const; 423 }; 424 425 _LIBCPP_FUNC_VIS const error_category& generic_category() _NOEXCEPT; 426 _LIBCPP_FUNC_VIS const error_category& system_category() _NOEXCEPT; 427 428 class _LIBCPP_TYPE_VIS error_condition 429 { 430 int __val_; 431 const error_category* __cat_; 432 public: 433 _LIBCPP_ALWAYS_INLINE 434 error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {} 435 436 _LIBCPP_ALWAYS_INLINE 437 error_condition(int __val, const error_category& __cat) _NOEXCEPT 438 : __val_(__val), __cat_(&__cat) {} 439 440 template <class _Ep> 441 _LIBCPP_ALWAYS_INLINE 442 error_condition(_Ep __e, 443 typename enable_if<is_error_condition_enum<_Ep>::value>::type* = 0 444 ) _NOEXCEPT 445 {*this = make_error_condition(__e);} 446 447 _LIBCPP_ALWAYS_INLINE 448 void assign(int __val, const error_category& __cat) _NOEXCEPT 449 { 450 __val_ = __val; 451 __cat_ = &__cat; 452 } 453 454 template <class _Ep> 455 _LIBCPP_ALWAYS_INLINE 456 typename enable_if 457 < 458 is_error_condition_enum<_Ep>::value, 459 error_condition& 460 >::type 461 operator=(_Ep __e) _NOEXCEPT 462 {*this = make_error_condition(__e); return *this;} 463 464 _LIBCPP_ALWAYS_INLINE 465 void clear() _NOEXCEPT 466 { 467 __val_ = 0; 468 __cat_ = &generic_category(); 469 } 470 471 _LIBCPP_ALWAYS_INLINE 472 int value() const _NOEXCEPT {return __val_;} 473 474 _LIBCPP_ALWAYS_INLINE 475 const error_category& category() const _NOEXCEPT {return *__cat_;} 476 string message() const; 477 478 _LIBCPP_ALWAYS_INLINE 479 _LIBCPP_EXPLICIT 480 operator bool() const _NOEXCEPT {return __val_ != 0;} 481 }; 482 483 inline _LIBCPP_INLINE_VISIBILITY 484 error_condition 485 make_error_condition(errc __e) _NOEXCEPT 486 { 487 return error_condition(static_cast<int>(__e), generic_category()); 488 } 489 490 inline _LIBCPP_INLINE_VISIBILITY 491 bool 492 operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT 493 { 494 return __x.category() < __y.category() 495 || (__x.category() == __y.category() && __x.value() < __y.value()); 496 } 497 498 // error_code 499 500 class _LIBCPP_TYPE_VIS error_code 501 { 502 int __val_; 503 const error_category* __cat_; 504 public: 505 _LIBCPP_ALWAYS_INLINE 506 error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {} 507 508 _LIBCPP_ALWAYS_INLINE 509 error_code(int __val, const error_category& __cat) _NOEXCEPT 510 : __val_(__val), __cat_(&__cat) {} 511 512 template <class _Ep> 513 _LIBCPP_ALWAYS_INLINE 514 error_code(_Ep __e, 515 typename enable_if<is_error_code_enum<_Ep>::value>::type* = 0 516 ) _NOEXCEPT 517 {*this = make_error_code(__e);} 518 519 _LIBCPP_ALWAYS_INLINE 520 void assign(int __val, const error_category& __cat) _NOEXCEPT 521 { 522 __val_ = __val; 523 __cat_ = &__cat; 524 } 525 526 template <class _Ep> 527 _LIBCPP_ALWAYS_INLINE 528 typename enable_if 529 < 530 is_error_code_enum<_Ep>::value, 531 error_code& 532 >::type 533 operator=(_Ep __e) _NOEXCEPT 534 {*this = make_error_code(__e); return *this;} 535 536 _LIBCPP_ALWAYS_INLINE 537 void clear() _NOEXCEPT 538 { 539 __val_ = 0; 540 __cat_ = &system_category(); 541 } 542 543 _LIBCPP_ALWAYS_INLINE 544 int value() const _NOEXCEPT {return __val_;} 545 546 _LIBCPP_ALWAYS_INLINE 547 const error_category& category() const _NOEXCEPT {return *__cat_;} 548 549 _LIBCPP_ALWAYS_INLINE 550 error_condition default_error_condition() const _NOEXCEPT 551 {return __cat_->default_error_condition(__val_);} 552 553 string message() const; 554 555 _LIBCPP_ALWAYS_INLINE 556 _LIBCPP_EXPLICIT 557 operator bool() const _NOEXCEPT {return __val_ != 0;} 558 }; 559 560 inline _LIBCPP_INLINE_VISIBILITY 561 error_code 562 make_error_code(errc __e) _NOEXCEPT 563 { 564 return error_code(static_cast<int>(__e), generic_category()); 565 } 566 567 inline _LIBCPP_INLINE_VISIBILITY 568 bool 569 operator<(const error_code& __x, const error_code& __y) _NOEXCEPT 570 { 571 return __x.category() < __y.category() 572 || (__x.category() == __y.category() && __x.value() < __y.value()); 573 } 574 575 inline _LIBCPP_INLINE_VISIBILITY 576 bool 577 operator==(const error_code& __x, const error_code& __y) _NOEXCEPT 578 { 579 return __x.category() == __y.category() && __x.value() == __y.value(); 580 } 581 582 inline _LIBCPP_INLINE_VISIBILITY 583 bool 584 operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT 585 { 586 return __x.category().equivalent(__x.value(), __y) 587 || __y.category().equivalent(__x, __y.value()); 588 } 589 590 inline _LIBCPP_INLINE_VISIBILITY 591 bool 592 operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT 593 { 594 return __y == __x; 595 } 596 597 inline _LIBCPP_INLINE_VISIBILITY 598 bool 599 operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT 600 { 601 return __x.category() == __y.category() && __x.value() == __y.value(); 602 } 603 604 inline _LIBCPP_INLINE_VISIBILITY 605 bool 606 operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT 607 {return !(__x == __y);} 608 609 inline _LIBCPP_INLINE_VISIBILITY 610 bool 611 operator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT 612 {return !(__x == __y);} 613 614 inline _LIBCPP_INLINE_VISIBILITY 615 bool 616 operator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT 617 {return !(__x == __y);} 618 619 inline _LIBCPP_INLINE_VISIBILITY 620 bool 621 operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT 622 {return !(__x == __y);} 623 624 template <> 625 struct _LIBCPP_TEMPLATE_VIS hash<error_code> 626 : public unary_function<error_code, size_t> 627 { 628 _LIBCPP_INLINE_VISIBILITY 629 size_t operator()(const error_code& __ec) const _NOEXCEPT 630 { 631 return static_cast<size_t>(__ec.value()); 632 } 633 }; 634 635 template <> 636 struct _LIBCPP_TEMPLATE_VIS hash<error_condition> 637 : public unary_function<error_condition, size_t> 638 { 639 _LIBCPP_INLINE_VISIBILITY 640 size_t operator()(const error_condition& __ec) const _NOEXCEPT 641 { 642 return static_cast<size_t>(__ec.value()); 643 } 644 }; 645 646 // system_error 647 648 class _LIBCPP_TYPE_VIS system_error 649 : public runtime_error 650 { 651 error_code __ec_; 652 public: 653 system_error(error_code __ec, const string& __what_arg); 654 system_error(error_code __ec, const char* __what_arg); 655 system_error(error_code __ec); 656 system_error(int __ev, const error_category& __ecat, const string& __what_arg); 657 system_error(int __ev, const error_category& __ecat, const char* __what_arg); 658 system_error(int __ev, const error_category& __ecat); 659 ~system_error() _NOEXCEPT; 660 661 _LIBCPP_ALWAYS_INLINE 662 const error_code& code() const _NOEXCEPT {return __ec_;} 663 664 private: 665 static string __init(const error_code&, string); 666 }; 667 668 _LIBCPP_NORETURN _LIBCPP_FUNC_VIS 669 void __throw_system_error(int ev, const char* what_arg); 670 671 _LIBCPP_END_NAMESPACE_STD 672 673 #endif // _LIBCPP_SYSTEM_ERROR 674