xref: /freebsd-src/contrib/llvm-project/libcxx/include/__math/traits.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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