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