File indexing completed on 2025-09-15 09:07:17
0001
0002
0003
0004 #ifndef QALGORITHMS_H
0005 #define QALGORITHMS_H
0006
0007 #if 0
0008 #pragma qt_class(QtAlgorithms)
0009 #endif
0010
0011 #include <QtCore/qglobal.h>
0012
0013 #if __has_include(<bit>) && __cplusplus > 201703L
0014 #include <bit>
0015 #endif
0016 #include <type_traits>
0017
0018 #ifdef Q_CC_MSVC
0019 #include <intrin.h>
0020 #endif
0021
0022 QT_BEGIN_NAMESPACE
0023
0024 template <typename ForwardIterator>
0025 Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
0026 {
0027 while (begin != end) {
0028 delete *begin;
0029 ++begin;
0030 }
0031 }
0032
0033 template <typename Container>
0034 inline void qDeleteAll(const Container &c)
0035 {
0036 qDeleteAll(c.begin(), c.end());
0037 }
0038
0039
0040
0041
0042
0043 namespace QAlgorithmsPrivate {
0044
0045 #if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
0046
0047 # define QT_HAS_CONSTEXPR_BITOPS
0048 #elif defined(Q_CC_GNU)
0049 # define QT_HAS_CONSTEXPR_BITOPS
0050 # define QT_HAS_BUILTIN_CTZS
0051 constexpr Q_ALWAYS_INLINE uint qt_builtin_ctzs(quint16 v) noexcept
0052 {
0053 # if __has_builtin(__builtin_ctzs)
0054 return __builtin_ctzs(v);
0055 # else
0056 return __builtin_ctz(v);
0057 # endif
0058 }
0059 #define QT_HAS_BUILTIN_CLZS
0060 constexpr Q_ALWAYS_INLINE uint qt_builtin_clzs(quint16 v) noexcept
0061 {
0062 # if __has_builtin(__builtin_clzs)
0063 return __builtin_clzs(v);
0064 # else
0065 return __builtin_clz(v) - 16U;
0066 # endif
0067 }
0068 #define QT_HAS_BUILTIN_CTZ
0069 constexpr Q_ALWAYS_INLINE uint qt_builtin_ctz(quint32 v) noexcept
0070 {
0071 return __builtin_ctz(v);
0072 }
0073 #define QT_HAS_BUILTIN_CLZ
0074 constexpr Q_ALWAYS_INLINE uint qt_builtin_clz(quint32 v) noexcept
0075 {
0076 return __builtin_clz(v);
0077 }
0078 #define QT_HAS_BUILTIN_CTZLL
0079 constexpr Q_ALWAYS_INLINE uint qt_builtin_ctzll(quint64 v) noexcept
0080 {
0081 return __builtin_ctzll(v);
0082 }
0083 #define QT_HAS_BUILTIN_CLZLL
0084 constexpr Q_ALWAYS_INLINE uint qt_builtin_clzll(quint64 v) noexcept
0085 {
0086 return __builtin_clzll(v);
0087 }
0088 #define QALGORITHMS_USE_BUILTIN_POPCOUNT
0089 constexpr Q_ALWAYS_INLINE uint qt_builtin_popcount(quint32 v) noexcept
0090 {
0091 return __builtin_popcount(v);
0092 }
0093 constexpr Q_ALWAYS_INLINE uint qt_builtin_popcount(quint8 v) noexcept
0094 {
0095 return __builtin_popcount(v);
0096 }
0097 constexpr Q_ALWAYS_INLINE uint qt_builtin_popcount(quint16 v) noexcept
0098 {
0099 return __builtin_popcount(v);
0100 }
0101 #define QALGORITHMS_USE_BUILTIN_POPCOUNTLL
0102 constexpr Q_ALWAYS_INLINE uint qt_builtin_popcountll(quint64 v) noexcept
0103 {
0104 return __builtin_popcountll(v);
0105 }
0106 #elif defined(Q_CC_MSVC) && !defined(Q_PROCESSOR_ARM)
0107 #define QT_HAS_BUILTIN_CTZ
0108 Q_ALWAYS_INLINE unsigned long qt_builtin_ctz(quint32 val)
0109 {
0110 unsigned long result;
0111 _BitScanForward(&result, val);
0112 return result;
0113 }
0114 #define QT_HAS_BUILTIN_CLZ
0115 Q_ALWAYS_INLINE unsigned long qt_builtin_clz(quint32 val)
0116 {
0117 unsigned long result;
0118 _BitScanReverse(&result, val);
0119
0120
0121
0122 result ^= sizeof(quint32) * 8 - 1;
0123 return result;
0124 }
0125 #if Q_PROCESSOR_WORDSIZE == 8
0126
0127 #define QT_HAS_BUILTIN_CTZLL
0128 Q_ALWAYS_INLINE unsigned long qt_builtin_ctzll(quint64 val)
0129 {
0130 unsigned long result;
0131 _BitScanForward64(&result, val);
0132 return result;
0133 }
0134
0135 #define QT_HAS_BUILTIN_CLZLL
0136 Q_ALWAYS_INLINE unsigned long qt_builtin_clzll(quint64 val)
0137 {
0138 unsigned long result;
0139 _BitScanReverse64(&result, val);
0140
0141 result ^= sizeof(quint64) * 8 - 1;
0142 return result;
0143 }
0144 #endif
0145 # define QT_HAS_BUILTIN_CTZS
0146 Q_ALWAYS_INLINE uint qt_builtin_ctzs(quint16 v) noexcept
0147 {
0148 return qt_builtin_ctz(v);
0149 }
0150 #define QT_HAS_BUILTIN_CLZS
0151 Q_ALWAYS_INLINE uint qt_builtin_clzs(quint16 v) noexcept
0152 {
0153 return qt_builtin_clz(v) - 16U;
0154 }
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165 #if defined(__AVX__) || defined(__SSE4_2__) || defined(__POPCNT__)
0166 #define QT_POPCOUNT_CONSTEXPR
0167 #define QT_POPCOUNT_RELAXED_CONSTEXPR
0168 #define QALGORITHMS_USE_BUILTIN_POPCOUNT
0169 #define QALGORITHMS_USE_BUILTIN_POPCOUNTLL
0170 Q_ALWAYS_INLINE uint qt_builtin_popcount(quint32 v) noexcept
0171 {
0172 return __popcnt(v);
0173 }
0174 Q_ALWAYS_INLINE uint qt_builtin_popcount(quint8 v) noexcept
0175 {
0176 return __popcnt16(v);
0177 }
0178 Q_ALWAYS_INLINE uint qt_builtin_popcount(quint16 v) noexcept
0179 {
0180 return __popcnt16(v);
0181 }
0182 Q_ALWAYS_INLINE uint qt_builtin_popcountll(quint64 v) noexcept
0183 {
0184 #if Q_PROCESSOR_WORDSIZE == 8
0185 return __popcnt64(v);
0186 #else
0187 return __popcnt(quint32(v)) + __popcnt(quint32(v >> 32));
0188 #endif
0189 }
0190
0191 #endif
0192
0193 #endif
0194
0195 #ifndef QT_POPCOUNT_CONSTEXPR
0196 #define QT_POPCOUNT_CONSTEXPR constexpr
0197 #define QT_POPCOUNT_RELAXED_CONSTEXPR constexpr
0198 #endif
0199
0200 }
0201
0202 Q_DECL_CONST_FUNCTION QT_POPCOUNT_CONSTEXPR inline uint qPopulationCount(quint32 v) noexcept
0203 {
0204 #if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
0205 return std::popcount(v);
0206 #elif defined QALGORITHMS_USE_BUILTIN_POPCOUNT
0207 return QAlgorithmsPrivate::qt_builtin_popcount(v);
0208 #else
0209
0210 return
0211 (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
0212 (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
0213 (((v >> 24) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
0214 #endif
0215 }
0216
0217 Q_DECL_CONST_FUNCTION QT_POPCOUNT_CONSTEXPR inline uint qPopulationCount(quint8 v) noexcept
0218 {
0219 #if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
0220 return std::popcount(v);
0221 #elif defined QALGORITHMS_USE_BUILTIN_POPCOUNT
0222 return QAlgorithmsPrivate::qt_builtin_popcount(v);
0223 #else
0224 return
0225 (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
0226 #endif
0227 }
0228
0229 Q_DECL_CONST_FUNCTION QT_POPCOUNT_CONSTEXPR inline uint qPopulationCount(quint16 v) noexcept
0230 {
0231 #if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
0232 return std::popcount(v);
0233 #elif defined QALGORITHMS_USE_BUILTIN_POPCOUNT
0234 return QAlgorithmsPrivate::qt_builtin_popcount(v);
0235 #else
0236 return
0237 (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
0238 (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
0239 #endif
0240 }
0241
0242 Q_DECL_CONST_FUNCTION QT_POPCOUNT_CONSTEXPR inline uint qPopulationCount(quint64 v) noexcept
0243 {
0244 #if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
0245 return std::popcount(v);
0246 #elif defined QALGORITHMS_USE_BUILTIN_POPCOUNTLL
0247 return QAlgorithmsPrivate::qt_builtin_popcountll(v);
0248 #else
0249 return
0250 (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
0251 (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
0252 (((v >> 24) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
0253 (((v >> 36) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
0254 (((v >> 48) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
0255 (((v >> 60) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
0256 #endif
0257 }
0258
0259 Q_DECL_CONST_FUNCTION QT_POPCOUNT_CONSTEXPR inline uint qPopulationCount(long unsigned int v) noexcept
0260 {
0261 return qPopulationCount(static_cast<quint64>(v));
0262 }
0263
0264 #if defined(QALGORITHMS_USE_BUILTIN_POPCOUNT)
0265 #undef QALGORITHMS_USE_BUILTIN_POPCOUNT
0266 #endif
0267 #undef QT_POPCOUNT_CONSTEXPR
0268
0269 namespace QtPrivate {
0270 constexpr inline uint qConstexprCountTrailingZeroBits(quint32 v) noexcept
0271 {
0272
0273 unsigned int c = 32;
0274 v &= -signed(v);
0275 if (v) c--;
0276 if (v & 0x0000FFFF) c -= 16;
0277 if (v & 0x00FF00FF) c -= 8;
0278 if (v & 0x0F0F0F0F) c -= 4;
0279 if (v & 0x33333333) c -= 2;
0280 if (v & 0x55555555) c -= 1;
0281 return c;
0282 }
0283
0284 constexpr inline uint qConstexprCountTrailingZeroBits(quint64 v) noexcept
0285 {
0286 quint32 x = static_cast<quint32>(v);
0287 return x ? qConstexprCountTrailingZeroBits(x)
0288 : 32 + qConstexprCountTrailingZeroBits(static_cast<quint32>(v >> 32));
0289 }
0290
0291 constexpr inline uint qConstexprCountTrailingZeroBits(quint8 v) noexcept
0292 {
0293 unsigned int c = 8;
0294 v &= quint8(-signed(v));
0295 if (v) c--;
0296 if (v & 0x0000000F) c -= 4;
0297 if (v & 0x00000033) c -= 2;
0298 if (v & 0x00000055) c -= 1;
0299 return c;
0300 }
0301
0302 constexpr inline uint qConstexprCountTrailingZeroBits(quint16 v) noexcept
0303 {
0304 unsigned int c = 16;
0305 v &= quint16(-signed(v));
0306 if (v) c--;
0307 if (v & 0x000000FF) c -= 8;
0308 if (v & 0x00000F0F) c -= 4;
0309 if (v & 0x00003333) c -= 2;
0310 if (v & 0x00005555) c -= 1;
0311 return c;
0312 }
0313
0314 constexpr inline uint qConstexprCountTrailingZeroBits(unsigned long v) noexcept
0315 {
0316 return qConstexprCountTrailingZeroBits(QIntegerForSizeof<long>::Unsigned(v));
0317 }
0318 }
0319
0320 constexpr inline uint qCountTrailingZeroBits(quint32 v) noexcept
0321 {
0322 #if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
0323 return std::countr_zero(v);
0324 #elif defined(QT_HAS_BUILTIN_CTZ)
0325 return v ? QAlgorithmsPrivate::qt_builtin_ctz(v) : 32U;
0326 #else
0327 return QtPrivate::qConstexprCountTrailingZeroBits(v);
0328 #endif
0329 }
0330
0331 constexpr inline uint qCountTrailingZeroBits(quint8 v) noexcept
0332 {
0333 #if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
0334 return std::countr_zero(v);
0335 #elif defined(QT_HAS_BUILTIN_CTZ)
0336 return v ? QAlgorithmsPrivate::qt_builtin_ctz(v) : 8U;
0337 #else
0338 return QtPrivate::qConstexprCountTrailingZeroBits(v);
0339 #endif
0340 }
0341
0342 constexpr inline uint qCountTrailingZeroBits(quint16 v) noexcept
0343 {
0344 #if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
0345 return std::countr_zero(v);
0346 #elif defined(QT_HAS_BUILTIN_CTZS)
0347 return v ? QAlgorithmsPrivate::qt_builtin_ctzs(v) : 16U;
0348 #else
0349 return QtPrivate::qConstexprCountTrailingZeroBits(v);
0350 #endif
0351 }
0352
0353 constexpr inline uint qCountTrailingZeroBits(quint64 v) noexcept
0354 {
0355 #if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
0356 return std::countr_zero(v);
0357 #elif defined(QT_HAS_BUILTIN_CTZLL)
0358 return v ? QAlgorithmsPrivate::qt_builtin_ctzll(v) : 64;
0359 #else
0360 return QtPrivate::qConstexprCountTrailingZeroBits(v);
0361 #endif
0362 }
0363
0364 constexpr inline uint qCountTrailingZeroBits(unsigned long v) noexcept
0365 {
0366 return qCountTrailingZeroBits(QIntegerForSizeof<long>::Unsigned(v));
0367 }
0368
0369 QT_POPCOUNT_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint32 v) noexcept
0370 {
0371 #if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
0372 return std::countl_zero(v);
0373 #elif defined(QT_HAS_BUILTIN_CLZ)
0374 return v ? QAlgorithmsPrivate::qt_builtin_clz(v) : 32U;
0375 #else
0376
0377 v = v | (v >> 1);
0378 v = v | (v >> 2);
0379 v = v | (v >> 4);
0380 v = v | (v >> 8);
0381 v = v | (v >> 16);
0382 return qPopulationCount(~v);
0383 #endif
0384 }
0385
0386 QT_POPCOUNT_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint8 v) noexcept
0387 {
0388 #if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
0389 return std::countl_zero(v);
0390 #elif defined(QT_HAS_BUILTIN_CLZ)
0391 return v ? QAlgorithmsPrivate::qt_builtin_clz(v)-24U : 8U;
0392 #else
0393 v = v | (v >> 1);
0394 v = v | (v >> 2);
0395 v = v | (v >> 4);
0396 return qPopulationCount(static_cast<quint8>(~v));
0397 #endif
0398 }
0399
0400 QT_POPCOUNT_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint16 v) noexcept
0401 {
0402 #if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
0403 return std::countl_zero(v);
0404 #elif defined(QT_HAS_BUILTIN_CLZS)
0405 return v ? QAlgorithmsPrivate::qt_builtin_clzs(v) : 16U;
0406 #else
0407 v = v | (v >> 1);
0408 v = v | (v >> 2);
0409 v = v | (v >> 4);
0410 v = v | (v >> 8);
0411 return qPopulationCount(static_cast<quint16>(~v));
0412 #endif
0413 }
0414
0415 QT_POPCOUNT_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint64 v) noexcept
0416 {
0417 #if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
0418 return std::countl_zero(v);
0419 #elif defined(QT_HAS_BUILTIN_CLZLL)
0420 return v ? QAlgorithmsPrivate::qt_builtin_clzll(v) : 64U;
0421 #else
0422 v = v | (v >> 1);
0423 v = v | (v >> 2);
0424 v = v | (v >> 4);
0425 v = v | (v >> 8);
0426 v = v | (v >> 16);
0427 v = v | (v >> 32);
0428 return qPopulationCount(~v);
0429 #endif
0430 }
0431
0432 QT_POPCOUNT_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(unsigned long v) noexcept
0433 {
0434 return qCountLeadingZeroBits(QIntegerForSizeof<long>::Unsigned(v));
0435 }
0436
0437 #undef QT_POPCOUNT_RELAXED_CONSTEXPR
0438
0439 namespace QtPrivate {
0440
0441 template <typename T>
0442 constexpr
0443 std::enable_if_t<std::conjunction_v<std::is_integral<T>, std::is_unsigned<T>>, int>
0444 log2i(T x)
0445 {
0446
0447 Q_ASSERT(x > 0);
0448
0449 return int(sizeof(T) * 8 - 1 - qCountLeadingZeroBits(x));
0450 }
0451
0452 }
0453
0454 QT_END_NAMESPACE
0455
0456 #endif