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