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