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>
signbit(_A1 __x)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>
signbit(_A1 __x)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>
signbit(_A1)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>
isfinite(_A1 __x)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>
isfinite(_A1)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>
isinf(_A1 __x)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>
isinf(_A1)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
isinf(float __x)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
isinf(double __x)76*5f757f3fSDimitry Andric isinf(double __x) _NOEXCEPT {
77*5f757f3fSDimitry Andric   return __builtin_isinf(__x);
78*5f757f3fSDimitry Andric }
79*5f757f3fSDimitry Andric 
isinf(long double __x)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>
isnan(_A1 __x)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>
isnan(_A1)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
isnan(float __x)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
isnan(double __x)103*5f757f3fSDimitry Andric isnan(double __x) _NOEXCEPT {
104*5f757f3fSDimitry Andric   return __builtin_isnan(__x);
105*5f757f3fSDimitry Andric }
106*5f757f3fSDimitry Andric 
isnan(long double __x)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>
isnormal(_A1 __x)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>
isnormal(_A1 __x)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>
isgreater(_A1 __x,_A2 __y)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>
isgreaterequal(_A1 __x,_A2 __y)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>
isless(_A1 __x,_A2 __y)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>
islessequal(_A1 __x,_A2 __y)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>
islessgreater(_A1 __x,_A2 __y)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>
isunordered(_A1 __x,_A2 __y)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