1// -*- C++ -*- 2//===---------------------------- system_error ----------------------------===// 3// 4// The LLVM Compiler Infrastructure 5// 6// This file is distributed under the University of Illinois Open Source 7// License. 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(); 24 25 error_category(const error_category&) = delete; 26 error_category& operator=(const error_category&) = delete; 27 28 virtual const char* name() const = 0; 29 virtual error_condition default_error_condition(int ev) const; 30 virtual bool equivalent(int code, const error_condition& condition) const; 31 virtual bool equivalent(const error_code& code, int condition) const; 32 virtual string message(int ev) const = 0; 33 34 bool operator==(const error_category& rhs) const; 35 bool operator!=(const error_category& rhs) const; 36 bool operator<(const error_category& rhs) const; 37}; 38 39const error_category& generic_category(); 40const error_category& system_category(); 41 42template <class T> struct is_error_code_enum 43 : public false_type {}; 44 45template <class T> struct is_error_condition_enum 46 : public false_type {}; 47 48class error_code 49{ 50public: 51 // constructors: 52 error_code(); 53 error_code(int val, const error_category& cat); 54 template <class ErrorCodeEnum> 55 error_code(ErrorCodeEnum e); 56 57 // modifiers: 58 void assign(int val, const error_category& cat); 59 template <class ErrorCodeEnum> 60 error_code& operator=(ErrorCodeEnum e); 61 void clear(); 62 63 // observers: 64 int value() const; 65 const error_category& category() const; 66 error_condition default_error_condition() const; 67 string message() const; 68 explicit operator bool() const; 69}; 70 71// non-member functions: 72bool operator<(const error_code& lhs, const error_code& rhs); 73template <class charT, class traits> 74 basic_ostream<charT,traits>& 75 operator<<(basic_ostream<charT,traits>& os, const error_code& ec); 76 77class error_condition 78{ 79public: 80 // constructors: 81 error_condition(); 82 error_condition(int val, const error_category& cat); 83 template <class ErrorConditionEnum> 84 error_condition(ErrorConditionEnum e); 85 86 // modifiers: 87 void assign(int val, const error_category& cat); 88 template <class ErrorConditionEnum> 89 error_condition& operator=(ErrorConditionEnum e); 90 void clear(); 91 92 // observers: 93 int value() const; 94 const error_category& category() const; 95 string message() const; 96 explicit operator bool() const; 97}; 98 99bool operator<(const error_condition& lhs, const error_condition& rhs); 100 101class system_error 102 : public runtime_error 103{ 104public: 105 system_error(error_code ec, const string& what_arg); 106 system_error(error_code ec, const char* what_arg); 107 system_error(error_code ec); 108 system_error(int ev, const error_category& ecat, const string& what_arg); 109 system_error(int ev, const error_category& ecat, const char* what_arg); 110 system_error(int ev, const error_category& ecat); 111 112 const error_code& code() const throw(); 113 const char* what() const throw(); 114}; 115 116enum class errc 117{ 118 address_family_not_supported, // EAFNOSUPPORT 119 address_in_use, // EADDRINUSE 120 address_not_available, // EADDRNOTAVAIL 121 already_connected, // EISCONN 122 argument_list_too_long, // E2BIG 123 argument_out_of_domain, // EDOM 124 bad_address, // EFAULT 125 bad_file_descriptor, // EBADF 126 bad_message, // EBADMSG 127 broken_pipe, // EPIPE 128 connection_aborted, // ECONNABORTED 129 connection_already_in_progress, // EALREADY 130 connection_refused, // ECONNREFUSED 131 connection_reset, // ECONNRESET 132 cross_device_link, // EXDEV 133 destination_address_required, // EDESTADDRREQ 134 device_or_resource_busy, // EBUSY 135 directory_not_empty, // ENOTEMPTY 136 executable_format_error, // ENOEXEC 137 file_exists, // EEXIST 138 file_too_large, // EFBIG 139 filename_too_long, // ENAMETOOLONG 140 function_not_supported, // ENOSYS 141 host_unreachable, // EHOSTUNREACH 142 identifier_removed, // EIDRM 143 illegal_byte_sequence, // EILSEQ 144 inappropriate_io_control_operation, // ENOTTY 145 interrupted, // EINTR 146 invalid_argument, // EINVAL 147 invalid_seek, // ESPIPE 148 io_error, // EIO 149 is_a_directory, // EISDIR 150 message_size, // EMSGSIZE 151 network_down, // ENETDOWN 152 network_reset, // ENETRESET 153 network_unreachable, // ENETUNREACH 154 no_buffer_space, // ENOBUFS 155 no_child_process, // ECHILD 156 no_link, // ENOLINK 157 no_lock_available, // ENOLCK 158 no_message_available, // ENODATA 159 no_message, // ENOMSG 160 no_protocol_option, // ENOPROTOOPT 161 no_space_on_device, // ENOSPC 162 no_stream_resources, // ENOSR 163 no_such_device_or_address, // ENXIO 164 no_such_device, // ENODEV 165 no_such_file_or_directory, // ENOENT 166 no_such_process, // ESRCH 167 not_a_directory, // ENOTDIR 168 not_a_socket, // ENOTSOCK 169 not_a_stream, // ENOSTR 170 not_connected, // ENOTCONN 171 not_enough_memory, // ENOMEM 172 not_supported, // ENOTSUP 173 operation_canceled, // ECANCELED 174 operation_in_progress, // EINPROGRESS 175 operation_not_permitted, // EPERM 176 operation_not_supported, // EOPNOTSUPP 177 operation_would_block, // EWOULDBLOCK 178 owner_dead, // EOWNERDEAD 179 permission_denied, // EACCES 180 protocol_error, // EPROTO 181 protocol_not_supported, // EPROTONOSUPPORT 182 read_only_file_system, // EROFS 183 resource_deadlock_would_occur, // EDEADLK 184 resource_unavailable_try_again, // EAGAIN 185 result_out_of_range, // ERANGE 186 state_not_recoverable, // ENOTRECOVERABLE 187 stream_timeout, // ETIME 188 text_file_busy, // ETXTBSY 189 timed_out, // ETIMEDOUT 190 too_many_files_open_in_system, // ENFILE 191 too_many_files_open, // EMFILE 192 too_many_links, // EMLINK 193 too_many_symbolic_link_levels, // ELOOP 194 value_too_large, // EOVERFLOW 195 wrong_protocol_type // EPROTOTYPE 196}; 197 198template <> struct is_error_condition_enum<errc> 199 : true_type { } 200 201error_code make_error_code(errc e); 202error_condition make_error_condition(errc e); 203 204// Comparison operators: 205bool operator==(const error_code& lhs, const error_code& rhs); 206bool operator==(const error_code& lhs, const error_condition& rhs); 207bool operator==(const error_condition& lhs, const error_code& rhs); 208bool operator==(const error_condition& lhs, const error_condition& rhs); 209bool operator!=(const error_code& lhs, const error_code& rhs); 210bool operator!=(const error_code& lhs, const error_condition& rhs); 211bool operator!=(const error_condition& lhs, const error_code& rhs); 212bool operator!=(const error_condition& lhs, const error_condition& rhs); 213 214template <> struct hash<std::error_code>; 215 216} // std 217 218*/ 219 220#include <__config> 221#include <cerrno> 222#include <type_traits> 223#include <stdexcept> 224#include <__functional_base> 225 226#pragma GCC system_header 227 228_LIBCPP_BEGIN_NAMESPACE_STD 229 230// is_error_code_enum 231 232template <class _Tp> struct is_error_code_enum 233 : public false_type {}; 234 235// is_error_condition_enum 236 237template <class _Tp> struct is_error_condition_enum 238 : public false_type {}; 239 240//enum class errc 241struct errc 242{ 243enum _ { 244 address_family_not_supported = EAFNOSUPPORT, 245 address_in_use = EADDRINUSE, 246 address_not_available = EADDRNOTAVAIL, 247 already_connected = EISCONN, 248 argument_list_too_long = E2BIG, 249 argument_out_of_domain = EDOM, 250 bad_address = EFAULT, 251 bad_file_descriptor = EBADF, 252 bad_message = EBADMSG, 253 broken_pipe = EPIPE, 254 connection_aborted = ECONNABORTED, 255 connection_already_in_progress = EALREADY, 256 connection_refused = ECONNREFUSED, 257 connection_reset = ECONNRESET, 258 cross_device_link = EXDEV, 259 destination_address_required = EDESTADDRREQ, 260 device_or_resource_busy = EBUSY, 261 directory_not_empty = ENOTEMPTY, 262 executable_format_error = ENOEXEC, 263 file_exists = EEXIST, 264 file_too_large = EFBIG, 265 filename_too_long = ENAMETOOLONG, 266 function_not_supported = ENOSYS, 267 host_unreachable = EHOSTUNREACH, 268 identifier_removed = EIDRM, 269 illegal_byte_sequence = EILSEQ, 270 inappropriate_io_control_operation = ENOTTY, 271 interrupted = EINTR, 272 invalid_argument = EINVAL, 273 invalid_seek = ESPIPE, 274 io_error = EIO, 275 is_a_directory = EISDIR, 276 message_size = EMSGSIZE, 277 network_down = ENETDOWN, 278 network_reset = ENETRESET, 279 network_unreachable = ENETUNREACH, 280 no_buffer_space = ENOBUFS, 281 no_child_process = ECHILD, 282 no_link = ENOLINK, 283 no_lock_available = ENOLCK, 284 no_message_available = ENODATA, 285 no_message = ENOMSG, 286 no_protocol_option = ENOPROTOOPT, 287 no_space_on_device = ENOSPC, 288 no_stream_resources = ENOSR, 289 no_such_device_or_address = ENXIO, 290 no_such_device = ENODEV, 291 no_such_file_or_directory = ENOENT, 292 no_such_process = ESRCH, 293 not_a_directory = ENOTDIR, 294 not_a_socket = ENOTSOCK, 295 not_a_stream = ENOSTR, 296 not_connected = ENOTCONN, 297 not_enough_memory = ENOMEM, 298 not_supported = ENOTSUP, 299 operation_canceled = ECANCELED, 300 operation_in_progress = EINPROGRESS, 301 operation_not_permitted = EPERM, 302 operation_not_supported = EOPNOTSUPP, 303 operation_would_block = EWOULDBLOCK, 304 owner_dead = EOWNERDEAD, 305 permission_denied = EACCES, 306 protocol_error = EPROTO, 307 protocol_not_supported = EPROTONOSUPPORT, 308 read_only_file_system = EROFS, 309 resource_deadlock_would_occur = EDEADLK, 310 resource_unavailable_try_again = EAGAIN, 311 result_out_of_range = ERANGE, 312 state_not_recoverable = ENOTRECOVERABLE, 313 stream_timeout = ETIME, 314 text_file_busy = ETXTBSY, 315 timed_out = ETIMEDOUT, 316 too_many_files_open_in_system = ENFILE, 317 too_many_files_open = EMFILE, 318 too_many_links = EMLINK, 319 too_many_symbolic_link_levels = ELOOP, 320 value_too_large = EOVERFLOW, 321 wrong_protocol_type = EPROTOTYPE 322}; 323 324 _ __v_; 325 326 errc(_ __v) : __v_(__v) {} 327 operator int() const {return __v_;} 328 329}; 330 331template <> struct is_error_condition_enum<errc> 332 : true_type { }; 333 334template <> struct is_error_condition_enum<errc::_> 335 : true_type { }; 336 337class error_condition; 338class error_code; 339 340// class error_category 341 342class __do_message; 343 344class error_category 345{ 346public: 347 virtual ~error_category(); 348 349private: 350 error_category(); 351 error_category(const error_category&);// = delete; 352 error_category& operator=(const error_category&);// = delete; 353 354public: 355 virtual const char* name() const = 0; 356 virtual error_condition default_error_condition(int __ev) const; 357 virtual bool equivalent(int __code, const error_condition& __condition) const; 358 virtual bool equivalent(const error_code& __code, int __condition) const; 359 virtual string message(int __ev) const = 0; 360 361 _LIBCPP_ALWAYS_INLINE 362 bool operator==(const error_category& __rhs) const {return this == &__rhs;} 363 364 _LIBCPP_ALWAYS_INLINE 365 bool operator!=(const error_category& __rhs) const {return !(*this == __rhs);} 366 367 _LIBCPP_ALWAYS_INLINE 368 bool operator< (const error_category& __rhs) const {return this < &__rhs;} 369 370 friend class __do_message; 371}; 372 373class _LIBCPP_HIDDEN __do_message 374 : public error_category 375{ 376public: 377 virtual string message(int ev) const; 378}; 379 380const error_category& generic_category(); 381const error_category& system_category(); 382 383class error_condition 384{ 385 int __val_; 386 const error_category* __cat_; 387public: 388 _LIBCPP_ALWAYS_INLINE 389 error_condition() : __val_(0), __cat_(&generic_category()) {} 390 391 _LIBCPP_ALWAYS_INLINE 392 error_condition(int __val, const error_category& __cat) 393 : __val_(__val), __cat_(&__cat) {} 394 395 template <class _E> 396 _LIBCPP_ALWAYS_INLINE 397 error_condition(_E __e, typename enable_if<is_error_condition_enum<_E>::value>::type* = 0) 398 {*this = make_error_condition(__e);} 399 400 _LIBCPP_ALWAYS_INLINE 401 void assign(int __val, const error_category& __cat) 402 { 403 __val_ = __val; 404 __cat_ = &__cat; 405 } 406 407 template <class _E> 408 _LIBCPP_ALWAYS_INLINE 409 typename enable_if 410 < 411 is_error_condition_enum<_E>::value, 412 error_condition& 413 >::type 414 operator=(_E __e) 415 {*this = make_error_condition(__e); return *this;} 416 417 _LIBCPP_ALWAYS_INLINE 418 void clear() 419 { 420 __val_ = 0; 421 __cat_ = &generic_category(); 422 } 423 424 _LIBCPP_ALWAYS_INLINE 425 int value() const {return __val_;} 426 427 _LIBCPP_ALWAYS_INLINE 428 const error_category& category() const {return *__cat_;} 429 string message() const; 430 431 _LIBCPP_ALWAYS_INLINE 432 //explicit 433 operator bool() const {return __val_ != 0;} 434}; 435 436inline _LIBCPP_INLINE_VISIBILITY 437error_condition 438make_error_condition(errc __e) 439{ 440 return error_condition(static_cast<int>(__e), generic_category()); 441} 442 443inline _LIBCPP_INLINE_VISIBILITY 444bool 445operator<(const error_condition& __x, const error_condition& __y) 446{ 447 return __x.category() < __y.category() 448 || __x.category() == __y.category() && __x.value() < __y.value(); 449} 450 451// error_code 452 453class error_code 454{ 455 int __val_; 456 const error_category* __cat_; 457public: 458 _LIBCPP_ALWAYS_INLINE 459 error_code() : __val_(0), __cat_(&system_category()) {} 460 461 _LIBCPP_ALWAYS_INLINE 462 error_code(int __val, const error_category& __cat) 463 : __val_(__val), __cat_(&__cat) {} 464 465 template <class _E> 466 _LIBCPP_ALWAYS_INLINE 467 error_code(_E __e, typename enable_if<is_error_code_enum<_E>::value>::type* = 0) 468 {*this = make_error_code(__e);} 469 470 _LIBCPP_ALWAYS_INLINE 471 void assign(int __val, const error_category& __cat) 472 { 473 __val_ = __val; 474 __cat_ = &__cat; 475 } 476 477 template <class _E> 478 _LIBCPP_ALWAYS_INLINE 479 typename enable_if 480 < 481 is_error_code_enum<_E>::value, 482 error_code& 483 >::type 484 operator=(_E __e) 485 {*this = make_error_code(__e); return *this;} 486 487 _LIBCPP_ALWAYS_INLINE 488 void clear() 489 { 490 __val_ = 0; 491 __cat_ = &system_category(); 492 } 493 494 _LIBCPP_ALWAYS_INLINE 495 int value() const {return __val_;} 496 497 _LIBCPP_ALWAYS_INLINE 498 const error_category& category() const {return *__cat_;} 499 500 _LIBCPP_ALWAYS_INLINE 501 error_condition default_error_condition() const 502 {return __cat_->default_error_condition(__val_);} 503 504 string message() const; 505 506 _LIBCPP_ALWAYS_INLINE 507 //explicit 508 operator bool() const {return __val_ != 0;} 509}; 510 511inline _LIBCPP_INLINE_VISIBILITY 512error_code 513make_error_code(errc __e) 514{ 515 return error_code(static_cast<int>(__e), generic_category()); 516} 517 518inline _LIBCPP_INLINE_VISIBILITY 519bool 520operator<(const error_code& __x, const error_code& __y) 521{ 522 return __x.category() < __y.category() 523 || __x.category() == __y.category() && __x.value() < __y.value(); 524} 525 526inline _LIBCPP_INLINE_VISIBILITY 527bool 528operator==(const error_code& __x, const error_code& __y) 529{ 530 return __x.category() == __y.category() && __x.value() == __y.value(); 531} 532 533inline _LIBCPP_INLINE_VISIBILITY 534bool 535operator==(const error_code& __x, const error_condition& __y) 536{ 537 return __x.category().equivalent(__x.value(), __y) 538 || __y.category().equivalent(__x, __y.value()); 539} 540 541inline _LIBCPP_INLINE_VISIBILITY 542bool 543operator==(const error_condition& __x, const error_code& __y) 544{ 545 return __y == __x; 546} 547 548inline _LIBCPP_INLINE_VISIBILITY 549bool 550operator==(const error_condition& __x, const error_condition& __y) 551{ 552 return __x.category() == __y.category() && __x.value() == __y.value(); 553} 554 555inline _LIBCPP_INLINE_VISIBILITY 556bool 557operator!=(const error_code& __x, const error_code& __y) {return !(__x == __y);} 558 559inline _LIBCPP_INLINE_VISIBILITY 560bool 561operator!=(const error_code& __x, const error_condition& __y) {return !(__x == __y);} 562 563inline _LIBCPP_INLINE_VISIBILITY 564bool 565operator!=(const error_condition& __x, const error_code& __y) {return !(__x == __y);} 566 567inline _LIBCPP_INLINE_VISIBILITY 568bool 569operator!=(const error_condition& __x, const error_condition& __y) {return !(__x == __y);} 570 571template <> 572struct hash<error_code> 573 : public unary_function<error_code, size_t> 574{ 575 size_t operator()(const error_code& __ec) const 576 { 577 return static_cast<size_t>(__ec.value()); 578 } 579}; 580 581// system_error 582 583class system_error 584 : public runtime_error 585{ 586 error_code __ec_; 587public: 588 system_error(error_code __ec, const string& __what_arg); 589 system_error(error_code __ec, const char* __what_arg); 590 system_error(error_code __ec); 591 system_error(int __ev, const error_category& __ecat, const string& __what_arg); 592 system_error(int __ev, const error_category& __ecat, const char* __what_arg); 593 system_error(int __ev, const error_category& __ecat); 594 ~system_error() throw(); 595 596 _LIBCPP_ALWAYS_INLINE 597 const error_code& code() const throw() {return __ec_;} 598 599private: 600 static string __init(const error_code&, string); 601}; 602 603void __throw_system_error(int ev, const char* what_arg); 604 605_LIBCPP_END_NAMESPACE_STD 606 607#endif // _LIBCPP_SYSTEM_ERROR 608