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