15f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 25f757f3fSDimitry Andric // 35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65f757f3fSDimitry Andric // 75f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 85f757f3fSDimitry Andric 95f757f3fSDimitry Andric #ifndef _LIBCPP___MATH_TRAITS_H 105f757f3fSDimitry Andric #define _LIBCPP___MATH_TRAITS_H 115f757f3fSDimitry Andric 125f757f3fSDimitry Andric #include <__config> 135f757f3fSDimitry Andric #include <__type_traits/enable_if.h> 145f757f3fSDimitry Andric #include <__type_traits/is_arithmetic.h> 155f757f3fSDimitry Andric #include <__type_traits/is_floating_point.h> 165f757f3fSDimitry Andric #include <__type_traits/is_integral.h> 175f757f3fSDimitry Andric #include <__type_traits/is_signed.h> 185f757f3fSDimitry Andric #include <__type_traits/promote.h> 195f757f3fSDimitry Andric #include <limits> 205f757f3fSDimitry Andric 215f757f3fSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 225f757f3fSDimitry Andric # pragma GCC system_header 235f757f3fSDimitry Andric #endif 245f757f3fSDimitry Andric 255f757f3fSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 265f757f3fSDimitry Andric 275f757f3fSDimitry Andric namespace __math { 285f757f3fSDimitry Andric 295f757f3fSDimitry Andric // signbit 305f757f3fSDimitry Andric 315f757f3fSDimitry Andric template <class _A1, __enable_if_t<is_floating_point<_A1>::value, int> = 0> 32*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { 335f757f3fSDimitry Andric return __builtin_signbit(__x); 345f757f3fSDimitry Andric } 355f757f3fSDimitry Andric 365f757f3fSDimitry Andric template <class _A1, __enable_if_t<is_integral<_A1>::value && is_signed<_A1>::value, int> = 0> 37*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { 385f757f3fSDimitry Andric return __x < 0; 395f757f3fSDimitry Andric } 405f757f3fSDimitry Andric 415f757f3fSDimitry Andric template <class _A1, __enable_if_t<is_integral<_A1>::value && !is_signed<_A1>::value, int> = 0> 42*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1) _NOEXCEPT { 435f757f3fSDimitry Andric return false; 445f757f3fSDimitry Andric } 455f757f3fSDimitry Andric 465f757f3fSDimitry Andric // isfinite 475f757f3fSDimitry Andric 485f757f3fSDimitry Andric template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && numeric_limits<_A1>::has_infinity, int> = 0> 49*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1 __x) _NOEXCEPT { 505f757f3fSDimitry Andric return __builtin_isfinite((typename __promote<_A1>::type)__x); 515f757f3fSDimitry Andric } 525f757f3fSDimitry Andric 535f757f3fSDimitry Andric template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && !numeric_limits<_A1>::has_infinity, int> = 0> 54*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT { 555f757f3fSDimitry Andric return true; 565f757f3fSDimitry Andric } 575f757f3fSDimitry Andric 58*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(float __x) _NOEXCEPT { 59*0fca6ea1SDimitry Andric return __builtin_isfinite(__x); 60*0fca6ea1SDimitry Andric } 61*0fca6ea1SDimitry Andric 62*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(double __x) _NOEXCEPT { 63*0fca6ea1SDimitry Andric return __builtin_isfinite(__x); 64*0fca6ea1SDimitry Andric } 65*0fca6ea1SDimitry Andric 66*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(long double __x) _NOEXCEPT { 67*0fca6ea1SDimitry Andric return __builtin_isfinite(__x); 68*0fca6ea1SDimitry Andric } 69*0fca6ea1SDimitry Andric 705f757f3fSDimitry Andric // isinf 715f757f3fSDimitry Andric 725f757f3fSDimitry Andric template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && numeric_limits<_A1>::has_infinity, int> = 0> 73*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1 __x) _NOEXCEPT { 745f757f3fSDimitry Andric return __builtin_isinf((typename __promote<_A1>::type)__x); 755f757f3fSDimitry Andric } 765f757f3fSDimitry Andric 775f757f3fSDimitry Andric template <class _A1, __enable_if_t<is_arithmetic<_A1>::value && !numeric_limits<_A1>::has_infinity, int> = 0> 78*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1) _NOEXCEPT { 795f757f3fSDimitry Andric return false; 805f757f3fSDimitry Andric } 815f757f3fSDimitry Andric 825f757f3fSDimitry Andric #ifdef _LIBCPP_PREFERRED_OVERLOAD 83*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT { 845f757f3fSDimitry Andric return __builtin_isinf(__x); 855f757f3fSDimitry Andric } 865f757f3fSDimitry Andric 87*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool 885f757f3fSDimitry Andric isinf(double __x) _NOEXCEPT { 895f757f3fSDimitry Andric return __builtin_isinf(__x); 905f757f3fSDimitry Andric } 915f757f3fSDimitry Andric 92*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT { 935f757f3fSDimitry Andric return __builtin_isinf(__x); 945f757f3fSDimitry Andric } 955f757f3fSDimitry Andric #endif 965f757f3fSDimitry Andric 975f757f3fSDimitry Andric // isnan 985f757f3fSDimitry Andric 995f757f3fSDimitry Andric template <class _A1, __enable_if_t<is_floating_point<_A1>::value, int> = 0> 100*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1 __x) _NOEXCEPT { 1015f757f3fSDimitry Andric return __builtin_isnan(__x); 1025f757f3fSDimitry Andric } 1035f757f3fSDimitry Andric 1045f757f3fSDimitry Andric template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0> 105*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) _NOEXCEPT { 1065f757f3fSDimitry Andric return false; 1075f757f3fSDimitry Andric } 1085f757f3fSDimitry Andric 1095f757f3fSDimitry Andric #ifdef _LIBCPP_PREFERRED_OVERLOAD 110*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT { 1115f757f3fSDimitry Andric return __builtin_isnan(__x); 1125f757f3fSDimitry Andric } 1135f757f3fSDimitry Andric 114*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool 1155f757f3fSDimitry Andric isnan(double __x) _NOEXCEPT { 1165f757f3fSDimitry Andric return __builtin_isnan(__x); 1175f757f3fSDimitry Andric } 1185f757f3fSDimitry Andric 119*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT { 1205f757f3fSDimitry Andric return __builtin_isnan(__x); 1215f757f3fSDimitry Andric } 1225f757f3fSDimitry Andric #endif 1235f757f3fSDimitry Andric 1245f757f3fSDimitry Andric // isnormal 1255f757f3fSDimitry Andric 1265f757f3fSDimitry Andric template <class _A1, __enable_if_t<is_floating_point<_A1>::value, int> = 0> 127*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { 1285f757f3fSDimitry Andric return __builtin_isnormal(__x); 1295f757f3fSDimitry Andric } 1305f757f3fSDimitry Andric 1315f757f3fSDimitry Andric template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0> 132*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { 1335f757f3fSDimitry Andric return __x != 0; 1345f757f3fSDimitry Andric } 1355f757f3fSDimitry Andric 1365f757f3fSDimitry Andric // isgreater 1375f757f3fSDimitry Andric 1385f757f3fSDimitry Andric template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0> 139*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT { 1405f757f3fSDimitry Andric using type = typename __promote<_A1, _A2>::type; 1415f757f3fSDimitry Andric return __builtin_isgreater((type)__x, (type)__y); 1425f757f3fSDimitry Andric } 1435f757f3fSDimitry Andric 1445f757f3fSDimitry Andric // isgreaterequal 1455f757f3fSDimitry Andric 1465f757f3fSDimitry Andric template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0> 147*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT { 1485f757f3fSDimitry Andric using type = typename __promote<_A1, _A2>::type; 1495f757f3fSDimitry Andric return __builtin_isgreaterequal((type)__x, (type)__y); 1505f757f3fSDimitry Andric } 1515f757f3fSDimitry Andric 1525f757f3fSDimitry Andric // isless 1535f757f3fSDimitry Andric 1545f757f3fSDimitry Andric template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0> 155*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT { 1565f757f3fSDimitry Andric using type = typename __promote<_A1, _A2>::type; 1575f757f3fSDimitry Andric return __builtin_isless((type)__x, (type)__y); 1585f757f3fSDimitry Andric } 1595f757f3fSDimitry Andric 1605f757f3fSDimitry Andric // islessequal 1615f757f3fSDimitry Andric 1625f757f3fSDimitry Andric template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0> 163*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT { 1645f757f3fSDimitry Andric using type = typename __promote<_A1, _A2>::type; 1655f757f3fSDimitry Andric return __builtin_islessequal((type)__x, (type)__y); 1665f757f3fSDimitry Andric } 1675f757f3fSDimitry Andric 1685f757f3fSDimitry Andric // islessgreater 1695f757f3fSDimitry Andric 1705f757f3fSDimitry Andric template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0> 171*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT { 1725f757f3fSDimitry Andric using type = typename __promote<_A1, _A2>::type; 1735f757f3fSDimitry Andric return __builtin_islessgreater((type)__x, (type)__y); 1745f757f3fSDimitry Andric } 1755f757f3fSDimitry Andric 1765f757f3fSDimitry Andric // isunordered 1775f757f3fSDimitry Andric 1785f757f3fSDimitry Andric template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0> 179*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT { 1805f757f3fSDimitry Andric using type = typename __promote<_A1, _A2>::type; 1815f757f3fSDimitry Andric return __builtin_isunordered((type)__x, (type)__y); 1825f757f3fSDimitry Andric } 1835f757f3fSDimitry Andric 1845f757f3fSDimitry Andric } // namespace __math 1855f757f3fSDimitry Andric 1865f757f3fSDimitry Andric _LIBCPP_END_NAMESPACE_STD 1875f757f3fSDimitry Andric 1885f757f3fSDimitry Andric #endif // _LIBCPP___MATH_TRAITS_H 189