9#include <QtCore/q20type_traits.h>
11#if defined(__cpp_lib_bitops) || defined(__cpp_lib_int_pow2)
14# include <QtCore/qtypes.h>
20# include <QtCore/qsimd.h>
44#if defined(__cpp_lib_bitops)
54#if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_ARM_64)
55 if constexpr (
sizeof(T) ==
sizeof(quint64))
56 return int(_CountOneBits64(v));
57 return int(_CountOneBits(v));
59#if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86) && defined(__POPCNT__)
61# ifdef Q_PROCESSOR_X86_64
62 if constexpr (
sizeof(T) ==
sizeof(quint64))
63 return int(__popcnt64(v));
65 if constexpr (
sizeof(T) ==
sizeof(quint64))
66 return int(__popcnt(quint32(v)) + __popcnt(quint32(v >> 32)));
67 if constexpr (
sizeof(T) ==
sizeof(quint32))
68 return int(__popcnt(v));
69 return int(__popcnt16(v));
77#if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_ARM_64)
78 if constexpr (
sizeof(T) ==
sizeof(quint64))
79 return int(_CountLeadingZeros64(v));
80 return int(_CountLeadingZeros(v)) - (32 - std::numeric_limits<T>::digits);
82#if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86) && defined(__LZCNT__)
84# if defined(Q_PROCESSOR_X86_64)
85 if constexpr (
sizeof(T) ==
sizeof(quint64))
86 return int(__lzcnt64(v));
88 if constexpr (
sizeof(T) ==
sizeof(quint32))
89 return int(__lzcnt(v));
90 if constexpr (
sizeof(T) ==
sizeof(quint16))
91 return int(__lzcnt16(v));
92 if constexpr (
sizeof(T) ==
sizeof(quint8))
93 return int(__lzcnt(v)) - 24;
95#if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86)
96 constexpr int Digits = std::numeric_limits<T>::digits;
99 if constexpr (
sizeof(T) ==
sizeof(quint64)) {
100# ifdef Q_PROCESSOR_X86_64
101 if (_BitScanReverse64(&result, v) == 0)
104 if (quint32 h = quint32(v >> 32))
105 return hw_countl_zero(h);
106 return hw_countl_zero(quint32(v)) + 32;
109 if (_BitScanReverse(&result, v) == 0)
116 result ^=
sizeof(T) * 8 - 1;
125#if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_ARM_64)
126 if constexpr (
sizeof(T) ==
sizeof(quint64))
127 return int(_CountTrailingZeros64(v));
128 constexpr int Digits = std::numeric_limits<T>::digits;
129 const int result =
int(_CountTrailingZeros(v));
130 return result > Digits ? Digits : result;
132#if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86) && defined(__BMI__)
134# if defined(Q_PROCESSOR_X86_64)
135 if constexpr (
sizeof(T) ==
sizeof(quint64))
136 return int(_tzcnt_u64(v));
138 if constexpr (
sizeof(T) ==
sizeof(quint32))
139 return int(_tzcnt_u32(v));
142#if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86)
143 constexpr int Digits = std::numeric_limits<T>::digits;
144 unsigned long result;
145 if constexpr (
sizeof(T) <=
sizeof(quint32))
146 return _BitScanForward(&result, v) ?
int(result) : Digits;
147# ifdef Q_PROCESSOR_X86_64
148 return _BitScanForward64(&result, v) ?
int(result) : Digits;
160 return __builtin_popcountg(v);
163 if constexpr (
sizeof(T) >
sizeof(quint64)) {
164 static_assert(
sizeof(T) == 16,
"Unsupported integer size");
165 return popcount(quint64(v)) + popcount(quint64(v >> 64));
171 if constexpr (
sizeof(T) >
sizeof(quint32))
172 return __builtin_popcountll(v);
173 return __builtin_popcount(v);
176# ifdef QT_SUPPORTS_IS_CONSTANT_EVALUATED
178 if (!is_constant_evaluated()) {
179 if constexpr (std::is_integral_v<
decltype(detail::hw_popcount(v))>)
180 return detail::hw_popcount(v);
184 constexpr int Digits =
std::numeric_limits<T>::digits;
185 int r = (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
186 if constexpr (Digits > 12)
187 r += (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
188 if constexpr (Digits > 24)
189 r += (((v >> 24) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
190 if constexpr (Digits > 36) {
191 r += (((v >> 36) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
192 (((v >> 48) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
193 (((v >> 60) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
204 return __builtin_clzg(v,
std::numeric_limits<T>::digits);
207 if constexpr (
sizeof(T) >
sizeof(quint64)) {
208 static_assert(
sizeof(T) == 16,
"Unsupported integer size");
209 if (quint64 h = quint64(v >> 64))
210 return countl_zero(h);
211 return countl_zero(quint64(v)) + 64;
218 return std::numeric_limits<T>::digits;
219 if constexpr (
sizeof(T) ==
sizeof(quint64))
220 return __builtin_clzll(v);
222 if constexpr (
sizeof(T) ==
sizeof(quint16))
223 return __builtin_clzs(v);
225 return __builtin_clz(v) - (32 -
std::numeric_limits<T>::digits);
228#ifdef QT_SUPPORTS_IS_CONSTANT_EVALUATED
230 if (!is_constant_evaluated()) {
231 if constexpr (std::is_integral_v<
decltype(detail::hw_countl_zero(v))>)
232 return detail::hw_countl_zero(v);
240 if constexpr (
sizeof(T) >
sizeof(quint8))
242 if constexpr (
sizeof(T) >
sizeof(quint16))
244 if constexpr (
sizeof(T) >
sizeof(quint32))
246 return popcount(T(~v));
255 return __builtin_ctzg(v,
std::numeric_limits<T>::digits);
258 if constexpr (
sizeof(T) >
sizeof(quint64)) {
259 static_assert(
sizeof(T) == 16,
"Unsupported integer size");
260 quint64 l = quint64(v);
261 return l ? countr_zero(l) : 64 + countr_zero(quint64(v >> 64));
268 return std::numeric_limits<T>::digits;
269 if constexpr (
sizeof(T) ==
sizeof(quint64))
270 return __builtin_ctzll(v);
272 if constexpr (
sizeof(T) ==
sizeof(quint16))
273 return __builtin_ctzs(v);
275 return __builtin_ctz(v);
278#ifdef QT_SUPPORTS_IS_CONSTANT_EVALUATED
280 if (!is_constant_evaluated()) {
281 if constexpr (std::is_integral_v<
decltype(detail::hw_countr_zero(v))>)
282 return detail::hw_countr_zero(v);
286 if constexpr (
sizeof(T) >
sizeof(quint32)) {
287 quint32 l = quint32(v);
288 return l ? countr_zero(l) : 32 + countr_zero(quint32(v >> 32));
292 int c =
std::numeric_limits<T>::digits;
294QT_WARNING_DISABLE_MSVC(4146)
298 if constexpr (
sizeof(T) ==
sizeof(quint32)) {
299 if (v & 0x0000FFFF) c -= 16;
300 if (v & 0x00FF00FF) c -= 8;
301 if (v & 0x0F0F0F0F) c -= 4;
302 if (v & 0x33333333) c -= 2;
303 if (v & 0x55555555) c -= 1;
304 }
else if constexpr (
sizeof(T) ==
sizeof(quint16)) {
305 if (v & 0x000000FF) c -= 8;
306 if (v & 0x00000F0F) c -= 4;
307 if (v & 0x00003333) c -= 2;
308 if (v & 0x00005555) c -= 1;
310 if (v & 0x0000000F) c -= 4;
311 if (v & 0x00000033) c -= 2;
312 if (v & 0x00000055) c -= 1;
320 constexpr int Digits =
std::numeric_limits<T>::digits;
321 unsigned n =
unsigned(s) % Digits;
322 return (v << n) | (v >> (Digits - n));
328 constexpr int Digits =
std::numeric_limits<T>::digits;
329 unsigned n =
unsigned(s) % Digits;
330 return (v >> n) | (v << (Digits - n));
334#if defined(__cpp_lib_int_pow2)
343 constexpr int Digits =
std::numeric_limits<T>::digits;
346 return T(1) << (Digits - countl_zero(T(v - 1)));
352 return std::numeric_limits<T>::digits - countl_zero(v);
358 return v ? T(1) << (bit_width(v) - 1) : 0;
\keyword 16-bit Floating Point Support\inmodule QtCore \inheaderfile QFloat16
Combined button and popup list for selecting options.
constexpr const T & min(const T &a, const T &b)
constexpr bool HasLargerInt
constexpr int qSaturateRound(FP value)
constexpr std::enable_if_t<(std::is_unsigned_v< T >||std::is_signed_v< T >), bool > qMulOverflowGeneric(T v1, T v2, T *r)
constexpr auto qUnsignedAbs(T t)
constexpr std::enable_if_t< std::is_unsigned_v< T >, bool > qAddOverflowGeneric(T v1, T v2, T *r)
constexpr std::enable_if_t< std::is_same_v< T, decltype(+T{})>, bool > qMulOverflowWideMultiplication(T v1, T v2, T *r)
constexpr bool fuzzyCompare(const T &lhs, const S &rhs) noexcept
constexpr Result qCheckedFPConversionToInteger(FP value)
auto hw_popcount(T v) noexcept
auto hw_countl_zero(T v) noexcept
auto hw_countr_zero(T v) noexcept
constexpr std::enable_if_t< std::is_unsigned_v< T >, int > popcount(T v) noexcept
constexpr std::enable_if_t< std::is_unsigned_v< T >, T > bit_floor(T v) noexcept
constexpr std::enable_if_t< std::is_unsigned_v< T >, T > rotl(T v, int s) noexcept
constexpr std::enable_if_t< std::is_unsigned_v< T >, int > countl_zero(T v) noexcept
constexpr std::enable_if_t< std::is_unsigned_v< T >, T > bit_width(T v) noexcept
constexpr std::enable_if_t< std::is_unsigned_v< T >, T > bit_ceil(T v) noexcept
constexpr std::enable_if_t< std::is_unsigned_v< T >, T > rotr(T v, int s) noexcept
constexpr std::enable_if_t< std::is_unsigned_v< T >, int > countr_zero(T v) noexcept
static Q_DECL_CONST_FUNCTION bool isinf(double d)
static Q_DECL_CONST_FUNCTION bool isnan(float f)
static Q_DECL_CONST_FUNCTION bool isinf(float f)
static Q_DECL_CONST_FUNCTION int fpclassify(float f)
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)
static Q_DECL_CONST_FUNCTION bool isfinite(float f)
static quint64 d2i(double d)
Q_CORE_EXPORT int qFpClassify(float val)
Q_CORE_EXPORT int qFpClassify(double val)
static quint32 f2i(float f)
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsFinite(float f)
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 bool qIsFinite(double d)
constexpr bool qSubOverflow(T v1, T *r)
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qInf()
constexpr bool qMulOverflow(T v1, T *r)
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsNaN(float f)
constexpr bool qFuzzyIsNull(double d) noexcept
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsInf(double d)
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsInf(float f)
constexpr bool qFuzzyCompare(float p1, float p2) noexcept
constexpr bool qSubOverflow(T v1, std::integral_constant< T, V2 >, T *r)
constexpr bool qAddOverflow(T v1, T *r)
constexpr std::enable_if< std::is_integral< T >::value, bool >::type qIsNaN(T)
constexpr std::enable_if_t< std::is_unsigned_v< T >||std::is_signed_v< T >, bool > qMulOverflow(T v1, T v2, T *r)
constexpr qint64 qRound64(double d)
constexpr int qRound(float f)
constexpr int qRound(double d)
constexpr bool qIsNull(float f) noexcept
constexpr bool qFuzzyIsNull(float f) noexcept
constexpr std::enable_if_t< std::is_unsigned_v< T >, bool > qSubOverflow(T v1, T v2, T *r)
constexpr bool qFuzzyCompare(double p1, double p2) noexcept
constexpr qint64 qRound64(float f)
constexpr bool qMulOverflow(T v1, std::integral_constant< T, V2 >, T *r)
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qQNaN()
constexpr std::enable_if_t< std::is_unsigned_v< T >, bool > qAddOverflow(T v1, T v2, T *r)
constexpr bool qAddOverflow(T v1, std::integral_constant< T, V2 >, T *r)
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsNaN(double d)
QT_WARNING_PUSH QT_WARNING_DISABLE_FLOAT_COMPARE constexpr bool qIsNull(double d) noexcept
static constexpr auto qt_saturate(From x)
static Q_DECL_CONST_FUNCTION bool qt_is_nan(double d)
#define __has_extension(X)
static Q_DECL_CONST_FUNCTION int qt_fpclassify(float f)
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)
static Q_DECL_CONST_FUNCTION bool qt_is_finite(float f)
static Q_DECL_CONST_FUNCTION bool qt_is_nan(float f)
static Q_DECL_CONST_FUNCTION bool qt_is_inf(float f)