17 #ifndef KOKKOS_NUMERIC_TRAITS_HPP
18 #define KOKKOS_NUMERIC_TRAITS_HPP
19 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
20 #define KOKKOS_IMPL_PUBLIC_INCLUDE
21 #define KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_NUMERIC_TRAITS
24 #include <Kokkos_Macros.hpp>
25 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
26 #include <Kokkos_ReductionIdentity.hpp>
32 #include <type_traits>
34 namespace Kokkos::Experimental {
37 template <
class>
struct infinity_helper {};
38 template <>
struct infinity_helper<float> {
static constexpr
float value = HUGE_VALF; };
39 template <>
struct infinity_helper<double> {
static constexpr
double value = HUGE_VAL; };
40 template <>
struct infinity_helper<long double> {
static constexpr
long double value = HUGE_VALL; };
41 template <
class>
struct finite_min_helper {};
42 template <>
struct finite_min_helper<bool> {
static constexpr
bool value =
false; };
43 template <>
struct finite_min_helper<char> {
static constexpr
char value = CHAR_MIN; };
44 template <>
struct finite_min_helper<signed char> {
static constexpr
signed char value = SCHAR_MIN; };
45 template <>
struct finite_min_helper<unsigned char> {
static constexpr
unsigned char value = 0; };
46 template <>
struct finite_min_helper<short> {
static constexpr
short value = SHRT_MIN; };
47 template <>
struct finite_min_helper<unsigned short> {
static constexpr
unsigned short value = 0; };
48 template <>
struct finite_min_helper<int> {
static constexpr
int value = INT_MIN; };
49 template <>
struct finite_min_helper<unsigned int> {
static constexpr
unsigned int value = 0; };
50 template <>
struct finite_min_helper<long int> {
static constexpr
long int value = LONG_MIN; };
51 template <>
struct finite_min_helper<unsigned long int> {
static constexpr
unsigned long int value = 0; };
52 template <>
struct finite_min_helper<long long int> {
static constexpr
long long int value = LLONG_MIN; };
53 template <>
struct finite_min_helper<unsigned long long int> {
static constexpr
unsigned long long int value = 0; };
54 template <>
struct finite_min_helper<float> {
static constexpr
float value = -FLT_MAX; };
55 template <>
struct finite_min_helper<double> {
static constexpr
double value = -DBL_MAX; };
56 template <>
struct finite_min_helper<long double> {
static constexpr
long double value = -LDBL_MAX; };
57 template <
class>
struct finite_max_helper {};
58 template <>
struct finite_max_helper<bool> {
static constexpr
bool value =
true; };
59 template <>
struct finite_max_helper<char> {
static constexpr
char value = CHAR_MAX; };
60 template <>
struct finite_max_helper<signed char> {
static constexpr
signed char value = SCHAR_MAX; };
61 template <>
struct finite_max_helper<unsigned char> {
static constexpr
unsigned char value = UCHAR_MAX; };
62 template <>
struct finite_max_helper<short> {
static constexpr
short value = SHRT_MAX; };
63 template <>
struct finite_max_helper<unsigned short> {
static constexpr
unsigned short value = USHRT_MAX; };
64 template <>
struct finite_max_helper<int> {
static constexpr
int value = INT_MAX; };
65 template <>
struct finite_max_helper<unsigned int> {
static constexpr
unsigned int value = UINT_MAX; };
66 template <>
struct finite_max_helper<long int> {
static constexpr
long int value = LONG_MAX; };
67 template <>
struct finite_max_helper<unsigned long int> {
static constexpr
unsigned long int value = ULONG_MAX; };
68 template <>
struct finite_max_helper<long long int> {
static constexpr
long long int value = LLONG_MAX; };
69 template <>
struct finite_max_helper<unsigned long long int> {
static constexpr
unsigned long long int value = ULLONG_MAX; };
70 template <>
struct finite_max_helper<float> {
static constexpr
float value = FLT_MAX; };
71 template <>
struct finite_max_helper<double> {
static constexpr
double value = DBL_MAX; };
72 template <>
struct finite_max_helper<long double> {
static constexpr
long double value = LDBL_MAX; };
73 template <
class>
struct epsilon_helper {};
74 template <>
struct epsilon_helper<float> {
static constexpr
float value = FLT_EPSILON; };
75 template <>
struct epsilon_helper<double> {
static constexpr
double value = DBL_EPSILON; };
76 template <>
struct epsilon_helper<long double> {
77 static constexpr
long double value = LDBL_EPSILON;
79 template <
class>
struct round_error_helper {};
80 template <>
struct round_error_helper<float> {
static constexpr
float value = 0.5F; };
81 template <>
struct round_error_helper<double> {
static constexpr
double value = 0.5; };
82 template <>
struct round_error_helper<long double> {
static constexpr
long double value = 0.5L; };
83 template <
class>
struct norm_min_helper {};
84 template <>
struct norm_min_helper<float> {
static constexpr
float value = FLT_MIN; };
85 template <>
struct norm_min_helper<double> {
static constexpr
double value = DBL_MIN; };
86 template <>
struct norm_min_helper<long double> {
static constexpr
long double value = LDBL_MIN; };
87 template <
class>
struct denorm_min_helper {};
90 #if defined (FLT_TRUE_MIN) || defined(_MSC_VER)
91 template <>
struct denorm_min_helper<float> {
static constexpr
float value = FLT_TRUE_MIN; };
92 template <>
struct denorm_min_helper<double> {
static constexpr
double value = DBL_TRUE_MIN; };
93 template <>
struct denorm_min_helper<long double> {
static constexpr
long double value = LDBL_TRUE_MIN; };
95 template <>
struct denorm_min_helper<float> {
static constexpr
float value = __FLT_DENORM_MIN__; };
96 template <>
struct denorm_min_helper<double> {
static constexpr
double value = __DBL_DENORM_MIN__; };
97 template <>
struct denorm_min_helper<long double> {
static constexpr
long double value = __LDBL_DENORM_MIN__; };
99 template <
class>
struct quiet_NaN_helper {};
100 template <>
struct quiet_NaN_helper<float> {
static constexpr
float value = __builtin_nanf(
""); };
101 template <>
struct quiet_NaN_helper<double> {
static constexpr
double value = __builtin_nan(
""); };
102 #if defined(_MSC_VER)
103 template <>
struct quiet_NaN_helper<long double> {
static constexpr
long double value = __builtin_nan(
""); };
105 template <>
struct quiet_NaN_helper<long double> {
static constexpr
long double value = __builtin_nanl(
""); };
107 template <
class>
struct signaling_NaN_helper {};
108 template <>
struct signaling_NaN_helper<float> {
static constexpr
float value = __builtin_nansf(
""); };
109 template <>
struct signaling_NaN_helper<double> {
static constexpr
double value = __builtin_nans(
""); };
110 #if defined(_MSC_VER)
111 template <>
struct signaling_NaN_helper<long double> {
static constexpr
long double value = __builtin_nans(
""); };
113 template <>
struct signaling_NaN_helper<long double> {
static constexpr
long double value = __builtin_nansl(
""); };
115 template <
class>
struct digits_helper {};
116 template <>
struct digits_helper<bool> {
static constexpr
int value = 1; };
117 template <>
struct digits_helper<char> {
static constexpr
int value = CHAR_BIT - std::is_signed<char>::value; };
118 template <>
struct digits_helper<signed char> {
static constexpr
int value = CHAR_BIT - 1; };
119 template <>
struct digits_helper<unsigned char> {
static constexpr
int value = CHAR_BIT; };
120 template <>
struct digits_helper<short> {
static constexpr
int value = CHAR_BIT*
sizeof(short)-1; };
121 template <>
struct digits_helper<unsigned short> {
static constexpr
int value = CHAR_BIT*
sizeof(short); };
122 template <>
struct digits_helper<int> {
static constexpr
int value = CHAR_BIT*
sizeof(int)-1; };
123 template <>
struct digits_helper<unsigned int> {
static constexpr
int value = CHAR_BIT*
sizeof(int); };
124 template <>
struct digits_helper<long int> {
static constexpr
int value = CHAR_BIT*
sizeof(
long int)-1; };
125 template <>
struct digits_helper<unsigned long int> {
static constexpr
int value = CHAR_BIT*
sizeof(
long int); };
126 template <>
struct digits_helper<long long int> {
static constexpr
int value = CHAR_BIT*
sizeof(
long long int)-1; };
127 template <>
struct digits_helper<unsigned long long int> {
static constexpr
int value = CHAR_BIT*
sizeof(
long long int); };
128 template <>
struct digits_helper<float> {
static constexpr
int value = FLT_MANT_DIG; };
129 template <>
struct digits_helper<double> {
static constexpr
int value = DBL_MANT_DIG; };
130 template <>
struct digits_helper<long double> {
static constexpr
int value = LDBL_MANT_DIG; };
131 template <
class>
struct digits10_helper {};
132 template <>
struct digits10_helper<bool> {
static constexpr
int value = 0; };
136 #define DIGITS10_HELPER_INTEGRAL(TYPE) \
137 template <> struct digits10_helper<TYPE> { static constexpr int value = digits_helper<TYPE>::value * 643L / 2136; };
138 DIGITS10_HELPER_INTEGRAL(
char)
139 DIGITS10_HELPER_INTEGRAL(
signed char)
140 DIGITS10_HELPER_INTEGRAL(
unsigned char)
141 DIGITS10_HELPER_INTEGRAL(
short)
142 DIGITS10_HELPER_INTEGRAL(
unsigned short)
143 DIGITS10_HELPER_INTEGRAL(
int)
144 DIGITS10_HELPER_INTEGRAL(
unsigned int)
145 DIGITS10_HELPER_INTEGRAL(
long int)
146 DIGITS10_HELPER_INTEGRAL(
unsigned long int)
147 DIGITS10_HELPER_INTEGRAL(
long long int)
148 DIGITS10_HELPER_INTEGRAL(
unsigned long long int)
149 #undef DIGITS10_HELPER_INTEGRAL
150 template <>
struct digits10_helper<float> {
static constexpr
int value = FLT_DIG; };
151 template <>
struct digits10_helper<double> {
static constexpr
int value = DBL_DIG; };
152 template <>
struct digits10_helper<long double> {
static constexpr
int value = LDBL_DIG; };
153 template <
class>
struct max_digits10_helper {};
155 #define MAX_DIGITS10_HELPER(TYPE) \
156 template <> struct max_digits10_helper<TYPE> { static constexpr int value = (digits_helper<TYPE>::value * 643L + 2135) / 2136 + 1; };
157 #ifdef FLT_DECIMAL_DIG
158 template <>
struct max_digits10_helper<float> {
static constexpr
int value = FLT_DECIMAL_DIG; };
160 MAX_DIGITS10_HELPER(
float)
162 #ifdef DBL_DECIMAL_DIG
163 template <>
struct max_digits10_helper<double> {
static constexpr
int value = DBL_DECIMAL_DIG; };
165 MAX_DIGITS10_HELPER(
double)
168 template <>
struct max_digits10_helper<long double> {
static constexpr
int value = DECIMAL_DIG; };
169 #elif LDBL_DECIMAL_DIG
170 template <>
struct max_digits10_helper<long double> {
static constexpr
int value = LDBL_DECIMAL_DIG; };
172 MAX_DIGITS10_HELPER(
long double)
174 #undef MAX_DIGITS10_HELPER
175 template <
class>
struct radix_helper {};
176 template <>
struct radix_helper<bool> {
static constexpr
int value = 2; };
177 template <>
struct radix_helper<char> {
static constexpr
int value = 2; };
178 template <>
struct radix_helper<signed char> {
static constexpr
int value = 2; };
179 template <>
struct radix_helper<unsigned char> {
static constexpr
int value = 2; };
180 template <>
struct radix_helper<short> {
static constexpr
int value = 2; };
181 template <>
struct radix_helper<unsigned short> {
static constexpr
int value = 2; };
182 template <>
struct radix_helper<int> {
static constexpr
int value = 2; };
183 template <>
struct radix_helper<unsigned int> {
static constexpr
int value = 2; };
184 template <>
struct radix_helper<long int> {
static constexpr
int value = 2; };
185 template <>
struct radix_helper<unsigned long int> {
static constexpr
int value = 2; };
186 template <>
struct radix_helper<long long int> {
static constexpr
int value = 2; };
187 template <>
struct radix_helper<unsigned long long int> {
static constexpr
int value = 2; };
188 template <>
struct radix_helper<float> {
static constexpr
int value = FLT_RADIX; };
189 template <>
struct radix_helper<double> {
static constexpr
int value = FLT_RADIX; };
190 template <>
struct radix_helper<long double> {
static constexpr
int value = FLT_RADIX; };
191 template <
class>
struct min_exponent_helper {};
192 template <>
struct min_exponent_helper<float> {
static constexpr
int value = FLT_MIN_EXP; };
193 template <>
struct min_exponent_helper<double> {
static constexpr
int value = DBL_MIN_EXP; };
194 template <>
struct min_exponent_helper<long double> {
static constexpr
int value = LDBL_MIN_EXP; };
195 template <
class>
struct min_exponent10_helper {};
196 template <>
struct min_exponent10_helper<float> {
static constexpr
int value = FLT_MIN_10_EXP; };
197 template <>
struct min_exponent10_helper<double> {
static constexpr
int value = DBL_MIN_10_EXP; };
198 template <>
struct min_exponent10_helper<long double> {
static constexpr
int value = LDBL_MIN_10_EXP; };
199 template <
class>
struct max_exponent_helper {};
200 template <>
struct max_exponent_helper<float> {
static constexpr
int value = FLT_MAX_EXP; };
201 template <>
struct max_exponent_helper<double> {
static constexpr
int value = DBL_MAX_EXP; };
202 template <>
struct max_exponent_helper<long double> {
static constexpr
int value = LDBL_MAX_EXP; };
203 template <
class>
struct max_exponent10_helper{};
204 template <>
struct max_exponent10_helper<float> {
static constexpr
int value = FLT_MAX_10_EXP; };
205 template <>
struct max_exponent10_helper<double> {
static constexpr
int value = DBL_MAX_10_EXP; };
206 template <>
struct max_exponent10_helper<long double> {
static constexpr
int value = LDBL_MAX_10_EXP; };
210 #define KOKKOS_IMPL_DEFINE_TRAIT(TRAIT) \
212 struct TRAIT : Impl::TRAIT##_helper<std::remove_cv_t<T>> {}; \
214 inline constexpr auto TRAIT##_v = TRAIT<T>::value;
217 KOKKOS_IMPL_DEFINE_TRAIT(infinity)
218 KOKKOS_IMPL_DEFINE_TRAIT(finite_min)
219 KOKKOS_IMPL_DEFINE_TRAIT(finite_max)
220 KOKKOS_IMPL_DEFINE_TRAIT(epsilon)
221 KOKKOS_IMPL_DEFINE_TRAIT(round_error)
222 KOKKOS_IMPL_DEFINE_TRAIT(norm_min)
223 KOKKOS_IMPL_DEFINE_TRAIT(denorm_min)
224 KOKKOS_IMPL_DEFINE_TRAIT(quiet_NaN)
225 KOKKOS_IMPL_DEFINE_TRAIT(signaling_NaN)
228 KOKKOS_IMPL_DEFINE_TRAIT(digits)
229 KOKKOS_IMPL_DEFINE_TRAIT(digits10)
230 KOKKOS_IMPL_DEFINE_TRAIT(max_digits10)
231 KOKKOS_IMPL_DEFINE_TRAIT(radix)
232 KOKKOS_IMPL_DEFINE_TRAIT(min_exponent)
233 KOKKOS_IMPL_DEFINE_TRAIT(min_exponent10)
234 KOKKOS_IMPL_DEFINE_TRAIT(max_exponent)
235 KOKKOS_IMPL_DEFINE_TRAIT(max_exponent10)
237 #undef KOKKOS_IMPL_DEFINE_TRAIT
241 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_NUMERIC_TRAITS
242 #undef KOKKOS_IMPL_PUBLIC_INCLUDE
243 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_NUMERIC_TRAITS