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; // removed in C++20 36 bool operator<(const error_category& rhs) const noexcept; // removed in C++20 37 strong_ordering operator<=>(const error_category& rhs) const noexcept; // C++20 38}; 39 40const error_category& generic_category() noexcept; 41const error_category& system_category() noexcept; 42 43template <class T> struct is_error_code_enum 44 : public false_type {}; 45 46template <class T> struct is_error_condition_enum 47 : public false_type {}; 48 49template <class _Tp> 50inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; // C++17 51 52template <class _Tp> 53inline constexpr bool is_error_code_enum_v = is_error_code_enum<_Tp>::value; // C++17 54 55class error_code 56{ 57public: 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: 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 105class system_error 106 : public runtime_error 107{ 108public: 109 system_error(error_code ec, const string& what_arg); 110 system_error(error_code ec, const char* what_arg); 111 system_error(error_code ec); 112 system_error(int ev, const error_category& ecat, const string& what_arg); 113 system_error(int ev, const error_category& ecat, const char* what_arg); 114 system_error(int ev, const error_category& ecat); 115 116 const error_code& code() const noexcept; 117 const char* what() const noexcept; 118}; 119 120template <> struct is_error_condition_enum<errc> 121 : true_type { } 122 123error_code make_error_code(errc e) noexcept; 124error_condition make_error_condition(errc e) noexcept; 125 126// Comparison operators: 127bool operator==(const error_code& lhs, const error_code& rhs) noexcept; 128bool operator==(const error_code& lhs, const error_condition& rhs) noexcept; 129bool operator==(const error_condition& lhs, const error_code& rhs) noexcept; // removed in C++20 130bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept; 131bool operator!=(const error_code& lhs, const error_code& rhs) noexcept; // removed in C++20 132bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept; // removed in C++20 133bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept; // removed in C++20 134bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept; // removed in C++20 135bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept; // removed in C++20 136bool operator<(const error_code& lhs, const error_code& rhs) noexcept; // removed in C++20 137strong_ordering operator<=>(const error_code& lhs, const error_code& rhs) noexcept; // C++20 138strong_ordering operator<=>(const error_condition& lhs, const error_condition& rhs) noexcept; // C++20 139 140template <> struct hash<std::error_code>; 141template <> struct hash<std::error_condition>; 142 143} // std 144 145*/ 146 147#include <__assert> // all public C++ headers provide the assertion handler 148#include <__config> 149#include <__errc> 150#include <__functional/hash.h> 151#include <__functional/unary_function.h> 152#include <__memory/addressof.h> 153#include <stdexcept> 154#include <string> 155#include <type_traits> 156#include <version> 157 158// standard-mandated includes 159 160// [system.error.syn] 161#include <compare> 162 163#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 164# pragma GCC system_header 165#endif 166 167_LIBCPP_BEGIN_NAMESPACE_STD 168 169// is_error_code_enum 170 171template <class _Tp> 172struct _LIBCPP_TEMPLATE_VIS is_error_code_enum 173 : public false_type {}; 174 175#if _LIBCPP_STD_VER > 14 176template <class _Tp> 177inline constexpr bool is_error_code_enum_v = is_error_code_enum<_Tp>::value; 178#endif 179 180// is_error_condition_enum 181 182template <class _Tp> 183struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum 184 : public false_type {}; 185 186#if _LIBCPP_STD_VER > 14 187template <class _Tp> 188inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; 189#endif 190 191template <> 192struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc> 193 : true_type { }; 194 195#ifdef _LIBCPP_CXX03_LANG 196template <> 197struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc::__lx> 198 : true_type { }; 199#endif 200 201class _LIBCPP_TYPE_VIS error_condition; 202class _LIBCPP_TYPE_VIS error_code; 203 204// class error_category 205 206class _LIBCPP_HIDDEN __do_message; 207 208class _LIBCPP_TYPE_VIS error_category 209{ 210public: 211 virtual ~error_category() _NOEXCEPT; 212 213#if defined(_LIBCPP_ERROR_CATEGORY_DEFINE_LEGACY_INLINE_FUNCTIONS) 214 error_category() noexcept; 215#else 216 _LIBCPP_INLINE_VISIBILITY 217 _LIBCPP_CONSTEXPR_SINCE_CXX14 error_category() _NOEXCEPT = default; 218#endif 219 error_category(const error_category&) = delete; 220 error_category& operator=(const error_category&) = delete; 221 222 virtual const char* name() const _NOEXCEPT = 0; 223 virtual error_condition default_error_condition(int __ev) const _NOEXCEPT; 224 virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT; 225 virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT; 226 virtual string message(int __ev) const = 0; 227 228 _LIBCPP_INLINE_VISIBILITY 229 bool operator==(const error_category& __rhs) const _NOEXCEPT {return this == &__rhs;} 230 231#if _LIBCPP_STD_VER > 17 232 233 _LIBCPP_HIDE_FROM_ABI 234 strong_ordering operator<=>(const error_category& __rhs) const noexcept {return compare_three_way()(this, std::addressof(__rhs));} 235 236#else // _LIBCPP_STD_VER > 17 237 238 _LIBCPP_INLINE_VISIBILITY 239 bool operator!=(const error_category& __rhs) const _NOEXCEPT {return !(*this == __rhs);} 240 241 _LIBCPP_INLINE_VISIBILITY 242 bool operator< (const error_category& __rhs) const _NOEXCEPT {return this < &__rhs;} 243 244#endif // _LIBCPP_STD_VER > 17 245 246 friend class _LIBCPP_HIDDEN __do_message; 247}; 248 249class _LIBCPP_HIDDEN __do_message 250 : public error_category 251{ 252public: 253 string message(int __ev) const override; 254}; 255 256_LIBCPP_FUNC_VIS const error_category& generic_category() _NOEXCEPT; 257_LIBCPP_FUNC_VIS const error_category& system_category() _NOEXCEPT; 258 259namespace __adl_only { 260 // Those cause ADL to trigger but they are not viable candidates, 261 // so they are never actually selected. 262 void make_error_condition() = delete; 263 void make_error_code() = delete; 264} // namespace __adl_only 265 266class _LIBCPP_TYPE_VIS error_condition 267{ 268 int __val_; 269 const error_category* __cat_; 270public: 271 _LIBCPP_INLINE_VISIBILITY 272 error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {} 273 274 _LIBCPP_INLINE_VISIBILITY 275 error_condition(int __val, const error_category& __cat) _NOEXCEPT 276 : __val_(__val), __cat_(&__cat) {} 277 278 template <class _Ep> 279 _LIBCPP_INLINE_VISIBILITY 280 error_condition(_Ep __e, 281 typename enable_if<is_error_condition_enum<_Ep>::value>::type* = nullptr 282 ) _NOEXCEPT 283 { 284 using __adl_only::make_error_condition; 285 *this = make_error_condition(__e); 286 } 287 288 _LIBCPP_INLINE_VISIBILITY 289 void assign(int __val, const error_category& __cat) _NOEXCEPT 290 { 291 __val_ = __val; 292 __cat_ = &__cat; 293 } 294 295 template <class _Ep> 296 _LIBCPP_INLINE_VISIBILITY 297 typename enable_if 298 < 299 is_error_condition_enum<_Ep>::value, 300 error_condition& 301 >::type 302 operator=(_Ep __e) _NOEXCEPT 303 { 304 using __adl_only::make_error_condition; 305 *this = make_error_condition(__e); 306 return *this; 307 } 308 309 _LIBCPP_INLINE_VISIBILITY 310 void clear() _NOEXCEPT 311 { 312 __val_ = 0; 313 __cat_ = &generic_category(); 314 } 315 316 _LIBCPP_INLINE_VISIBILITY 317 int value() const _NOEXCEPT {return __val_;} 318 319 _LIBCPP_INLINE_VISIBILITY 320 const error_category& category() const _NOEXCEPT {return *__cat_;} 321 string message() const; 322 323 _LIBCPP_INLINE_VISIBILITY 324 explicit operator bool() const _NOEXCEPT {return __val_ != 0;} 325}; 326 327inline _LIBCPP_INLINE_VISIBILITY 328error_condition 329make_error_condition(errc __e) _NOEXCEPT 330{ 331 return error_condition(static_cast<int>(__e), generic_category()); 332} 333 334// error_code 335 336class _LIBCPP_TYPE_VIS error_code 337{ 338 int __val_; 339 const error_category* __cat_; 340public: 341 _LIBCPP_INLINE_VISIBILITY 342 error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {} 343 344 _LIBCPP_INLINE_VISIBILITY 345 error_code(int __val, const error_category& __cat) _NOEXCEPT 346 : __val_(__val), __cat_(&__cat) {} 347 348 template <class _Ep> 349 _LIBCPP_INLINE_VISIBILITY 350 error_code(_Ep __e, 351 typename enable_if<is_error_code_enum<_Ep>::value>::type* = nullptr 352 ) _NOEXCEPT 353 { 354 using __adl_only::make_error_code; 355 *this = make_error_code(__e); 356 } 357 358 _LIBCPP_INLINE_VISIBILITY 359 void assign(int __val, const error_category& __cat) _NOEXCEPT 360 { 361 __val_ = __val; 362 __cat_ = &__cat; 363 } 364 365 template <class _Ep> 366 _LIBCPP_INLINE_VISIBILITY 367 typename enable_if 368 < 369 is_error_code_enum<_Ep>::value, 370 error_code& 371 >::type 372 operator=(_Ep __e) _NOEXCEPT 373 { 374 using __adl_only::make_error_code; 375 *this = make_error_code(__e); 376 return *this; 377 } 378 379 _LIBCPP_INLINE_VISIBILITY 380 void clear() _NOEXCEPT 381 { 382 __val_ = 0; 383 __cat_ = &system_category(); 384 } 385 386 _LIBCPP_INLINE_VISIBILITY 387 int value() const _NOEXCEPT {return __val_;} 388 389 _LIBCPP_INLINE_VISIBILITY 390 const error_category& category() const _NOEXCEPT {return *__cat_;} 391 392 _LIBCPP_INLINE_VISIBILITY 393 error_condition default_error_condition() const _NOEXCEPT 394 {return __cat_->default_error_condition(__val_);} 395 396 string message() const; 397 398 _LIBCPP_INLINE_VISIBILITY 399 explicit operator bool() const _NOEXCEPT {return __val_ != 0;} 400}; 401 402inline _LIBCPP_INLINE_VISIBILITY 403error_code 404make_error_code(errc __e) _NOEXCEPT 405{ 406 return error_code(static_cast<int>(__e), generic_category()); 407} 408 409inline _LIBCPP_INLINE_VISIBILITY 410bool 411operator==(const error_code& __x, const error_code& __y) _NOEXCEPT 412{ 413 return __x.category() == __y.category() && __x.value() == __y.value(); 414} 415 416inline _LIBCPP_INLINE_VISIBILITY 417bool 418operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT 419{ 420 return __x.category().equivalent(__x.value(), __y) 421 || __y.category().equivalent(__x, __y.value()); 422} 423 424#if _LIBCPP_STD_VER <= 17 425inline _LIBCPP_INLINE_VISIBILITY 426bool 427operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT 428{ 429 return __y == __x; 430} 431#endif 432 433inline _LIBCPP_INLINE_VISIBILITY 434bool 435operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT 436{ 437 return __x.category() == __y.category() && __x.value() == __y.value(); 438} 439 440#if _LIBCPP_STD_VER <= 17 441 442inline _LIBCPP_INLINE_VISIBILITY 443bool 444operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT 445{return !(__x == __y);} 446 447inline _LIBCPP_INLINE_VISIBILITY 448bool 449operator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT 450{return !(__x == __y);} 451 452inline _LIBCPP_INLINE_VISIBILITY 453bool 454operator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT 455{return !(__x == __y);} 456 457inline _LIBCPP_INLINE_VISIBILITY 458bool 459operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT 460{return !(__x == __y);} 461 462inline _LIBCPP_INLINE_VISIBILITY 463bool 464operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT 465{ 466 return __x.category() < __y.category() 467 || (__x.category() == __y.category() && __x.value() < __y.value()); 468} 469 470inline _LIBCPP_INLINE_VISIBILITY 471bool 472operator<(const error_code& __x, const error_code& __y) _NOEXCEPT 473{ 474 return __x.category() < __y.category() 475 || (__x.category() == __y.category() && __x.value() < __y.value()); 476} 477 478#else // _LIBCPP_STD_VER <= 17 479 480inline _LIBCPP_HIDE_FROM_ABI strong_ordering 481operator<=>(const error_code& __x, const error_code& __y) noexcept 482{ 483 if (auto __c = __x.category() <=> __y.category(); __c != 0) 484 return __c; 485 return __x.value() <=> __y.value(); 486} 487 488inline _LIBCPP_HIDE_FROM_ABI strong_ordering 489operator<=>(const error_condition& __x, const error_condition& __y) noexcept 490{ 491 if (auto __c = __x.category() <=> __y.category(); __c != 0) 492 return __c; 493 return __x.value() <=> __y.value(); 494} 495 496#endif // _LIBCPP_STD_VER <= 17 497 498template <> 499struct _LIBCPP_TEMPLATE_VIS hash<error_code> 500 : public __unary_function<error_code, size_t> 501{ 502 _LIBCPP_INLINE_VISIBILITY 503 size_t operator()(const error_code& __ec) const _NOEXCEPT 504 { 505 return static_cast<size_t>(__ec.value()); 506 } 507}; 508 509template <> 510struct _LIBCPP_TEMPLATE_VIS hash<error_condition> 511 : public __unary_function<error_condition, size_t> 512{ 513 _LIBCPP_INLINE_VISIBILITY 514 size_t operator()(const error_condition& __ec) const _NOEXCEPT 515 { 516 return static_cast<size_t>(__ec.value()); 517 } 518}; 519 520// system_error 521 522class _LIBCPP_TYPE_VIS system_error 523 : public runtime_error 524{ 525 error_code __ec_; 526public: 527 system_error(error_code __ec, const string& __what_arg); 528 system_error(error_code __ec, const char* __what_arg); 529 system_error(error_code __ec); 530 system_error(int __ev, const error_category& __ecat, const string& __what_arg); 531 system_error(int __ev, const error_category& __ecat, const char* __what_arg); 532 system_error(int __ev, const error_category& __ecat); 533 system_error(const system_error&) _NOEXCEPT = default; 534 ~system_error() _NOEXCEPT override; 535 536 _LIBCPP_INLINE_VISIBILITY 537 const error_code& code() const _NOEXCEPT {return __ec_;} 538 539private: 540 static string __init(const error_code&, string); 541}; 542 543_LIBCPP_NORETURN _LIBCPP_FUNC_VIS 544void __throw_system_error(int __ev, const char* __what_arg); 545 546_LIBCPP_END_NAMESPACE_STD 547 548#endif // _LIBCPP_SYSTEM_ERROR 549