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 inline constexpr size_t is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; // C++17
     51 
     52 template <class _Tp>
     53 inline constexpr size_t is_error_code_enum_v = is_error_code_enum<_Tp>::value; // C++17
     54 
     55 class error_code
     56 {
     57 public:
     58     // constructors:
     59     error_code() noexcept;
     60     error_code(int val, const error_category& cat) noexcept;
     61     template <class ErrorCodeEnum>
     62         error_code(ErrorCodeEnum e) noexcept;
     63 
     64     // modifiers:
     65     void assign(int val, const error_category& cat) noexcept;
     66     template <class ErrorCodeEnum>
     67         error_code& operator=(ErrorCodeEnum e) noexcept;
     68     void clear() noexcept;
     69 
     70     // observers:
     71     int value() const noexcept;
     72     const error_category& category() const noexcept;
     73     error_condition default_error_condition() const noexcept;
     74     string message() const;
     75     explicit operator bool() const noexcept;
     76 };
     77 
     78 // non-member functions:
     79 bool operator<(const error_code& lhs, const error_code& rhs) noexcept;
     80 template <class charT, class traits>
     81     basic_ostream<charT,traits>&
     82     operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
     83 
     84 class error_condition
     85 {
     86 public:
     87     // constructors:
     88     error_condition() noexcept;
     89     error_condition(int val, const error_category& cat) noexcept;
     90     template <class ErrorConditionEnum>
     91         error_condition(ErrorConditionEnum e) noexcept;
     92 
     93     // modifiers:
     94     void assign(int val, const error_category& cat) noexcept;
     95     template <class ErrorConditionEnum>
     96         error_condition& operator=(ErrorConditionEnum e) noexcept;
     97     void clear() noexcept;
     98 
     99     // observers:
    100     int value() const noexcept;
    101     const error_category& category() const noexcept;
    102     string message() const noexcept;
    103     explicit operator bool() const noexcept;
    104 };
    105 
    106 bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
    107 
    108 class system_error
    109     : public runtime_error
    110 {
    111 public:
    112     system_error(error_code ec, const string& what_arg);
    113     system_error(error_code ec, const char* what_arg);
    114     system_error(error_code ec);
    115     system_error(int ev, const error_category& ecat, const string& what_arg);
    116     system_error(int ev, const error_category& ecat, const char* what_arg);
    117     system_error(int ev, const error_category& ecat);
    118 
    119     const error_code& code() const noexcept;
    120     const char* what() const noexcept;
    121 };
    122 
    123 template <> struct is_error_condition_enum<errc>
    124     : true_type { }
    125 
    126 error_code make_error_code(errc e) noexcept;
    127 error_condition make_error_condition(errc e) noexcept;
    128 
    129 // Comparison operators:
    130 bool operator==(const error_code& lhs, const error_code& rhs) noexcept;
    131 bool operator==(const error_code& lhs, const error_condition& rhs) noexcept;
    132 bool operator==(const error_condition& lhs, const error_code& rhs) noexcept;
    133 bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;
    134 bool operator!=(const error_code& lhs, const error_code& rhs) noexcept;
    135 bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept;
    136 bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept;
    137 bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept;
    138 
    139 template <> struct hash<std::error_code>;
    140 template <> struct hash<std::error_condition>;
    141 
    142 }  // std
    143 
    144 */
    145 
    146 #include <__errc>
    147 #include <type_traits>
    148 #include <stdexcept>
    149 #include <__functional_base>
    150 #include <string>
    151 
    152 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
    153 #pragma GCC system_header
    154 #endif
    155 
    156 _LIBCPP_BEGIN_NAMESPACE_STD
    157 
    158 // is_error_code_enum
    159 
    160 template <class _Tp>
    161 struct _LIBCPP_TEMPLATE_VIS is_error_code_enum
    162     : public false_type {};
    163 
    164 #if _LIBCPP_STD_VER > 14
    165 template <class _Tp>
    166 _LIBCPP_INLINE_VAR constexpr size_t is_error_code_enum_v = is_error_code_enum<_Tp>::value;
    167 #endif
    168 
    169 // is_error_condition_enum
    170 
    171 template <class _Tp>
    172 struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum
    173     : public false_type {};
    174 
    175 #if _LIBCPP_STD_VER > 14
    176 template <class _Tp>
    177 _LIBCPP_INLINE_VAR constexpr size_t is_error_condition_enum_v = is_error_condition_enum<_Tp>::value;
    178 #endif
    179 
    180 template <>
    181 struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc>
    182     : true_type { };
    183 
    184 #ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
    185 template <>
    186 struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc::__lx>
    187     : true_type { };
    188 #endif
    189 
    190 class _LIBCPP_TYPE_VIS error_condition;
    191 class _LIBCPP_TYPE_VIS error_code;
    192 
    193 // class error_category
    194 
    195 class _LIBCPP_HIDDEN __do_message;
    196 
    197 class _LIBCPP_TYPE_VIS error_category
    198 {
    199 public:
    200     virtual ~error_category() _NOEXCEPT;
    201 
    202 #if defined(_LIBCPP_BUILDING_LIBRARY) && \
    203     defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
    204     error_category() _NOEXCEPT;
    205 #else
    206     _LIBCPP_INLINE_VISIBILITY
    207     _LIBCPP_CONSTEXPR_AFTER_CXX11 error_category() _NOEXCEPT _LIBCPP_DEFAULT
    208 #endif
    209 private:
    210     error_category(const error_category&);// = delete;
    211     error_category& operator=(const error_category&);// = delete;
    212 
    213 public:
    214     virtual const char* name() const _NOEXCEPT = 0;
    215     virtual error_condition default_error_condition(int __ev) const _NOEXCEPT;
    216     virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT;
    217     virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT;
    218     virtual string message(int __ev) const = 0;
    219 
    220     _LIBCPP_INLINE_VISIBILITY
    221     bool operator==(const error_category& __rhs) const _NOEXCEPT {return this == &__rhs;}
    222 
    223     _LIBCPP_INLINE_VISIBILITY
    224     bool operator!=(const error_category& __rhs) const _NOEXCEPT {return !(*this == __rhs);}
    225 
    226     _LIBCPP_INLINE_VISIBILITY
    227     bool operator< (const error_category& __rhs) const _NOEXCEPT {return this < &__rhs;}
    228 
    229     friend class _LIBCPP_HIDDEN __do_message;
    230 };
    231 
    232 class _LIBCPP_HIDDEN __do_message
    233     : public error_category
    234 {
    235 public:
    236     virtual string message(int ev) const;
    237 };
    238 
    239 _LIBCPP_FUNC_VIS const error_category& generic_category() _NOEXCEPT;
    240 _LIBCPP_FUNC_VIS const error_category& system_category() _NOEXCEPT;
    241 
    242 class _LIBCPP_TYPE_VIS error_condition
    243 {
    244     int __val_;
    245     const error_category* __cat_;
    246 public:
    247     _LIBCPP_INLINE_VISIBILITY
    248     error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {}
    249 
    250     _LIBCPP_INLINE_VISIBILITY
    251     error_condition(int __val, const error_category& __cat) _NOEXCEPT
    252         : __val_(__val), __cat_(&__cat) {}
    253 
    254     template <class _Ep>
    255         _LIBCPP_INLINE_VISIBILITY
    256         error_condition(_Ep __e,
    257               typename enable_if<is_error_condition_enum<_Ep>::value>::type* = 0
    258                                                                      ) _NOEXCEPT
    259             {*this = make_error_condition(__e);}
    260 
    261     _LIBCPP_INLINE_VISIBILITY
    262     void assign(int __val, const error_category& __cat) _NOEXCEPT
    263     {
    264         __val_ = __val;
    265         __cat_ = &__cat;
    266     }
    267 
    268     template <class _Ep>
    269         _LIBCPP_INLINE_VISIBILITY
    270         typename enable_if
    271         <
    272             is_error_condition_enum<_Ep>::value,
    273             error_condition&
    274         >::type
    275         operator=(_Ep __e) _NOEXCEPT
    276             {*this = make_error_condition(__e); return *this;}
    277 
    278     _LIBCPP_INLINE_VISIBILITY
    279     void clear() _NOEXCEPT
    280     {
    281         __val_ = 0;
    282         __cat_ = &generic_category();
    283     }
    284 
    285     _LIBCPP_INLINE_VISIBILITY
    286     int value() const _NOEXCEPT {return __val_;}
    287 
    288     _LIBCPP_INLINE_VISIBILITY
    289     const error_category& category() const _NOEXCEPT {return *__cat_;}
    290     string message() const;
    291 
    292     _LIBCPP_INLINE_VISIBILITY
    293         _LIBCPP_EXPLICIT
    294         operator bool() const _NOEXCEPT {return __val_ != 0;}
    295 };
    296 
    297 inline _LIBCPP_INLINE_VISIBILITY
    298 error_condition
    299 make_error_condition(errc __e) _NOEXCEPT
    300 {
    301     return error_condition(static_cast<int>(__e), generic_category());
    302 }
    303 
    304 inline _LIBCPP_INLINE_VISIBILITY
    305 bool
    306 operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT
    307 {
    308     return __x.category() < __y.category()
    309         || (__x.category() == __y.category() && __x.value() < __y.value());
    310 }
    311 
    312 // error_code
    313 
    314 class _LIBCPP_TYPE_VIS error_code
    315 {
    316     int __val_;
    317     const error_category* __cat_;
    318 public:
    319     _LIBCPP_INLINE_VISIBILITY
    320     error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {}
    321 
    322     _LIBCPP_INLINE_VISIBILITY
    323     error_code(int __val, const error_category& __cat) _NOEXCEPT
    324         : __val_(__val), __cat_(&__cat) {}
    325 
    326     template <class _Ep>
    327         _LIBCPP_INLINE_VISIBILITY
    328         error_code(_Ep __e,
    329                    typename enable_if<is_error_code_enum<_Ep>::value>::type* = 0
    330                                                                      ) _NOEXCEPT
    331             {*this = make_error_code(__e);}
    332 
    333     _LIBCPP_INLINE_VISIBILITY
    334     void assign(int __val, const error_category& __cat) _NOEXCEPT
    335     {
    336         __val_ = __val;
    337         __cat_ = &__cat;
    338     }
    339 
    340     template <class _Ep>
    341         _LIBCPP_INLINE_VISIBILITY
    342         typename enable_if
    343         <
    344             is_error_code_enum<_Ep>::value,
    345             error_code&
    346         >::type
    347         operator=(_Ep __e) _NOEXCEPT
    348             {*this = make_error_code(__e); return *this;}
    349 
    350     _LIBCPP_INLINE_VISIBILITY
    351     void clear() _NOEXCEPT
    352     {
    353         __val_ = 0;
    354         __cat_ = &system_category();
    355     }
    356 
    357     _LIBCPP_INLINE_VISIBILITY
    358     int value() const _NOEXCEPT {return __val_;}
    359 
    360     _LIBCPP_INLINE_VISIBILITY
    361     const error_category& category() const _NOEXCEPT {return *__cat_;}
    362 
    363     _LIBCPP_INLINE_VISIBILITY
    364     error_condition default_error_condition() const _NOEXCEPT
    365         {return __cat_->default_error_condition(__val_);}
    366 
    367     string message() const;
    368 
    369     _LIBCPP_INLINE_VISIBILITY
    370         _LIBCPP_EXPLICIT
    371         operator bool() const _NOEXCEPT {return __val_ != 0;}
    372 };
    373 
    374 inline _LIBCPP_INLINE_VISIBILITY
    375 error_code
    376 make_error_code(errc __e) _NOEXCEPT
    377 {
    378     return error_code(static_cast<int>(__e), generic_category());
    379 }
    380 
    381 inline _LIBCPP_INLINE_VISIBILITY
    382 bool
    383 operator<(const error_code& __x, const error_code& __y) _NOEXCEPT
    384 {
    385     return __x.category() < __y.category()
    386         || (__x.category() == __y.category() && __x.value() < __y.value());
    387 }
    388 
    389 inline _LIBCPP_INLINE_VISIBILITY
    390 bool
    391 operator==(const error_code& __x, const error_code& __y) _NOEXCEPT
    392 {
    393     return __x.category() == __y.category() && __x.value() == __y.value();
    394 }
    395 
    396 inline _LIBCPP_INLINE_VISIBILITY
    397 bool
    398 operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT
    399 {
    400     return __x.category().equivalent(__x.value(), __y)
    401         || __y.category().equivalent(__x, __y.value());
    402 }
    403 
    404 inline _LIBCPP_INLINE_VISIBILITY
    405 bool
    406 operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT
    407 {
    408     return __y == __x;
    409 }
    410 
    411 inline _LIBCPP_INLINE_VISIBILITY
    412 bool
    413 operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT
    414 {
    415     return __x.category() == __y.category() && __x.value() == __y.value();
    416 }
    417 
    418 inline _LIBCPP_INLINE_VISIBILITY
    419 bool
    420 operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT
    421 {return !(__x == __y);}
    422 
    423 inline _LIBCPP_INLINE_VISIBILITY
    424 bool
    425 operator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT
    426 {return !(__x == __y);}
    427 
    428 inline _LIBCPP_INLINE_VISIBILITY
    429 bool
    430 operator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT
    431 {return !(__x == __y);}
    432 
    433 inline _LIBCPP_INLINE_VISIBILITY
    434 bool
    435 operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT
    436 {return !(__x == __y);}
    437 
    438 template <>
    439 struct _LIBCPP_TEMPLATE_VIS hash<error_code>
    440     : public unary_function<error_code, size_t>
    441 {
    442     _LIBCPP_INLINE_VISIBILITY
    443     size_t operator()(const error_code& __ec) const _NOEXCEPT
    444     {
    445         return static_cast<size_t>(__ec.value());
    446     }
    447 };
    448 
    449 template <>
    450 struct _LIBCPP_TEMPLATE_VIS hash<error_condition>
    451     : public unary_function<error_condition, size_t>
    452 {
    453     _LIBCPP_INLINE_VISIBILITY
    454     size_t operator()(const error_condition& __ec) const _NOEXCEPT
    455     {
    456         return static_cast<size_t>(__ec.value());
    457     }
    458 };
    459 
    460 // system_error
    461 
    462 class _LIBCPP_TYPE_VIS system_error
    463     : public runtime_error
    464 {
    465     error_code __ec_;
    466 public:
    467     system_error(error_code __ec, const string& __what_arg);
    468     system_error(error_code __ec, const char* __what_arg);
    469     system_error(error_code __ec);
    470     system_error(int __ev, const error_category& __ecat, const string& __what_arg);
    471     system_error(int __ev, const error_category& __ecat, const char* __what_arg);
    472     system_error(int __ev, const error_category& __ecat);
    473     ~system_error() _NOEXCEPT;
    474 
    475     _LIBCPP_INLINE_VISIBILITY
    476     const error_code& code() const _NOEXCEPT {return __ec_;}
    477 
    478 private:
    479     static string __init(const error_code&, string);
    480 };
    481 
    482 _LIBCPP_NORETURN _LIBCPP_FUNC_VIS
    483 void __throw_system_error(int ev, const char* what_arg);
    484 
    485 _LIBCPP_END_NAMESPACE_STD
    486 
    487 #endif  // _LIBCPP_SYSTEM_ERROR
    488