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 <__config> 146#include <__errc> 147#include <__functional/unary_function.h> 148#include <__functional_base> 149#include <compare> 150#include <stdexcept> 151#include <string> 152#include <type_traits> 153 154#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 155#pragma GCC system_header 156#endif 157 158_LIBCPP_BEGIN_NAMESPACE_STD 159 160// is_error_code_enum 161 162template <class _Tp> 163struct _LIBCPP_TEMPLATE_VIS is_error_code_enum 164 : public false_type {}; 165 166#if _LIBCPP_STD_VER > 14 167template <class _Tp> 168inline constexpr bool is_error_code_enum_v = is_error_code_enum<_Tp>::value; 169#endif 170 171// is_error_condition_enum 172 173template <class _Tp> 174struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum 175 : public false_type {}; 176 177#if _LIBCPP_STD_VER > 14 178template <class _Tp> 179inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; 180#endif 181 182template <> 183struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc> 184 : true_type { }; 185 186#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS 187template <> 188struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc::__lx> 189 : true_type { }; 190#endif 191 192class _LIBCPP_TYPE_VIS error_condition; 193class _LIBCPP_TYPE_VIS error_code; 194 195// class error_category 196 197class _LIBCPP_HIDDEN __do_message; 198 199class _LIBCPP_TYPE_VIS error_category 200{ 201public: 202 virtual ~error_category() _NOEXCEPT; 203 204#if defined(_LIBCPP_BUILDING_LIBRARY) && \ 205 defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) 206 error_category() _NOEXCEPT; 207#else 208 _LIBCPP_INLINE_VISIBILITY 209 _LIBCPP_CONSTEXPR_AFTER_CXX11 error_category() _NOEXCEPT _LIBCPP_DEFAULT 210#endif 211private: 212 error_category(const error_category&);// = delete; 213 error_category& operator=(const error_category&);// = delete; 214 215public: 216 virtual const char* name() const _NOEXCEPT = 0; 217 virtual error_condition default_error_condition(int __ev) const _NOEXCEPT; 218 virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT; 219 virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT; 220 virtual string message(int __ev) const = 0; 221 222 _LIBCPP_INLINE_VISIBILITY 223 bool operator==(const error_category& __rhs) const _NOEXCEPT {return this == &__rhs;} 224 225 _LIBCPP_INLINE_VISIBILITY 226 bool operator!=(const error_category& __rhs) const _NOEXCEPT {return !(*this == __rhs);} 227 228 _LIBCPP_INLINE_VISIBILITY 229 bool operator< (const error_category& __rhs) const _NOEXCEPT {return this < &__rhs;} 230 231 friend class _LIBCPP_HIDDEN __do_message; 232}; 233 234class _LIBCPP_HIDDEN __do_message 235 : public error_category 236{ 237public: 238 virtual string message(int ev) const; 239}; 240 241_LIBCPP_FUNC_VIS const error_category& generic_category() _NOEXCEPT; 242_LIBCPP_FUNC_VIS const error_category& system_category() _NOEXCEPT; 243 244class _LIBCPP_TYPE_VIS error_condition 245{ 246 int __val_; 247 const error_category* __cat_; 248public: 249 _LIBCPP_INLINE_VISIBILITY 250 error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {} 251 252 _LIBCPP_INLINE_VISIBILITY 253 error_condition(int __val, const error_category& __cat) _NOEXCEPT 254 : __val_(__val), __cat_(&__cat) {} 255 256 template <class _Ep> 257 _LIBCPP_INLINE_VISIBILITY 258 error_condition(_Ep __e, 259 typename enable_if<is_error_condition_enum<_Ep>::value>::type* = nullptr 260 ) _NOEXCEPT 261 {*this = make_error_condition(__e);} 262 263 _LIBCPP_INLINE_VISIBILITY 264 void assign(int __val, const error_category& __cat) _NOEXCEPT 265 { 266 __val_ = __val; 267 __cat_ = &__cat; 268 } 269 270 template <class _Ep> 271 _LIBCPP_INLINE_VISIBILITY 272 typename enable_if 273 < 274 is_error_condition_enum<_Ep>::value, 275 error_condition& 276 >::type 277 operator=(_Ep __e) _NOEXCEPT 278 {*this = make_error_condition(__e); return *this;} 279 280 _LIBCPP_INLINE_VISIBILITY 281 void clear() _NOEXCEPT 282 { 283 __val_ = 0; 284 __cat_ = &generic_category(); 285 } 286 287 _LIBCPP_INLINE_VISIBILITY 288 int value() const _NOEXCEPT {return __val_;} 289 290 _LIBCPP_INLINE_VISIBILITY 291 const error_category& category() const _NOEXCEPT {return *__cat_;} 292 string message() const; 293 294 _LIBCPP_INLINE_VISIBILITY 295 explicit operator bool() const _NOEXCEPT {return __val_ != 0;} 296}; 297 298inline _LIBCPP_INLINE_VISIBILITY 299error_condition 300make_error_condition(errc __e) _NOEXCEPT 301{ 302 return error_condition(static_cast<int>(__e), generic_category()); 303} 304 305inline _LIBCPP_INLINE_VISIBILITY 306bool 307operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT 308{ 309 return __x.category() < __y.category() 310 || (__x.category() == __y.category() && __x.value() < __y.value()); 311} 312 313// error_code 314 315class _LIBCPP_TYPE_VIS error_code 316{ 317 int __val_; 318 const error_category* __cat_; 319public: 320 _LIBCPP_INLINE_VISIBILITY 321 error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {} 322 323 _LIBCPP_INLINE_VISIBILITY 324 error_code(int __val, const error_category& __cat) _NOEXCEPT 325 : __val_(__val), __cat_(&__cat) {} 326 327 template <class _Ep> 328 _LIBCPP_INLINE_VISIBILITY 329 error_code(_Ep __e, 330 typename enable_if<is_error_code_enum<_Ep>::value>::type* = nullptr 331 ) _NOEXCEPT 332 {*this = make_error_code(__e);} 333 334 _LIBCPP_INLINE_VISIBILITY 335 void assign(int __val, const error_category& __cat) _NOEXCEPT 336 { 337 __val_ = __val; 338 __cat_ = &__cat; 339 } 340 341 template <class _Ep> 342 _LIBCPP_INLINE_VISIBILITY 343 typename enable_if 344 < 345 is_error_code_enum<_Ep>::value, 346 error_code& 347 >::type 348 operator=(_Ep __e) _NOEXCEPT 349 {*this = make_error_code(__e); return *this;} 350 351 _LIBCPP_INLINE_VISIBILITY 352 void clear() _NOEXCEPT 353 { 354 __val_ = 0; 355 __cat_ = &system_category(); 356 } 357 358 _LIBCPP_INLINE_VISIBILITY 359 int value() const _NOEXCEPT {return __val_;} 360 361 _LIBCPP_INLINE_VISIBILITY 362 const error_category& category() const _NOEXCEPT {return *__cat_;} 363 364 _LIBCPP_INLINE_VISIBILITY 365 error_condition default_error_condition() const _NOEXCEPT 366 {return __cat_->default_error_condition(__val_);} 367 368 string message() const; 369 370 _LIBCPP_INLINE_VISIBILITY 371 explicit operator bool() const _NOEXCEPT {return __val_ != 0;} 372}; 373 374inline _LIBCPP_INLINE_VISIBILITY 375error_code 376make_error_code(errc __e) _NOEXCEPT 377{ 378 return error_code(static_cast<int>(__e), generic_category()); 379} 380 381inline _LIBCPP_INLINE_VISIBILITY 382bool 383operator<(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 389inline _LIBCPP_INLINE_VISIBILITY 390bool 391operator==(const error_code& __x, const error_code& __y) _NOEXCEPT 392{ 393 return __x.category() == __y.category() && __x.value() == __y.value(); 394} 395 396inline _LIBCPP_INLINE_VISIBILITY 397bool 398operator==(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 404inline _LIBCPP_INLINE_VISIBILITY 405bool 406operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT 407{ 408 return __y == __x; 409} 410 411inline _LIBCPP_INLINE_VISIBILITY 412bool 413operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT 414{ 415 return __x.category() == __y.category() && __x.value() == __y.value(); 416} 417 418inline _LIBCPP_INLINE_VISIBILITY 419bool 420operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT 421{return !(__x == __y);} 422 423inline _LIBCPP_INLINE_VISIBILITY 424bool 425operator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT 426{return !(__x == __y);} 427 428inline _LIBCPP_INLINE_VISIBILITY 429bool 430operator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT 431{return !(__x == __y);} 432 433inline _LIBCPP_INLINE_VISIBILITY 434bool 435operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT 436{return !(__x == __y);} 437 438template <> 439struct _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 449template <> 450struct _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 462class _LIBCPP_TYPE_VIS system_error 463 : public runtime_error 464{ 465 error_code __ec_; 466public: 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(const system_error&) _NOEXCEPT = default; 474 ~system_error() _NOEXCEPT; 475 476 _LIBCPP_INLINE_VISIBILITY 477 const error_code& code() const _NOEXCEPT {return __ec_;} 478 479private: 480 static string __init(const error_code&, string); 481}; 482 483_LIBCPP_NORETURN _LIBCPP_FUNC_VIS 484void __throw_system_error(int ev, const char* what_arg); 485 486_LIBCPP_END_NAMESPACE_STD 487 488#endif // _LIBCPP_SYSTEM_ERROR 489