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