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/unary_function.h> 16 #include <__system_error/errc.h> 17 #include <__system_error/error_category.h> 18 #include <cstddef> 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_TYPE_VIS 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> 61 _LIBCPP_HIDE_FROM_ABI 62 error_condition(_Ep __e, typename enable_if<is_error_condition_enum<_Ep>::value>::type* = nullptr) _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> 73 _LIBCPP_HIDE_FROM_ABI typename enable_if< is_error_condition_enum<_Ep>::value, error_condition& >::type 74 operator=(_Ep __e) _NOEXCEPT { 75 using __adl_only::make_error_condition; 76 *this = make_error_condition(__e); 77 return *this; 78 } 79 80 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { 81 __val_ = 0; 82 __cat_ = &generic_category(); 83 } 84 85 _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; } 86 87 _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; } 88 string message() const; 89 90 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; } 91 }; 92 93 inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(errc __e) _NOEXCEPT { 94 return error_condition(static_cast<int>(__e), generic_category()); 95 } 96 97 inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT { 98 return __x.category() == __y.category() && __x.value() == __y.value(); 99 } 100 101 #if _LIBCPP_STD_VER <= 17 102 103 inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT { 104 return !(__x == __y); 105 } 106 107 inline _LIBCPP_HIDE_FROM_ABI bool operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT { 108 return __x.category() < __y.category() || (__x.category() == __y.category() && __x.value() < __y.value()); 109 } 110 111 #else // _LIBCPP_STD_VER <= 17 112 113 inline _LIBCPP_HIDE_FROM_ABI strong_ordering 114 operator<=>(const error_condition& __x, const error_condition& __y) noexcept { 115 if (auto __c = __x.category() <=> __y.category(); __c != 0) 116 return __c; 117 return __x.value() <=> __y.value(); 118 } 119 120 #endif // _LIBCPP_STD_VER <= 17 121 122 template <> 123 struct _LIBCPP_TEMPLATE_VIS hash<error_condition> : public __unary_function<error_condition, size_t> { 124 _LIBCPP_HIDE_FROM_ABI size_t operator()(const error_condition& __ec) const _NOEXCEPT { 125 return static_cast<size_t>(__ec.value()); 126 } 127 }; 128 129 _LIBCPP_END_NAMESPACE_STD 130 131 #endif // _LIBCPP___SYSTEM_ERROR_ERROR_CONDITION_H 132