21#if defined(__clang__) || defined(__GNUC__)
22 #define NEM_TRAP() __builtin_trap()
24 #define NEM_UNREACHABLE() NEM_TRAP()
26 #define NEM_UNREACHABLE() __builtin_unreachable()
29#elif defined(_MSC_VER)
30 #define NEM_TRAP() __debugbreak()
31 #define NEM_UNREACHABLE() __assume(0)
34 #error "Unsupported compiler"
37#if defined(__clang__) || defined(__GNUC__)
38 template <std::
floating_po
int T>
39 T _nem_sqrt(T x)
noexcept
41 if constexpr (std::is_same_v<T, float>)
43 return __builtin_sqrtf(x);
45 else if constexpr (std::is_same_v<T, double>)
47 return __builtin_sqrt(x);
51 return __builtin_sqrtl(x);
55#elif defined(_MSC_VER)
56 template <std::
floating_po
int T>
57 T _nem_sqrt(T x)
noexcept
59 if constexpr (std::is_same_v<T, float>)
61 return _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(x)));
63 else if constexpr (std::is_same_v<T, double>)
74#if defined(__clang__) || defined(__GNUC__)
75 template <std::
floating_po
int T>
76 constexpr T _nem_fabs(T x)
noexcept
78 if constexpr (std::is_same_v<T, float>)
80 return __builtin_fabsf(x);
82 else if constexpr (std::is_same_v<T, double>)
84 return __builtin_fabs(x);
88 return __builtin_fabsl(x);
92#elif defined(_MSC_VER)
93 template <std::
floating_po
int T>
94 T _nem_fabs(T x)
noexcept
96 if constexpr (std::is_same_v<T, float>)
100 else if constexpr (std::is_same_v<T, double>)
111 template <std::
floating_po
int T>
bool _nem_isnan(T x)
noexcept {
return x != x; }
112 template <std::
integral T>
bool _nem_isnan(T)
noexcept {
return false; }
114 template <std::
floating_po
int T>
117 return (x == x) && (x - x == T{0});
119 template <std::
integral T>
bool _nem_isfinite(T)
noexcept {
return true; }
121#if defined(__clang__) || defined(__GNUC__)
122 template <
typename T>
123 constexpr T _nem_copysign(T to, T from)
noexcept
125 if constexpr (std::is_same_v<T, float>)
127 return __builtin_copysignf(to, from);
129 else if constexpr (std::is_same_v<T, double>)
131 return __builtin_copysign(to, from);
133 else if constexpr (std::is_same_v<T, long double>)
135 return __builtin_copysignl(to, from);
137 else if constexpr (std::is_integral_v<T>)
139 const bool flip = (to < T{0}) ^ (from < T{0});
140 return flip ? -to : to;
148#elif defined(_MSC_VER)
149 template <
typename T>
150 T _nem_copysign(T to, T from)
noexcept
152 if constexpr (std::is_same_v<T, float>)
154 return ::copysignf(to, from);
156 else if constexpr (std::is_same_v<T, double>)
158 return ::copysign(to, from);
160 else if constexpr (std::is_same_v<T, long double>)
162 return ::copysignl(to, from);
164 else if constexpr (std::is_integral_v<T>)
166 const bool flip = (to < T{0}) ^ (from < T{0});
167 return flip ? -to : to;
169 else { NEM_UNREACHABLE(); }