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