19#include "QtCore/private/qglobal_p.h"
20#include "QtCore/qnumeric.h"
21#include "QtCore/qsimd.h"
26#if !defined(Q_CC_MSVC) && defined(Q_OS_QNX)
29# define QT_MATH_H_DEFINES_MACROS
55#if defined(QT_MATH_H_DEFINES_MACROS)
56# undef QT_MATH_H_DEFINES_MACROS
79 static_assert(std::numeric_limits<double>::has_infinity,
80 "platform has no definition for infinity for type double");
81 return std::numeric_limits<double>::infinity();
84#if QT_CONFIG(signaling_nan)
87 static_assert(std::numeric_limits<double>::has_signaling_NaN,
88 "platform has no definition for signaling NaN for type double");
89 return std::numeric_limits<double>::signaling_NaN();
96 static_assert(std::numeric_limits<double>::has_quiet_NaN,
97 "platform has no definition for quiet NaN for type double");
98 return std::numeric_limits<double>::quiet_NaN();
154static inline bool convertDoubleTo(
double v, T *
value,
bool allow_precision_upgrade =
true)
156 static_assert(std::numeric_limits<T>::is_integer);
157 static_assert(std::is_integral_v<T>);
158 constexpr bool TypeIsLarger = std::numeric_limits<T>::digits > std::numeric_limits<double>::digits;
160 if constexpr (TypeIsLarger) {
161 using S = std::make_signed_t<T>;
162 constexpr S max_mantissa =
S(1) << std::numeric_limits<double>::digits;
166 if (!allow_precision_upgrade && !(
v <=
double(max_mantissa) &&
v >=
double(-max_mantissa - 1)))
170 constexpr T Tmin = (std::numeric_limits<T>::min)();
171 constexpr T Tmax = (std::numeric_limits<T>::max)();
183#if defined(Q_PROCESSOR_X86_64) && defined(__SSE2__)
192 if (std::numeric_limits<T>::is_signed) {
193 __m128d mv = _mm_set_sd(
v);
197 *
value = T(_mm_cvtt_roundsd_i64(mv, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
199 *
value = _mm_cvtt_roundsd_i32(mv, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
201 *
value =
sizeof(T) > 4 ? T(_mm_cvttsd_si64(mv)) : _mm_cvttsd_si32(mv);
206 if (*
value == Tmin && !_mm_ucomieq_sd(mv, _mm_set_sd(Tmin))) {
215 __m128d mi = _mm_setzero_pd();
216 mi =
sizeof(T) > 4 ? _mm_cvtsi64_sd(mv, *
value) : _mm_cvtsi32_sd(mv, *
value);
217 return _mm_ucomieq_sd(mv, mi);
221 if (!std::numeric_limits<T>::is_signed) {
231 __m128d mv = _mm_set_sd(
v);
235 *
value = T(_mm_cvtt_roundsd_u64(mv, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
237 *
value = _mm_cvtt_roundsd_u32(mv, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
239 if (*
value == Tmax) {
242 if (TypeIsLarger || _mm_ucomieq_sd(mv, _mm_set_sd(Tmax)))
247 __m128d mi = _mm_setzero_pd();
248 mi =
sizeof(T) > 4 ? _mm_cvtu64_sd(mv, *
value) : _mm_cvtu32_sd(mv, *
value);
249 return _mm_ucomieq_sd(mv, mi);
255 if (std::numeric_limits<T>::is_signed) {
256 supremum = -1.0 * Tmin;
261 using ST =
typename std::make_signed<T>::type;
262 supremum = -2.0 * (std::numeric_limits<ST>::min)();
285template <
typename T, T V2>
bool add_overflow(T
v1, std::integral_constant<T, V2>, T *
r)
287 return qAddOverflow<T, V2>(
v1, std::integral_constant<T, V2>{},
r);
290template <auto V2,
typename T>
bool add_overflow(T
v1, T *
r)
292 return qAddOverflow<V2, T>(
v1,
r);
295template <
typename T, T V2>
bool sub_overflow(T
v1, std::integral_constant<T, V2>, T *
r)
297 return qSubOverflow<T, V2>(
v1, std::integral_constant<T, V2>{},
r);
300template <auto V2,
typename T>
bool sub_overflow(T
v1, T *
r)
302 return qSubOverflow<V2, T>(
v1,
r);
305template <
typename T, T V2>
bool mul_overflow(T
v1, std::integral_constant<T, V2>, T *
r)
307 return qMulOverflow<T, V2>(
v1, std::integral_constant<T, V2>{},
r);
310template <auto V2,
typename T>
bool mul_overflow(T
v1, T *
r)
312 return qMulOverflow<V2, T>(
v1,
r);
324template <
typename To,
typename From>
327 static_assert(std::is_integral_v<To>);
328 static_assert(std::is_integral_v<From>);
331 constexpr auto Lo = (std::numeric_limits<To>::min)();
332 constexpr auto Hi = (std::numeric_limits<To>::max)();
334 if constexpr (std::is_signed_v<From> == std::is_signed_v<To>) {
340 if constexpr (std::is_signed_v<From>) {
346 using FromU = std::make_unsigned_t<From>;
347 using ToU = std::make_unsigned_t<To>;
348 return FromU(
x) > ToU(Hi) ? Hi : To(
x);
Combined button and popup list for selecting options.
static Q_DECL_CONST_FUNCTION bool isinf(double d)
static Q_DECL_CONST_FUNCTION int fpclassify(double d)
static Q_DECL_CONST_FUNCTION bool isfinite(double d)
static Q_DECL_CONST_FUNCTION bool isnan(double d)
#define Q_DECL_CONST_FUNCTION
#define QT_WARNING_DISABLE_FLOAT_COMPARE
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
std::enable_if_t< std::is_unsigned_v< T >, bool > qAddOverflow(T v1, T v2, T *r)
std::enable_if_t< std::is_unsigned_v< T >, bool > qSubOverflow(T v1, T v2, T *r)
std::enable_if_t< std::is_unsigned_v< T >||std::is_signed_v< T >, bool > qMulOverflow(T v1, T v2, T *r)
static constexpr auto qt_saturate(From x)
static Q_DECL_CONST_FUNCTION bool qt_is_nan(double d)
constexpr static Q_DECL_CONST_FUNCTION double qt_qnan() noexcept
constexpr static Q_DECL_CONST_FUNCTION double qt_inf() noexcept
static Q_DECL_CONST_FUNCTION int qt_fpclassify(double d)
static Q_DECL_CONST_FUNCTION bool qt_is_inf(double d)
static Q_DECL_CONST_FUNCTION bool qt_is_finite(double d)
GLint GLfloat GLfloat GLfloat v2
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]