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_ERROR_CONDITION_H 11 #define _LIBCPP___SYSTEM_ERROR_ERROR_CONDITION_H 12 13 #include <__compare/ordering.h> 14 #include <__config> 15 #include <__functional/hash.h> 16 #include <__functional/unary_function.h> 17 #include <__system_error/errc.h> 18 #include <__system_error/error_category.h> 19 #include <string> 20 21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 22 # pragma GCC system_header 23 #endif 24 25 _LIBCPP_BEGIN_NAMESPACE_STD 26 27 template <class _Tp> 28 struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum : public false_type {}; 29 30 #if _LIBCPP_STD_VER >= 17 31 template <class _Tp> 32 inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; 33 #endif 34 35 template <> 36 struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc> : true_type {}; 37 38 #ifdef _LIBCPP_CXX03_LANG 39 template <> 40 struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc::__lx> : true_type {}; 41 #endif 42 43 namespace __adl_only { 44 // Those cause ADL to trigger but they are not viable candidates, 45 // so they are never actually selected. 46 void make_error_condition() = delete; 47 } // namespace __adl_only 48 49 class _LIBCPP_EXPORTED_FROM_ABI error_condition { 50 int __val_; 51 const error_category* __cat_; 52 53 public: 54 _LIBCPP_HIDE_FROM_ABI error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {} 55 56 _LIBCPP_HIDE_FROM_ABI error_condition(int __val, const error_category& __cat) _NOEXCEPT 57 : __val_(__val), 58 __cat_(&__cat) {} 59 60 template <class _Ep, __enable_if_t<is_error_condition_enum<_Ep>::value, int> = 0> 61 _LIBCPP_HIDE_FROM_ABI error_condition(_Ep __e) _NOEXCEPT { 62 using __adl_only::make_error_condition; 63 *this = make_error_condition(__e); 64 } 65 66 _LIBCPP_HIDE_FROM_ABI void assign(int __val, const error_category& __cat) _NOEXCEPT { 67 __val_ = __val; 68 __cat_ = &__cat; 69 } 70 71 template <class _Ep, __enable_if_t<is_error_condition_enum<_Ep>::value, int> = 0> 72 _LIBCPP_HIDE_FROM_ABI error_condition& operator=(_Ep __e) _NOEXCEPT { 73 using __adl_only::make_error_condition; 74 *this = make_error_condition(__e); 75 return *this; 76 } 77 78 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { 79 __val_ = 0; 80 __cat_ = &generic_category(); 81 } 82 83 _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; } 84 85 _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; } 86 string message() const; 87 88 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; } 89 }; 90 91 inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(errc __e) _NOEXCEPT { 92 return error_condition(static_cast<int>(__e), generic_category()); 93 } 94 95 inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT { 96 return __x.category() == __y.category() && __x.value() == __y.value(); 97 } 98 99 #if _LIBCPP_STD_VER <= 17 100 101 inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT { 102 return !(__x == __y); 103 } 104 105 inline _LIBCPP_HIDE_FROM_ABI bool operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT { 106 return __x.category() < __y.category() || (__x.category() == __y.category() && __x.value() < __y.value()); 107 } 108 109 #else // _LIBCPP_STD_VER <= 17 110 111 inline _LIBCPP_HIDE_FROM_ABI strong_ordering 112 operator<=>(const error_condition& __x, const error_condition& __y) noexcept { 113 if (auto __c = __x.category() <=> __y.category(); __c != 0) 114 return __c; 115 return __x.value() <=> __y.value(); 116 } 117 118 #endif // _LIBCPP_STD_VER <= 17 119 120 template <> 121 struct _LIBCPP_TEMPLATE_VIS hash<error_condition> : public __unary_function<error_condition, size_t> { 122 _LIBCPP_HIDE_FROM_ABI size_t operator()(const error_condition& __ec) const _NOEXCEPT { 123 return static_cast<size_t>(__ec.value()); 124 } 125 }; 126 127 _LIBCPP_END_NAMESPACE_STD 128 129 #endif // _LIBCPP___SYSTEM_ERROR_ERROR_CONDITION_H 130