8#pragma qt_class(QtNumeric)
11#include <QtCore/qtconfigmacros.h>
12#include <QtCore/qtcoreexports.h>
13#include <QtCore/qtypes.h>
29# if defined(Q_PROCESSOR_X86_64) || defined(Q_PROCESSOR_ARM_64)
30# define Q_INTRINSIC_MUL_OVERFLOW64
31# define Q_UMULH(v1, v2) __umulh(v1, v2);
32# define Q_SMULH(v1, v2) __mulh(v1, v2);
33# pragma intrinsic(__umulh)
34# pragma intrinsic(__mulh)
38# if defined(Q_OS_INTEGRITY) && defined(Q_PROCESSOR_ARM_64)
39# include <arm64_ghs.h>
40# define Q_INTRINSIC_MUL_OVERFLOW64
41# define Q_UMULH(v1, v2) __MULUH64(v1, v2);
42# define Q_SMULH(v1, v2) __MULSH64(v1, v2);
49constexpr typename std::enable_if<std::is_integral<T>::value,
bool>
::type
52constexpr typename std::enable_if<std::is_integral<T>::value,
bool>
::type
55constexpr typename std::enable_if<std::is_integral<T>::value,
bool>
::type
68#if QT_CONFIG(signaling_nan)
77#define Q_INFINITY (QT_PREPEND_NAMESPACE(qInf)())
78#if QT_CONFIG(signaling_nan)
79# define Q_SNAN (QT_PREPEND_NAMESPACE(qSNaN)())
81#define Q_QNAN (QT_PREPEND_NAMESPACE(qQNaN)())
88#if (Q_CC_GNU >= 500 || __has_builtin(__builtin_add_overflow)) \
89 && !(QT_POINTER_SIZE == 4 && defined(Q_CC_CLANG))
92#define Q_INTRINSIC_MUL_OVERFLOW64
94template <
typename T>
inline
95typename std::enable_if_t<std::is_unsigned_v<T> || std::is_signed_v<T>,
bool>
97{
return __builtin_add_overflow(
v1,
v2,
r); }
99template <
typename T>
inline
100typename std::enable_if_t<std::is_unsigned_v<T> || std::is_signed_v<T>,
bool>
102{
return __builtin_sub_overflow(
v1,
v2,
r); }
104template <
typename T>
inline
105typename std::enable_if_t<std::is_unsigned_v<T> || std::is_signed_v<T>,
bool>
107{
return __builtin_mul_overflow(
v1,
v2,
r); }
112template <
typename T>
inline typename std::enable_if_t<std::is_unsigned_v<T>,
bool>
120template <
typename T>
inline typename std::enable_if_t<std::is_signed_v<T>,
bool>
132 using U =
typename std::make_unsigned_t<T>;
133 *
r = T(U(
v1) + U(
v2));
136 if (std::is_same_v<int32_t, int>) {
142 return ((
v1 ^ *
r) & (
v2 ^ *
r)) < 0;
148 return s1 != sr &&
s2 != sr;
152template <
typename T>
inline typename std::enable_if_t<std::is_unsigned_v<T>,
bool>
160template <
typename T>
inline typename std::enable_if_t<std::is_signed_v<T>,
bool>
167 using U =
typename std::make_unsigned_t<T>;
168 *
r = T(U(
v1) - U(
v2));
170 if (std::is_same_v<int32_t, int>)
171 return ((
v1 ^ *
r) & (~
v2 ^ *
r)) < 0;
176 return s1 != sr &&
s2 != sr;
180template <
typename T>
inline
181typename std::enable_if_t<std::is_unsigned_v<T> || std::is_signed_v<T>,
bool>
186 using LargerInt = QIntegerForSize<
sizeof(T) * 2>;
187 using Larger =
typename std::conditional_t<std::is_signed_v<T>,
188 typename LargerInt::Signed,
typename LargerInt::Unsigned>;
189 Larger lr = Larger(
v1) * Larger(
v2);
191 return lr > (std::numeric_limits<T>::max)() || lr < (std::numeric_limits<T>::min)();
194# if defined(Q_INTRINSIC_MUL_OVERFLOW64)
198 return Q_UMULH(
v1,
v2);
210 return (*
r >> 63) != high;
213# if defined(Q_OS_INTEGRITY) && defined(Q_PROCESSOR_ARM_64)
216 return qMulOverflow<quint64>(
v1,
v2,
reinterpret_cast<quint64*
>(
r));
221 return qMulOverflow<qint64>(
v1,
v2,
reinterpret_cast<qint64*
>(
r));
226# if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86)
229{
return _addcarry_u32(0,
v1,
v2,
r); }
235# if defined(Q_PROCESSOR_X86_64)
236 return _addcarry_u64(0,
v1,
v2,
reinterpret_cast<unsigned __int64 *
>(
r));
239 uchar carry = _addcarry_u32(0,
unsigned(
v1),
unsigned(
v2), &low);
240 carry = _addcarry_u32(carry,
v1 >> 32,
v2 >> 32, &high);
253template <
typename T, T V2>
bool qAddOverflow(T
v1, std::integral_constant<T, V2>, T *
r)
263template <
typename T, T V2>
bool qSubOverflow(T
v1, std::integral_constant<T, V2>, T *
r)
273template <
typename T, T V2>
bool qMulOverflow(T
v1, std::integral_constant<T, V2>, T *
r)
279 if constexpr (
sizeof(T) <=
sizeof(qregisteruint)) {
282#ifdef Q_INTRINSIC_MUL_OVERFLOW64
283 }
else if constexpr (
sizeof(T) <=
sizeof(
quint64)) {
289 }
else if constexpr (V2 == 0 || V2 == 1) {
293 }
else if constexpr (V2 == -1) {
296 if (
v1 < 0 &&
v1 == (std::numeric_limits<T>::min)())
303 constexpr T Highest = (std::numeric_limits<T>::max)() / V2;
304 constexpr T Lowest = (std::numeric_limits<T>::min)() / V2;
305 if constexpr (Highest > Lowest) {
306 if (
v1 > Highest ||
v1 < Lowest)
310 static_assert(V2 < 0);
311 if (
v1 > Lowest ||
v1 < Highest)
322 if constexpr (V2 == 2)
328constexpr inline T
qAbs(
const T &
t) {
return t >= 0 ?
t : -
t; }
331#if defined(Q_PROCESSOR_ARM_64) && (__has_builtin(__builtin_round) || defined(Q_CC_GNU)) && !defined(Q_CC_CLANG)
334constexpr inline int qRound(
double d)
335{
return int(__builtin_round(
d)); }
336constexpr inline int qRound(
float f)
337{
return int(__builtin_roundf(
f)); }
339{
return qint64(__builtin_round(
d)); }
341{
return qint64(__builtin_roundf(
f)); }
342#elif defined(__SSE2__) && (__has_builtin(__builtin_copysign) || defined(Q_CC_GNU))
344constexpr inline int qRound(
double d)
345{
return int(
d + __builtin_copysign(0.5,
d)); }
346constexpr inline int qRound(
float f)
347{
return int(
f + __builtin_copysignf(0.5f,
f)); }
349{
return qint64(
d + __builtin_copysign(0.5,
d)); }
351{
return qint64(
f + __builtin_copysignf(0.5f,
f)); }
354{
return d >= 0.0 ? int(
d + 0.5) : int(
d - 0.5); }
356{
return d >= 0.0f ? int(
d + 0.5f) : int(
d - 0.5f); }
366constexpr inline const T &
min(
const T &
a,
const T &
b) {
return (
a <
b) ?
a :
b; }
381 return qAbs(
d) <= 0.000000000001;
386 return qAbs(
f) <= 0.00001f;
392[[nodiscard]]
constexpr bool qIsNull(
double d)
noexcept
397[[nodiscard]]
constexpr bool qIsNull(
float f)
noexcept
Combined button and popup list for selecting options.
constexpr const T & min(const T &a, const T &b)
#define Q_DECL_CONST_FUNCTION
#define QT_WARNING_DISABLE_FLOAT_COMPARE
Q_CORE_EXPORT quint32 qFloatDistance(float a, float b)
constexpr T qAbs(const T &t)
constexpr std::enable_if< std::is_integral< T >::value, bool >::type qIsFinite(T)
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qInf()
constexpr bool qFuzzyIsNull(double d)
constexpr bool qFuzzyCompare(double p1, double p2)
std::enable_if_t< std::is_unsigned_v< T >, bool > qAddOverflow(T v1, T v2, T *r)
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION int qFpClassify(double val)
std::enable_if_t< std::is_unsigned_v< T >, bool > qSubOverflow(T v1, T v2, T *r)
constexpr std::enable_if< std::is_integral< T >::value, bool >::type qIsNaN(T)
constexpr qint64 qRound64(double d)
constexpr int qRound(double d)
QT_BEGIN_NAMESPACE constexpr std::enable_if< std::is_integral< T >::value, bool >::type qIsInf(T)
QT_WARNING_POP int qIntCast(double f)
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qQNaN()
std::enable_if_t< std::is_unsigned_v< T >||std::is_signed_v< T >, bool > qMulOverflow(T v1, T v2, T *r)
QT_WARNING_PUSH QT_WARNING_DISABLE_FLOAT_COMPARE constexpr bool qIsNull(double d) noexcept
GLint GLfloat GLfloat GLfloat v2
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
unsigned long long quint64