diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/corelib/kernel/qmetaobject.cpp | 4 | ||||
| -rw-r--r-- | src/corelib/time/qcalendarmath_p.h | 2 | ||||
| -rw-r--r-- | src/corelib/tools/qalgorithms.h | 383 | ||||
| -rw-r--r-- | src/corelib/tools/qtaggedpointer.h | 2 |
4 files changed, 31 insertions, 360 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 17a9856dfd2..8e11bd52578 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -2481,7 +2481,7 @@ bool QMetaMethod::isConst() const */ QMetaMethod::Access QMetaMethod::access() const { - constexpr int AccessShift = QtPrivate::qConstexprCountTrailingZeroBits(AccessMask); + constexpr int AccessShift = qCountTrailingZeroBits(AccessMask); static_assert(AccessPrivate >> AccessShift == Private); static_assert(AccessProtected >> AccessShift == Protected); static_assert(AccessPublic >> AccessShift == Public); @@ -2497,7 +2497,7 @@ QMetaMethod::Access QMetaMethod::access() const */ QMetaMethod::MethodType QMetaMethod::methodType() const { - constexpr int MethodShift = QtPrivate::qConstexprCountTrailingZeroBits(MethodTypeMask); + constexpr int MethodShift = qCountTrailingZeroBits(MethodTypeMask); static_assert(MethodMethod >> MethodShift == Method); static_assert(MethodSignal >> MethodShift == Signal); static_assert(MethodSlot >> MethodShift == Slot); diff --git a/src/corelib/time/qcalendarmath_p.h b/src/corelib/time/qcalendarmath_p.h index 03153b0eed1..e3c89429ae2 100644 --- a/src/corelib/time/qcalendarmath_p.h +++ b/src/corelib/time/qcalendarmath_p.h @@ -89,7 +89,7 @@ template <unsigned b, typename Int, bool> = true> constexpr auto qDivMod(Int a) { - constexpr unsigned w = QtPrivate::qConstexprCountTrailingZeroBits(b); + constexpr unsigned w = qCountTrailingZeroBits(b); struct R { Int quotient; Int remainder; }; if constexpr (std::is_signed_v<Int>) { if (a < 0) diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h index 5b579c0938f..74b46e80ebc 100644 --- a/src/corelib/tools/qalgorithms.h +++ b/src/corelib/tools/qalgorithms.h @@ -9,16 +9,11 @@ #endif #include <QtCore/qglobal.h> +#include <QtCore/q20bit.h> #include <QtCore/q20functional.h> - -#if __has_include(<bit>) && __cplusplus > 201703L -#include <bit> -#endif #include <type_traits> -#ifdef Q_CC_MSVC -#include <intrin.h> -#endif +#define QT_HAS_CONSTEXPR_BITOPS QT_BEGIN_NAMESPACE @@ -37,406 +32,82 @@ inline void qDeleteAll(const Container &c) qDeleteAll(c.begin(), c.end()); } -/* - Warning: The contents of QAlgorithmsPrivate is not a part of the public Qt API - and may be changed from version to version or even be completely removed. -*/ -namespace QAlgorithmsPrivate { - -#if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L -// We use C++20 <bit> operations instead which ensures constexpr bit ops -# define QT_HAS_CONSTEXPR_BITOPS -#elif defined(Q_CC_GNU) -# define QT_HAS_CONSTEXPR_BITOPS -# define QT_HAS_BUILTIN_CTZS -constexpr Q_ALWAYS_INLINE uint qt_builtin_ctzs(quint16 v) noexcept -{ -# if __has_builtin(__builtin_ctzs) - return __builtin_ctzs(v); -# else - return __builtin_ctz(v); -# endif -} -#define QT_HAS_BUILTIN_CLZS -constexpr Q_ALWAYS_INLINE uint qt_builtin_clzs(quint16 v) noexcept -{ -# if __has_builtin(__builtin_clzs) - return __builtin_clzs(v); -# else - return __builtin_clz(v) - 16U; -# endif -} -#define QT_HAS_BUILTIN_CTZ -constexpr Q_ALWAYS_INLINE uint qt_builtin_ctz(quint32 v) noexcept -{ - return __builtin_ctz(v); -} -#define QT_HAS_BUILTIN_CLZ -constexpr Q_ALWAYS_INLINE uint qt_builtin_clz(quint32 v) noexcept -{ - return __builtin_clz(v); -} -#define QT_HAS_BUILTIN_CTZLL -constexpr Q_ALWAYS_INLINE uint qt_builtin_ctzll(quint64 v) noexcept -{ - return __builtin_ctzll(v); -} -#define QT_HAS_BUILTIN_CLZLL -constexpr Q_ALWAYS_INLINE uint qt_builtin_clzll(quint64 v) noexcept -{ - return __builtin_clzll(v); -} -#define QALGORITHMS_USE_BUILTIN_POPCOUNT -constexpr Q_ALWAYS_INLINE uint qt_builtin_popcount(quint32 v) noexcept -{ - return __builtin_popcount(v); -} -constexpr Q_ALWAYS_INLINE uint qt_builtin_popcount(quint8 v) noexcept -{ - return __builtin_popcount(v); -} -constexpr Q_ALWAYS_INLINE uint qt_builtin_popcount(quint16 v) noexcept -{ - return __builtin_popcount(v); -} -#define QALGORITHMS_USE_BUILTIN_POPCOUNTLL -constexpr Q_ALWAYS_INLINE uint qt_builtin_popcountll(quint64 v) noexcept -{ - return __builtin_popcountll(v); -} -#elif defined(Q_CC_MSVC) && !defined(Q_PROCESSOR_ARM) -#define QT_HAS_BUILTIN_CTZ -Q_ALWAYS_INLINE unsigned long qt_builtin_ctz(quint32 val) -{ - unsigned long result; - _BitScanForward(&result, val); - return result; -} -#define QT_HAS_BUILTIN_CLZ -Q_ALWAYS_INLINE unsigned long qt_builtin_clz(quint32 val) -{ - unsigned long result; - _BitScanReverse(&result, val); - // Now Invert the result: clz will count *down* from the msb to the lsb, so the msb index is 31 - // and the lsb index is 0. The result for the index when counting up: msb index is 0 (because it - // starts there), and the lsb index is 31. - result ^= sizeof(quint32) * 8 - 1; - return result; -} -#if Q_PROCESSOR_WORDSIZE == 8 -// These are only defined for 64bit builds. -#define QT_HAS_BUILTIN_CTZLL -Q_ALWAYS_INLINE unsigned long qt_builtin_ctzll(quint64 val) -{ - unsigned long result; - _BitScanForward64(&result, val); - return result; -} -// MSVC calls it _BitScanReverse and returns the carry flag, which we don't need -#define QT_HAS_BUILTIN_CLZLL -Q_ALWAYS_INLINE unsigned long qt_builtin_clzll(quint64 val) -{ - unsigned long result; - _BitScanReverse64(&result, val); - // see qt_builtin_clz - result ^= sizeof(quint64) * 8 - 1; - return result; -} -#endif // MSVC 64bit -# define QT_HAS_BUILTIN_CTZS -Q_ALWAYS_INLINE uint qt_builtin_ctzs(quint16 v) noexcept -{ - return qt_builtin_ctz(v); -} -#define QT_HAS_BUILTIN_CLZS -Q_ALWAYS_INLINE uint qt_builtin_clzs(quint16 v) noexcept -{ - return qt_builtin_clz(v) - 16U; -} - -// Neither MSVC nor the Intel compiler define a macro for the POPCNT processor -// feature, so we're using either the SSE4.2 or the AVX macro as a proxy (Clang -// does define the macro). It's incorrect for two reasons: -// 1. It's a separate bit in CPUID, so a processor could implement SSE4.2 and -// not POPCNT, but that's unlikely to happen. -// 2. There are processors that support POPCNT but not AVX (Intel Nehalem -// architecture), but unlike the other compilers, MSVC has no option -// to generate code for those processors. -// So it's an acceptable compromise. -#if defined(__AVX__) || defined(__SSE4_2__) || defined(__POPCNT__) -#define QT_POPCOUNT_CONSTEXPR -#define QT_POPCOUNT_RELAXED_CONSTEXPR -#define QALGORITHMS_USE_BUILTIN_POPCOUNT -#define QALGORITHMS_USE_BUILTIN_POPCOUNTLL -Q_ALWAYS_INLINE uint qt_builtin_popcount(quint32 v) noexcept -{ - return __popcnt(v); -} -Q_ALWAYS_INLINE uint qt_builtin_popcount(quint8 v) noexcept -{ - return __popcnt16(v); -} -Q_ALWAYS_INLINE uint qt_builtin_popcount(quint16 v) noexcept -{ - return __popcnt16(v); -} -Q_ALWAYS_INLINE uint qt_builtin_popcountll(quint64 v) noexcept -{ -#if Q_PROCESSOR_WORDSIZE == 8 - return __popcnt64(v); -#else - return __popcnt(quint32(v)) + __popcnt(quint32(v >> 32)); -#endif // MSVC 64bit -} - -#endif // __AVX__ || __SSE4_2__ || __POPCNT__ - -#endif // MSVC -#ifndef QT_POPCOUNT_CONSTEXPR -#define QT_POPCOUNT_CONSTEXPR constexpr -#define QT_POPCOUNT_RELAXED_CONSTEXPR constexpr -#endif - -} //namespace QAlgorithmsPrivate - -Q_DECL_CONST_FUNCTION QT_POPCOUNT_CONSTEXPR inline uint qPopulationCount(quint32 v) noexcept +Q_DECL_CONST_FUNCTION constexpr inline uint qPopulationCount(quint32 v) noexcept { -#if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L - return std::popcount(v); -#elif defined QALGORITHMS_USE_BUILTIN_POPCOUNT - return QAlgorithmsPrivate::qt_builtin_popcount(v); -#else - // See http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel - return - (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f + - (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f + - (((v >> 24) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f; -#endif + return q20::popcount(v); } -Q_DECL_CONST_FUNCTION QT_POPCOUNT_CONSTEXPR inline uint qPopulationCount(quint8 v) noexcept +Q_DECL_CONST_FUNCTION constexpr inline uint qPopulationCount(quint8 v) noexcept { -#if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L - return std::popcount(v); -#elif defined QALGORITHMS_USE_BUILTIN_POPCOUNT - return QAlgorithmsPrivate::qt_builtin_popcount(v); -#else - return - (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f; -#endif + return q20::popcount(v); } -Q_DECL_CONST_FUNCTION QT_POPCOUNT_CONSTEXPR inline uint qPopulationCount(quint16 v) noexcept +Q_DECL_CONST_FUNCTION constexpr inline uint qPopulationCount(quint16 v) noexcept { -#if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L - return std::popcount(v); -#elif defined QALGORITHMS_USE_BUILTIN_POPCOUNT - return QAlgorithmsPrivate::qt_builtin_popcount(v); -#else - return - (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f + - (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f; -#endif -} - -Q_DECL_CONST_FUNCTION QT_POPCOUNT_CONSTEXPR inline uint qPopulationCount(quint64 v) noexcept -{ -#if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L - return std::popcount(v); -#elif defined QALGORITHMS_USE_BUILTIN_POPCOUNTLL - return QAlgorithmsPrivate::qt_builtin_popcountll(v); -#else - return - (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f + - (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f + - (((v >> 24) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f + - (((v >> 36) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f + - (((v >> 48) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f + - (((v >> 60) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f; -#endif + return q20::popcount(v); } -Q_DECL_CONST_FUNCTION QT_POPCOUNT_CONSTEXPR inline uint qPopulationCount(long unsigned int v) noexcept +Q_DECL_CONST_FUNCTION constexpr inline uint qPopulationCount(quint64 v) noexcept { - return qPopulationCount(static_cast<quint64>(v)); + return q20::popcount(v); } -#if defined(QALGORITHMS_USE_BUILTIN_POPCOUNT) -#undef QALGORITHMS_USE_BUILTIN_POPCOUNT -#endif -#undef QT_POPCOUNT_CONSTEXPR - -namespace QtPrivate { -constexpr inline uint qConstexprCountTrailingZeroBits(quint32 v) noexcept +Q_DECL_CONST_FUNCTION constexpr inline uint qPopulationCount(long unsigned int v) noexcept { - // see http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightParallel - unsigned int c = 32; // c will be the number of zero bits on the right - v &= -signed(v); - if (v) c--; - if (v & 0x0000FFFF) c -= 16; - if (v & 0x00FF00FF) c -= 8; - if (v & 0x0F0F0F0F) c -= 4; - if (v & 0x33333333) c -= 2; - if (v & 0x55555555) c -= 1; - return c; -} - -constexpr inline uint qConstexprCountTrailingZeroBits(quint64 v) noexcept -{ - quint32 x = static_cast<quint32>(v); - return x ? qConstexprCountTrailingZeroBits(x) - : 32 + qConstexprCountTrailingZeroBits(static_cast<quint32>(v >> 32)); -} - -constexpr inline uint qConstexprCountTrailingZeroBits(quint8 v) noexcept -{ - unsigned int c = 8; // c will be the number of zero bits on the right - v &= quint8(-signed(v)); - if (v) c--; - if (v & 0x0000000F) c -= 4; - if (v & 0x00000033) c -= 2; - if (v & 0x00000055) c -= 1; - return c; -} - -constexpr inline uint qConstexprCountTrailingZeroBits(quint16 v) noexcept -{ - unsigned int c = 16; // c will be the number of zero bits on the right - v &= quint16(-signed(v)); - if (v) c--; - if (v & 0x000000FF) c -= 8; - if (v & 0x00000F0F) c -= 4; - if (v & 0x00003333) c -= 2; - if (v & 0x00005555) c -= 1; - return c; -} - -constexpr inline uint qConstexprCountTrailingZeroBits(unsigned long v) noexcept -{ - return qConstexprCountTrailingZeroBits(QIntegerForSizeof<long>::Unsigned(v)); -} + return q20::popcount(v); } constexpr inline uint qCountTrailingZeroBits(quint32 v) noexcept { -#if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L - return std::countr_zero(v); -#elif defined(QT_HAS_BUILTIN_CTZ) - return v ? QAlgorithmsPrivate::qt_builtin_ctz(v) : 32U; -#else - return QtPrivate::qConstexprCountTrailingZeroBits(v); -#endif + return q20::countr_zero(v); } constexpr inline uint qCountTrailingZeroBits(quint8 v) noexcept { -#if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L - return std::countr_zero(v); -#elif defined(QT_HAS_BUILTIN_CTZ) - return v ? QAlgorithmsPrivate::qt_builtin_ctz(v) : 8U; -#else - return QtPrivate::qConstexprCountTrailingZeroBits(v); -#endif + return q20::countr_zero(v); } constexpr inline uint qCountTrailingZeroBits(quint16 v) noexcept { -#if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L - return std::countr_zero(v); -#elif defined(QT_HAS_BUILTIN_CTZS) - return v ? QAlgorithmsPrivate::qt_builtin_ctzs(v) : 16U; -#else - return QtPrivate::qConstexprCountTrailingZeroBits(v); -#endif + return q20::countr_zero(v); } constexpr inline uint qCountTrailingZeroBits(quint64 v) noexcept { -#if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L - return std::countr_zero(v); -#elif defined(QT_HAS_BUILTIN_CTZLL) - return v ? QAlgorithmsPrivate::qt_builtin_ctzll(v) : 64; -#else - return QtPrivate::qConstexprCountTrailingZeroBits(v); -#endif + return q20::countr_zero(v); } constexpr inline uint qCountTrailingZeroBits(unsigned long v) noexcept { - return qCountTrailingZeroBits(QIntegerForSizeof<long>::Unsigned(v)); + return q20::countr_zero(v); } -QT_POPCOUNT_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint32 v) noexcept +constexpr inline uint qCountLeadingZeroBits(quint32 v) noexcept { -#if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L - return std::countl_zero(v); -#elif defined(QT_HAS_BUILTIN_CLZ) - return v ? QAlgorithmsPrivate::qt_builtin_clz(v) : 32U; -#else - // Hacker's Delight, 2nd ed. Fig 5-16, p. 102 - v = v | (v >> 1); - v = v | (v >> 2); - v = v | (v >> 4); - v = v | (v >> 8); - v = v | (v >> 16); - return qPopulationCount(~v); -#endif + return q20::countl_zero(v); } -QT_POPCOUNT_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint8 v) noexcept +constexpr inline uint qCountLeadingZeroBits(quint8 v) noexcept { -#if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L - return std::countl_zero(v); -#elif defined(QT_HAS_BUILTIN_CLZ) - return v ? QAlgorithmsPrivate::qt_builtin_clz(v)-24U : 8U; -#else - v = v | (v >> 1); - v = v | (v >> 2); - v = v | (v >> 4); - return qPopulationCount(static_cast<quint8>(~v)); -#endif + return q20::countl_zero(v); } -QT_POPCOUNT_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint16 v) noexcept +constexpr inline uint qCountLeadingZeroBits(quint16 v) noexcept { -#if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L - return std::countl_zero(v); -#elif defined(QT_HAS_BUILTIN_CLZS) - return v ? QAlgorithmsPrivate::qt_builtin_clzs(v) : 16U; -#else - v = v | (v >> 1); - v = v | (v >> 2); - v = v | (v >> 4); - v = v | (v >> 8); - return qPopulationCount(static_cast<quint16>(~v)); -#endif + return q20::countl_zero(v); } -QT_POPCOUNT_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint64 v) noexcept +constexpr inline uint qCountLeadingZeroBits(quint64 v) noexcept { -#if defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L - return std::countl_zero(v); -#elif defined(QT_HAS_BUILTIN_CLZLL) - return v ? QAlgorithmsPrivate::qt_builtin_clzll(v) : 64U; -#else - v = v | (v >> 1); - v = v | (v >> 2); - v = v | (v >> 4); - v = v | (v >> 8); - v = v | (v >> 16); - v = v | (v >> 32); - return qPopulationCount(~v); -#endif + return q20::countl_zero(v); } -QT_POPCOUNT_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(unsigned long v) noexcept +constexpr inline uint qCountLeadingZeroBits(unsigned long v) noexcept { - return qCountLeadingZeroBits(QIntegerForSizeof<long>::Unsigned(v)); + return q20::countl_zero(v); } -#undef QT_POPCOUNT_RELAXED_CONSTEXPR - template <typename InputIterator, typename Result, typename Separator = Result, typename Projection = q20::identity> Result qJoin(InputIterator first, InputIterator last, Result init, const Separator &separator = {}, diff --git a/src/corelib/tools/qtaggedpointer.h b/src/corelib/tools/qtaggedpointer.h index 6c467d59f84..36d679b4ec9 100644 --- a/src/corelib/tools/qtaggedpointer.h +++ b/src/corelib/tools/qtaggedpointer.h @@ -21,7 +21,7 @@ namespace QtPrivate { static_assert((alignment & (alignment - 1)) == 0, "Alignment of template parameter must be power of two"); - static constexpr quint8 tagBits = quint8{QtPrivate::qConstexprCountTrailingZeroBits(alignment)}; + static constexpr quint8 tagBits = quint8{qCountTrailingZeroBits(alignment)}; static_assert(tagBits > 0, "Alignment of template parameter does not allow any tags"); |
