1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef _LIBCPP___MATH_TRAITS_H 10 #define _LIBCPP___MATH_TRAITS_H 11 12 #include <__config> 13 #include <__type_traits/enable_if.h> 14 #include <__type_traits/is_arithmetic.h> 15 #include <__type_traits/is_floating_point.h> 16 #include <__type_traits/is_integral.h> 17 #include <__type_traits/is_signed.h> 18 #include <__type_traits/promote.h> 19 #include <limits> 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 namespace __math { 28 29 // signbit 30 31 template <class _A1, __enable_if_t<is_floating_point<_A1>::value, int> = 0> 32 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { 33 return __builtin_signbit(__x); 34 } 35 36 template <class _A1, __enable_if_t<is_integral<_A1>::value && is_signed<_A1>::value, int> = 0> 37 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { 38 return __x < 0; 39 } 40 41 template <class _A1, __enable_if_t<is_integral<_A1>::value && !is_signed<_A1>::value, int> = 0> 42 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1) _NOEXCEPT { 43 return false; 44 } 45 46 // isfinite 47 48 template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && numeric_limits<_A1>::has_infinity, int> = 0> 49 _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1 __x) _NOEXCEPT { 50 return __builtin_isfinite((typename __promote<_A1>::type)__x); 51 } 52 53 template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && !numeric_limits<_A1>::has_infinity, int> = 0> 54 _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT { 55 return true; 56 } 57 58 // isinf 59 60 template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && numeric_limits<_A1>::has_infinity, int> = 0> 61 _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1 __x) _NOEXCEPT { 62 return __builtin_isinf((typename __promote<_A1>::type)__x); 63 } 64 65 template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && !numeric_limits<_A1>::has_infinity, int> = 0> 66 _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1) _NOEXCEPT { 67 return false; 68 } 69 70 #ifdef _LIBCPP_PREFERRED_OVERLOAD 71 _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT { 72 return __builtin_isinf(__x); 73 } 74 75 _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool 76 isinf(double __x) _NOEXCEPT { 77 return __builtin_isinf(__x); 78 } 79 80 _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT { 81 return __builtin_isinf(__x); 82 } 83 #endif 84 85 // isnan 86 87 template <class _A1, __enable_if_t<is_floating_point<_A1>::value, int> = 0> 88 _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1 __x) _NOEXCEPT { 89 return __builtin_isnan(__x); 90 } 91 92 template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0> 93 _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) _NOEXCEPT { 94 return false; 95 } 96 97 #ifdef _LIBCPP_PREFERRED_OVERLOAD 98 _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT { 99 return __builtin_isnan(__x); 100 } 101 102 _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool 103 isnan(double __x) _NOEXCEPT { 104 return __builtin_isnan(__x); 105 } 106 107 _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT { 108 return __builtin_isnan(__x); 109 } 110 #endif 111 112 // isnormal 113 114 template <class _A1, __enable_if_t<is_floating_point<_A1>::value, int> = 0> 115 _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { 116 return __builtin_isnormal(__x); 117 } 118 119 template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0> 120 _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { 121 return __x != 0; 122 } 123 124 // isgreater 125 126 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0> 127 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT { 128 using type = typename __promote<_A1, _A2>::type; 129 return __builtin_isgreater((type)__x, (type)__y); 130 } 131 132 // isgreaterequal 133 134 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0> 135 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT { 136 using type = typename __promote<_A1, _A2>::type; 137 return __builtin_isgreaterequal((type)__x, (type)__y); 138 } 139 140 // isless 141 142 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0> 143 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT { 144 using type = typename __promote<_A1, _A2>::type; 145 return __builtin_isless((type)__x, (type)__y); 146 } 147 148 // islessequal 149 150 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0> 151 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT { 152 using type = typename __promote<_A1, _A2>::type; 153 return __builtin_islessequal((type)__x, (type)__y); 154 } 155 156 // islessgreater 157 158 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0> 159 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT { 160 using type = typename __promote<_A1, _A2>::type; 161 return __builtin_islessgreater((type)__x, (type)__y); 162 } 163 164 // isunordered 165 166 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0> 167 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT { 168 using type = typename __promote<_A1, _A2>::type; 169 return __builtin_isunordered((type)__x, (type)__y); 170 } 171 172 } // namespace __math 173 174 _LIBCPP_END_NAMESPACE_STD 175 176 #endif // _LIBCPP___MATH_TRAITS_H 177