LLVM API Documentation
00001 //===---------------------------- system_error ------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This was lifted from libc++ and modified for C++03. This is called 00011 // system_error even though it does not define that class because that's what 00012 // it's called in C++0x. We don't define system_error because it is only used 00013 // for exception handling, which we don't use in LLVM. 00014 // 00015 //===----------------------------------------------------------------------===// 00016 00017 #ifndef LLVM_SUPPORT_SYSTEM_ERROR_H 00018 #define LLVM_SUPPORT_SYSTEM_ERROR_H 00019 00020 #include "llvm/Support/Compiler.h" 00021 00022 /* 00023 system_error synopsis 00024 00025 namespace std 00026 { 00027 00028 class error_category 00029 { 00030 public: 00031 virtual ~error_category(); 00032 00033 error_category(const error_category&) = delete; 00034 error_category& operator=(const error_category&) = delete; 00035 00036 virtual const char* name() const = 0; 00037 virtual error_condition default_error_condition(int ev) const; 00038 virtual bool equivalent(int code, const error_condition& condition) const; 00039 virtual bool equivalent(const error_code& code, int condition) const; 00040 virtual std::string message(int ev) const = 0; 00041 00042 bool operator==(const error_category& rhs) const; 00043 bool operator!=(const error_category& rhs) const; 00044 bool operator<(const error_category& rhs) const; 00045 }; 00046 00047 const error_category& generic_category(); 00048 const error_category& system_category(); 00049 00050 template <class T> struct is_error_code_enum 00051 : public false_type {}; 00052 00053 template <class T> struct is_error_condition_enum 00054 : public false_type {}; 00055 00056 class error_code 00057 { 00058 public: 00059 // constructors: 00060 error_code(); 00061 error_code(int val, const error_category& cat); 00062 template <class ErrorCodeEnum> 00063 error_code(ErrorCodeEnum e); 00064 00065 // modifiers: 00066 void assign(int val, const error_category& cat); 00067 template <class ErrorCodeEnum> 00068 error_code& operator=(ErrorCodeEnum e); 00069 void clear(); 00070 00071 // observers: 00072 int value() const; 00073 const error_category& category() const; 00074 error_condition default_error_condition() const; 00075 std::string message() const; 00076 explicit operator bool() const; 00077 }; 00078 00079 // non-member functions: 00080 bool operator<(const error_code& lhs, const error_code& rhs); 00081 template <class charT, class traits> 00082 basic_ostream<charT,traits>& 00083 operator<<(basic_ostream<charT,traits>& os, const error_code& ec); 00084 00085 class error_condition 00086 { 00087 public: 00088 // constructors: 00089 error_condition(); 00090 error_condition(int val, const error_category& cat); 00091 template <class ErrorConditionEnum> 00092 error_condition(ErrorConditionEnum e); 00093 00094 // modifiers: 00095 void assign(int val, const error_category& cat); 00096 template <class ErrorConditionEnum> 00097 error_condition& operator=(ErrorConditionEnum e); 00098 void clear(); 00099 00100 // observers: 00101 int value() const; 00102 const error_category& category() const; 00103 std::string message() const; 00104 explicit operator bool() const; 00105 }; 00106 00107 bool operator<(const error_condition& lhs, const error_condition& rhs); 00108 00109 class system_error 00110 : public runtime_error 00111 { 00112 public: 00113 system_error(error_code ec, const std::string& what_arg); 00114 system_error(error_code ec, const char* what_arg); 00115 system_error(error_code ec); 00116 system_error(int ev, const error_category& ecat, const std::string& what_arg); 00117 system_error(int ev, const error_category& ecat, const char* what_arg); 00118 system_error(int ev, const error_category& ecat); 00119 00120 const error_code& code() const throw(); 00121 const char* what() const throw(); 00122 }; 00123 00124 enum class errc 00125 { 00126 address_family_not_supported, // EAFNOSUPPORT 00127 address_in_use, // EADDRINUSE 00128 address_not_available, // EADDRNOTAVAIL 00129 already_connected, // EISCONN 00130 argument_list_too_long, // E2BIG 00131 argument_out_of_domain, // EDOM 00132 bad_address, // EFAULT 00133 bad_file_descriptor, // EBADF 00134 bad_message, // EBADMSG 00135 broken_pipe, // EPIPE 00136 connection_aborted, // ECONNABORTED 00137 connection_already_in_progress, // EALREADY 00138 connection_refused, // ECONNREFUSED 00139 connection_reset, // ECONNRESET 00140 cross_device_link, // EXDEV 00141 destination_address_required, // EDESTADDRREQ 00142 device_or_resource_busy, // EBUSY 00143 directory_not_empty, // ENOTEMPTY 00144 executable_format_error, // ENOEXEC 00145 file_exists, // EEXIST 00146 file_too_large, // EFBIG 00147 filename_too_long, // ENAMETOOLONG 00148 function_not_supported, // ENOSYS 00149 host_unreachable, // EHOSTUNREACH 00150 identifier_removed, // EIDRM 00151 illegal_byte_sequence, // EILSEQ 00152 inappropriate_io_control_operation, // ENOTTY 00153 interrupted, // EINTR 00154 invalid_argument, // EINVAL 00155 invalid_seek, // ESPIPE 00156 io_error, // EIO 00157 is_a_directory, // EISDIR 00158 message_size, // EMSGSIZE 00159 network_down, // ENETDOWN 00160 network_reset, // ENETRESET 00161 network_unreachable, // ENETUNREACH 00162 no_buffer_space, // ENOBUFS 00163 no_child_process, // ECHILD 00164 no_link, // ENOLINK 00165 no_lock_available, // ENOLCK 00166 no_message_available, // ENODATA 00167 no_message, // ENOMSG 00168 no_protocol_option, // ENOPROTOOPT 00169 no_space_on_device, // ENOSPC 00170 no_stream_resources, // ENOSR 00171 no_such_device_or_address, // ENXIO 00172 no_such_device, // ENODEV 00173 no_such_file_or_directory, // ENOENT 00174 no_such_process, // ESRCH 00175 not_a_directory, // ENOTDIR 00176 not_a_socket, // ENOTSOCK 00177 not_a_stream, // ENOSTR 00178 not_connected, // ENOTCONN 00179 not_enough_memory, // ENOMEM 00180 not_supported, // ENOTSUP 00181 operation_canceled, // ECANCELED 00182 operation_in_progress, // EINPROGRESS 00183 operation_not_permitted, // EPERM 00184 operation_not_supported, // EOPNOTSUPP 00185 operation_would_block, // EWOULDBLOCK 00186 owner_dead, // EOWNERDEAD 00187 permission_denied, // EACCES 00188 protocol_error, // EPROTO 00189 protocol_not_supported, // EPROTONOSUPPORT 00190 read_only_file_system, // EROFS 00191 resource_deadlock_would_occur, // EDEADLK 00192 resource_unavailable_try_again, // EAGAIN 00193 result_out_of_range, // ERANGE 00194 state_not_recoverable, // ENOTRECOVERABLE 00195 stream_timeout, // ETIME 00196 text_file_busy, // ETXTBSY 00197 timed_out, // ETIMEDOUT 00198 too_many_files_open_in_system, // ENFILE 00199 too_many_files_open, // EMFILE 00200 too_many_links, // EMLINK 00201 too_many_symbolic_link_levels, // ELOOP 00202 value_too_large, // EOVERFLOW 00203 wrong_protocol_type // EPROTOTYPE 00204 }; 00205 00206 template <> struct is_error_condition_enum<errc> : true_type { } 00207 00208 error_code make_error_code(errc e); 00209 error_condition make_error_condition(errc e); 00210 00211 // Comparison operators: 00212 bool operator==(const error_code& lhs, const error_code& rhs); 00213 bool operator==(const error_code& lhs, const error_condition& rhs); 00214 bool operator==(const error_condition& lhs, const error_code& rhs); 00215 bool operator==(const error_condition& lhs, const error_condition& rhs); 00216 bool operator!=(const error_code& lhs, const error_code& rhs); 00217 bool operator!=(const error_code& lhs, const error_condition& rhs); 00218 bool operator!=(const error_condition& lhs, const error_code& rhs); 00219 bool operator!=(const error_condition& lhs, const error_condition& rhs); 00220 00221 template <> struct hash<std::error_code>; 00222 00223 } // std 00224 00225 */ 00226 00227 #include "llvm/Config/llvm-config.h" 00228 #include "llvm/Support/type_traits.h" 00229 #include <cerrno> 00230 #include <string> 00231 00232 // This must be here instead of a .inc file because it is used in the definition 00233 // of the enum values below. 00234 #ifdef LLVM_ON_WIN32 00235 00236 // The following numbers were taken from VS2010. 00237 # ifndef EAFNOSUPPORT 00238 # define EAFNOSUPPORT 102 00239 # endif 00240 # ifndef EADDRINUSE 00241 # define EADDRINUSE 100 00242 # endif 00243 # ifndef EADDRNOTAVAIL 00244 # define EADDRNOTAVAIL 101 00245 # endif 00246 # ifndef EISCONN 00247 # define EISCONN 113 00248 # endif 00249 # ifndef E2BIG 00250 # define E2BIG 7 00251 # endif 00252 # ifndef EDOM 00253 # define EDOM 33 00254 # endif 00255 # ifndef EFAULT 00256 # define EFAULT 14 00257 # endif 00258 # ifndef EBADF 00259 # define EBADF 9 00260 # endif 00261 # ifndef EBADMSG 00262 # define EBADMSG 104 00263 # endif 00264 # ifndef EPIPE 00265 # define EPIPE 32 00266 # endif 00267 # ifndef ECONNABORTED 00268 # define ECONNABORTED 106 00269 # endif 00270 # ifndef EALREADY 00271 # define EALREADY 103 00272 # endif 00273 # ifndef ECONNREFUSED 00274 # define ECONNREFUSED 107 00275 # endif 00276 # ifndef ECONNRESET 00277 # define ECONNRESET 108 00278 # endif 00279 # ifndef EXDEV 00280 # define EXDEV 18 00281 # endif 00282 # ifndef EDESTADDRREQ 00283 # define EDESTADDRREQ 109 00284 # endif 00285 # ifndef EBUSY 00286 # define EBUSY 16 00287 # endif 00288 # ifndef ENOTEMPTY 00289 # define ENOTEMPTY 41 00290 # endif 00291 # ifndef ENOEXEC 00292 # define ENOEXEC 8 00293 # endif 00294 # ifndef EEXIST 00295 # define EEXIST 17 00296 # endif 00297 # ifndef EFBIG 00298 # define EFBIG 27 00299 # endif 00300 # ifndef ENAMETOOLONG 00301 # define ENAMETOOLONG 38 00302 # endif 00303 # ifndef ENOSYS 00304 # define ENOSYS 40 00305 # endif 00306 # ifndef EHOSTUNREACH 00307 # define EHOSTUNREACH 110 00308 # endif 00309 # ifndef EIDRM 00310 # define EIDRM 111 00311 # endif 00312 # ifndef EILSEQ 00313 # define EILSEQ 42 00314 # endif 00315 # ifndef ENOTTY 00316 # define ENOTTY 25 00317 # endif 00318 # ifndef EINTR 00319 # define EINTR 4 00320 # endif 00321 # ifndef EINVAL 00322 # define EINVAL 22 00323 # endif 00324 # ifndef ESPIPE 00325 # define ESPIPE 29 00326 # endif 00327 # ifndef EIO 00328 # define EIO 5 00329 # endif 00330 # ifndef EISDIR 00331 # define EISDIR 21 00332 # endif 00333 # ifndef EMSGSIZE 00334 # define EMSGSIZE 115 00335 # endif 00336 # ifndef ENETDOWN 00337 # define ENETDOWN 116 00338 # endif 00339 # ifndef ENETRESET 00340 # define ENETRESET 117 00341 # endif 00342 # ifndef ENETUNREACH 00343 # define ENETUNREACH 118 00344 # endif 00345 # ifndef ENOBUFS 00346 # define ENOBUFS 119 00347 # endif 00348 # ifndef ECHILD 00349 # define ECHILD 10 00350 # endif 00351 # ifndef ENOLINK 00352 # define ENOLINK 121 00353 # endif 00354 # ifndef ENOLCK 00355 # define ENOLCK 39 00356 # endif 00357 # ifndef ENODATA 00358 # define ENODATA 120 00359 # endif 00360 # ifndef ENOMSG 00361 # define ENOMSG 122 00362 # endif 00363 # ifndef ENOPROTOOPT 00364 # define ENOPROTOOPT 123 00365 # endif 00366 # ifndef ENOSPC 00367 # define ENOSPC 28 00368 # endif 00369 # ifndef ENOSR 00370 # define ENOSR 124 00371 # endif 00372 # ifndef ENXIO 00373 # define ENXIO 6 00374 # endif 00375 # ifndef ENODEV 00376 # define ENODEV 19 00377 # endif 00378 # ifndef ENOENT 00379 # define ENOENT 2 00380 # endif 00381 # ifndef ESRCH 00382 # define ESRCH 3 00383 # endif 00384 # ifndef ENOTDIR 00385 # define ENOTDIR 20 00386 # endif 00387 # ifndef ENOTSOCK 00388 # define ENOTSOCK 128 00389 # endif 00390 # ifndef ENOSTR 00391 # define ENOSTR 125 00392 # endif 00393 # ifndef ENOTCONN 00394 # define ENOTCONN 126 00395 # endif 00396 # ifndef ENOMEM 00397 # define ENOMEM 12 00398 # endif 00399 # ifndef ENOTSUP 00400 # define ENOTSUP 129 00401 # endif 00402 # ifndef ECANCELED 00403 # define ECANCELED 105 00404 # endif 00405 # ifndef EINPROGRESS 00406 # define EINPROGRESS 112 00407 # endif 00408 # ifndef EPERM 00409 # define EPERM 1 00410 # endif 00411 # ifndef EOPNOTSUPP 00412 # define EOPNOTSUPP 130 00413 # endif 00414 # ifndef EWOULDBLOCK 00415 # define EWOULDBLOCK 140 00416 # endif 00417 # ifndef EOWNERDEAD 00418 # define EOWNERDEAD 133 00419 # endif 00420 # ifndef EACCES 00421 # define EACCES 13 00422 # endif 00423 # ifndef EPROTO 00424 # define EPROTO 134 00425 # endif 00426 # ifndef EPROTONOSUPPORT 00427 # define EPROTONOSUPPORT 135 00428 # endif 00429 # ifndef EROFS 00430 # define EROFS 30 00431 # endif 00432 # ifndef EDEADLK 00433 # define EDEADLK 36 00434 # endif 00435 # ifndef EAGAIN 00436 # define EAGAIN 11 00437 # endif 00438 # ifndef ERANGE 00439 # define ERANGE 34 00440 # endif 00441 # ifndef ENOTRECOVERABLE 00442 # define ENOTRECOVERABLE 127 00443 # endif 00444 # ifndef ETIME 00445 # define ETIME 137 00446 # endif 00447 # ifndef ETXTBSY 00448 # define ETXTBSY 139 00449 # endif 00450 # ifndef ETIMEDOUT 00451 # define ETIMEDOUT 138 00452 # endif 00453 # ifndef ENFILE 00454 # define ENFILE 23 00455 # endif 00456 # ifndef EMFILE 00457 # define EMFILE 24 00458 # endif 00459 # ifndef EMLINK 00460 # define EMLINK 31 00461 # endif 00462 # ifndef ELOOP 00463 # define ELOOP 114 00464 # endif 00465 # ifndef EOVERFLOW 00466 # define EOVERFLOW 132 00467 # endif 00468 # ifndef EPROTOTYPE 00469 # define EPROTOTYPE 136 00470 # endif 00471 #endif 00472 00473 namespace llvm { 00474 00475 // is_error_code_enum 00476 00477 template <class Tp> struct is_error_code_enum : public false_type {}; 00478 00479 // is_error_condition_enum 00480 00481 template <class Tp> struct is_error_condition_enum : public false_type {}; 00482 00483 // Some error codes are not present on all platforms, so we provide equivalents 00484 // for them: 00485 00486 //enum class errc 00487 struct errc { 00488 enum _ { 00489 success = 0, 00490 address_family_not_supported = EAFNOSUPPORT, 00491 address_in_use = EADDRINUSE, 00492 address_not_available = EADDRNOTAVAIL, 00493 already_connected = EISCONN, 00494 argument_list_too_long = E2BIG, 00495 argument_out_of_domain = EDOM, 00496 bad_address = EFAULT, 00497 bad_file_descriptor = EBADF, 00498 #ifdef EBADMSG 00499 bad_message = EBADMSG, 00500 #else 00501 bad_message = EINVAL, 00502 #endif 00503 broken_pipe = EPIPE, 00504 connection_aborted = ECONNABORTED, 00505 connection_already_in_progress = EALREADY, 00506 connection_refused = ECONNREFUSED, 00507 connection_reset = ECONNRESET, 00508 cross_device_link = EXDEV, 00509 destination_address_required = EDESTADDRREQ, 00510 device_or_resource_busy = EBUSY, 00511 directory_not_empty = ENOTEMPTY, 00512 executable_format_error = ENOEXEC, 00513 file_exists = EEXIST, 00514 file_too_large = EFBIG, 00515 filename_too_long = ENAMETOOLONG, 00516 function_not_supported = ENOSYS, 00517 host_unreachable = EHOSTUNREACH, 00518 identifier_removed = EIDRM, 00519 illegal_byte_sequence = EILSEQ, 00520 inappropriate_io_control_operation = ENOTTY, 00521 interrupted = EINTR, 00522 invalid_argument = EINVAL, 00523 invalid_seek = ESPIPE, 00524 io_error = EIO, 00525 is_a_directory = EISDIR, 00526 message_size = EMSGSIZE, 00527 network_down = ENETDOWN, 00528 network_reset = ENETRESET, 00529 network_unreachable = ENETUNREACH, 00530 no_buffer_space = ENOBUFS, 00531 no_child_process = ECHILD, 00532 #ifdef ENOLINK 00533 no_link = ENOLINK, 00534 #else 00535 no_link = EINVAL, 00536 #endif 00537 no_lock_available = ENOLCK, 00538 #ifdef ENODATA 00539 no_message_available = ENODATA, 00540 #else 00541 no_message_available = ENOMSG, 00542 #endif 00543 no_message = ENOMSG, 00544 no_protocol_option = ENOPROTOOPT, 00545 no_space_on_device = ENOSPC, 00546 #ifdef ENOSR 00547 no_stream_resources = ENOSR, 00548 #else 00549 no_stream_resources = ENOMEM, 00550 #endif 00551 no_such_device_or_address = ENXIO, 00552 no_such_device = ENODEV, 00553 no_such_file_or_directory = ENOENT, 00554 no_such_process = ESRCH, 00555 not_a_directory = ENOTDIR, 00556 not_a_socket = ENOTSOCK, 00557 #ifdef ENOSTR 00558 not_a_stream = ENOSTR, 00559 #else 00560 not_a_stream = EINVAL, 00561 #endif 00562 not_connected = ENOTCONN, 00563 not_enough_memory = ENOMEM, 00564 not_supported = ENOTSUP, 00565 #ifdef ECANCELED 00566 operation_canceled = ECANCELED, 00567 #else 00568 operation_canceled = EINVAL, 00569 #endif 00570 operation_in_progress = EINPROGRESS, 00571 operation_not_permitted = EPERM, 00572 operation_not_supported = EOPNOTSUPP, 00573 operation_would_block = EWOULDBLOCK, 00574 #ifdef EOWNERDEAD 00575 owner_dead = EOWNERDEAD, 00576 #else 00577 owner_dead = EINVAL, 00578 #endif 00579 permission_denied = EACCES, 00580 #ifdef EPROTO 00581 protocol_error = EPROTO, 00582 #else 00583 protocol_error = EINVAL, 00584 #endif 00585 protocol_not_supported = EPROTONOSUPPORT, 00586 read_only_file_system = EROFS, 00587 resource_deadlock_would_occur = EDEADLK, 00588 resource_unavailable_try_again = EAGAIN, 00589 result_out_of_range = ERANGE, 00590 #ifdef ENOTRECOVERABLE 00591 state_not_recoverable = ENOTRECOVERABLE, 00592 #else 00593 state_not_recoverable = EINVAL, 00594 #endif 00595 #ifdef ETIME 00596 stream_timeout = ETIME, 00597 #else 00598 stream_timeout = ETIMEDOUT, 00599 #endif 00600 text_file_busy = ETXTBSY, 00601 timed_out = ETIMEDOUT, 00602 too_many_files_open_in_system = ENFILE, 00603 too_many_files_open = EMFILE, 00604 too_many_links = EMLINK, 00605 too_many_symbolic_link_levels = ELOOP, 00606 value_too_large = EOVERFLOW, 00607 wrong_protocol_type = EPROTOTYPE 00608 }; 00609 00610 _ v_; 00611 00612 errc(_ v) : v_(v) {} 00613 operator int() const {return v_;} 00614 }; 00615 00616 template <> struct is_error_condition_enum<errc> : true_type { }; 00617 00618 template <> struct is_error_condition_enum<errc::_> : true_type { }; 00619 00620 class error_condition; 00621 class error_code; 00622 00623 // class error_category 00624 00625 class _do_message; 00626 00627 class error_category 00628 { 00629 public: 00630 virtual ~error_category(); 00631 00632 private: 00633 error_category(); 00634 error_category(const error_category&) LLVM_DELETED_FUNCTION; 00635 error_category& operator=(const error_category&) LLVM_DELETED_FUNCTION; 00636 00637 public: 00638 virtual const char* name() const = 0; 00639 virtual error_condition default_error_condition(int _ev) const; 00640 virtual bool equivalent(int _code, const error_condition& _condition) const; 00641 virtual bool equivalent(const error_code& _code, int _condition) const; 00642 virtual std::string message(int _ev) const = 0; 00643 00644 bool operator==(const error_category& _rhs) const {return this == &_rhs;} 00645 00646 bool operator!=(const error_category& _rhs) const {return !(*this == _rhs);} 00647 00648 bool operator< (const error_category& _rhs) const {return this < &_rhs;} 00649 00650 friend class _do_message; 00651 }; 00652 00653 class _do_message : public error_category 00654 { 00655 public: 00656 virtual std::string message(int ev) const LLVM_OVERRIDE; 00657 }; 00658 00659 const error_category& generic_category(); 00660 const error_category& system_category(); 00661 00662 /// Get the error_category used for errno values from POSIX functions. This is 00663 /// the same as the system_category on POSIX systems, but is the same as the 00664 /// generic_category on Windows. 00665 const error_category& posix_category(); 00666 00667 class error_condition 00668 { 00669 int _val_; 00670 const error_category* _cat_; 00671 public: 00672 error_condition() : _val_(0), _cat_(&generic_category()) {} 00673 00674 error_condition(int _val, const error_category& _cat) 00675 : _val_(_val), _cat_(&_cat) {} 00676 00677 template <class E> 00678 error_condition(E _e, typename enable_if_c< 00679 is_error_condition_enum<E>::value 00680 >::type* = 0) 00681 {*this = make_error_condition(_e);} 00682 00683 void assign(int _val, const error_category& _cat) { 00684 _val_ = _val; 00685 _cat_ = &_cat; 00686 } 00687 00688 template <class E> 00689 typename enable_if_c 00690 < 00691 is_error_condition_enum<E>::value, 00692 error_condition& 00693 >::type 00694 operator=(E _e) 00695 {*this = make_error_condition(_e); return *this;} 00696 00697 void clear() { 00698 _val_ = 0; 00699 _cat_ = &generic_category(); 00700 } 00701 00702 int value() const {return _val_;} 00703 00704 const error_category& category() const {return *_cat_;} 00705 std::string message() const; 00706 00707 typedef void (*unspecified_bool_type)(); 00708 static void unspecified_bool_true() {} 00709 00710 operator unspecified_bool_type() const { // true if error 00711 return _val_ == 0 ? 0 : unspecified_bool_true; 00712 } 00713 }; 00714 00715 inline error_condition make_error_condition(errc _e) { 00716 return error_condition(static_cast<int>(_e), generic_category()); 00717 } 00718 00719 inline bool operator<(const error_condition& _x, const error_condition& _y) { 00720 return _x.category() < _y.category() 00721 || (_x.category() == _y.category() && _x.value() < _y.value()); 00722 } 00723 00724 // error_code 00725 00726 class error_code { 00727 int _val_; 00728 const error_category* _cat_; 00729 public: 00730 error_code() : _val_(0), _cat_(&system_category()) {} 00731 00732 static error_code success() { 00733 return error_code(); 00734 } 00735 00736 error_code(int _val, const error_category& _cat) 00737 : _val_(_val), _cat_(&_cat) {} 00738 00739 template <class E> 00740 error_code(E _e, typename enable_if_c< 00741 is_error_code_enum<E>::value 00742 >::type* = 0) { 00743 *this = make_error_code(_e); 00744 } 00745 00746 void assign(int _val, const error_category& _cat) { 00747 _val_ = _val; 00748 _cat_ = &_cat; 00749 } 00750 00751 template <class E> 00752 typename enable_if_c 00753 < 00754 is_error_code_enum<E>::value, 00755 error_code& 00756 >::type 00757 operator=(E _e) 00758 {*this = make_error_code(_e); return *this;} 00759 00760 void clear() { 00761 _val_ = 0; 00762 _cat_ = &system_category(); 00763 } 00764 00765 int value() const {return _val_;} 00766 00767 const error_category& category() const {return *_cat_;} 00768 00769 error_condition default_error_condition() const 00770 {return _cat_->default_error_condition(_val_);} 00771 00772 std::string message() const; 00773 00774 typedef void (*unspecified_bool_type)(); 00775 static void unspecified_bool_true() {} 00776 00777 operator unspecified_bool_type() const { // true if error 00778 return _val_ == 0 ? 0 : unspecified_bool_true; 00779 } 00780 }; 00781 00782 inline error_code make_error_code(errc _e) { 00783 return error_code(static_cast<int>(_e), generic_category()); 00784 } 00785 00786 inline bool operator<(const error_code& _x, const error_code& _y) { 00787 return _x.category() < _y.category() 00788 || (_x.category() == _y.category() && _x.value() < _y.value()); 00789 } 00790 00791 inline bool operator==(const error_code& _x, const error_code& _y) { 00792 return _x.category() == _y.category() && _x.value() == _y.value(); 00793 } 00794 00795 inline bool operator==(const error_code& _x, const error_condition& _y) { 00796 return _x.category().equivalent(_x.value(), _y) 00797 || _y.category().equivalent(_x, _y.value()); 00798 } 00799 00800 inline bool operator==(const error_condition& _x, const error_code& _y) { 00801 return _y == _x; 00802 } 00803 00804 inline bool operator==(const error_condition& _x, const error_condition& _y) { 00805 return _x.category() == _y.category() && _x.value() == _y.value(); 00806 } 00807 00808 inline bool operator!=(const error_code& _x, const error_code& _y) { 00809 return !(_x == _y); 00810 } 00811 00812 inline bool operator!=(const error_code& _x, const error_condition& _y) { 00813 return !(_x == _y); 00814 } 00815 00816 inline bool operator!=(const error_condition& _x, const error_code& _y) { 00817 return !(_x == _y); 00818 } 00819 00820 inline bool operator!=(const error_condition& _x, const error_condition& _y) { 00821 return !(_x == _y); 00822 } 00823 00824 // Windows errors. 00825 00826 // To construct an error_code after an API error: 00827 // 00828 // error_code( ::GetLastError(), system_category() ) 00829 struct windows_error { 00830 enum _ { 00831 success = 0, 00832 // These names and values are based on Windows WinError.h 00833 // This is not a complete list. Add to this list if you need to explicitly 00834 // check for it. 00835 invalid_function = 1, // ERROR_INVALID_FUNCTION, 00836 file_not_found = 2, // ERROR_FILE_NOT_FOUND, 00837 path_not_found = 3, // ERROR_PATH_NOT_FOUND, 00838 too_many_open_files = 4, // ERROR_TOO_MANY_OPEN_FILES, 00839 access_denied = 5, // ERROR_ACCESS_DENIED, 00840 invalid_handle = 6, // ERROR_INVALID_HANDLE, 00841 arena_trashed = 7, // ERROR_ARENA_TRASHED, 00842 not_enough_memory = 8, // ERROR_NOT_ENOUGH_MEMORY, 00843 invalid_block = 9, // ERROR_INVALID_BLOCK, 00844 bad_environment = 10, // ERROR_BAD_ENVIRONMENT, 00845 bad_format = 11, // ERROR_BAD_FORMAT, 00846 invalid_access = 12, // ERROR_INVALID_ACCESS, 00847 outofmemory = 14, // ERROR_OUTOFMEMORY, 00848 invalid_drive = 15, // ERROR_INVALID_DRIVE, 00849 current_directory = 16, // ERROR_CURRENT_DIRECTORY, 00850 not_same_device = 17, // ERROR_NOT_SAME_DEVICE, 00851 no_more_files = 18, // ERROR_NO_MORE_FILES, 00852 write_protect = 19, // ERROR_WRITE_PROTECT, 00853 bad_unit = 20, // ERROR_BAD_UNIT, 00854 not_ready = 21, // ERROR_NOT_READY, 00855 bad_command = 22, // ERROR_BAD_COMMAND, 00856 crc = 23, // ERROR_CRC, 00857 bad_length = 24, // ERROR_BAD_LENGTH, 00858 seek = 25, // ERROR_SEEK, 00859 not_dos_disk = 26, // ERROR_NOT_DOS_DISK, 00860 sector_not_found = 27, // ERROR_SECTOR_NOT_FOUND, 00861 out_of_paper = 28, // ERROR_OUT_OF_PAPER, 00862 write_fault = 29, // ERROR_WRITE_FAULT, 00863 read_fault = 30, // ERROR_READ_FAULT, 00864 gen_failure = 31, // ERROR_GEN_FAILURE, 00865 sharing_violation = 32, // ERROR_SHARING_VIOLATION, 00866 lock_violation = 33, // ERROR_LOCK_VIOLATION, 00867 wrong_disk = 34, // ERROR_WRONG_DISK, 00868 sharing_buffer_exceeded = 36, // ERROR_SHARING_BUFFER_EXCEEDED, 00869 handle_eof = 38, // ERROR_HANDLE_EOF, 00870 handle_disk_full = 39, // ERROR_HANDLE_DISK_FULL, 00871 rem_not_list = 51, // ERROR_REM_NOT_LIST, 00872 dup_name = 52, // ERROR_DUP_NAME, 00873 bad_net_path = 53, // ERROR_BAD_NETPATH, 00874 network_busy = 54, // ERROR_NETWORK_BUSY, 00875 file_exists = 80, // ERROR_FILE_EXISTS, 00876 cannot_make = 82, // ERROR_CANNOT_MAKE, 00877 broken_pipe = 109, // ERROR_BROKEN_PIPE, 00878 open_failed = 110, // ERROR_OPEN_FAILED, 00879 buffer_overflow = 111, // ERROR_BUFFER_OVERFLOW, 00880 disk_full = 112, // ERROR_DISK_FULL, 00881 insufficient_buffer = 122, // ERROR_INSUFFICIENT_BUFFER, 00882 lock_failed = 167, // ERROR_LOCK_FAILED, 00883 busy = 170, // ERROR_BUSY, 00884 cancel_violation = 173, // ERROR_CANCEL_VIOLATION, 00885 already_exists = 183 // ERROR_ALREADY_EXISTS 00886 }; 00887 _ v_; 00888 00889 windows_error(_ v) : v_(v) {} 00890 explicit windows_error(int v) : v_(_(v)) {} 00891 operator int() const {return v_;} 00892 }; 00893 00894 00895 template <> struct is_error_code_enum<windows_error> : true_type { }; 00896 00897 template <> struct is_error_code_enum<windows_error::_> : true_type { }; 00898 00899 inline error_code make_error_code(windows_error e) { 00900 return error_code(static_cast<int>(e), system_category()); 00901 } 00902 00903 } // end namespace llvm 00904 00905 #endif