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