diff options
Diffstat (limited to 'src/corelib/tools')
-rw-r--r-- | src/corelib/tools/qalgorithms.h | 67 | ||||
-rw-r--r-- | src/corelib/tools/qalgorithms.qdoc | 31 | ||||
-rw-r--r-- | src/corelib/tools/qbitarray.cpp | 11 | ||||
-rw-r--r-- | src/corelib/tools/qbitarray.h | 1 | ||||
-rw-r--r-- | src/corelib/tools/qharfbuzz_p.h | 14 | ||||
-rw-r--r-- | src/corelib/tools/qset.h | 1 |
6 files changed, 103 insertions, 22 deletions
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h index e3b76886f1..8337afcb9d 100644 --- a/src/corelib/tools/qalgorithms.h +++ b/src/corelib/tools/qalgorithms.h @@ -516,6 +516,73 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator } //namespace QAlgorithmsPrivate + +// Use __builtin_popcount on gcc. Clang claims to be gcc +// but has a bug where __builtin_popcount is not marked as +// constexpr. +#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) +#define QALGORITHMS_USE_BUILTIN_POPCOUNT +#endif + +Q_DECL_CONSTEXPR inline uint qPopulationCount(quint32 v) +{ +#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT + return __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 +} + +Q_DECL_CONSTEXPR inline uint qPopulationCount(quint8 v) +{ +#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT + return __builtin_popcount(v); +#else + return + (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f; +#endif +} + +Q_DECL_CONSTEXPR inline uint qPopulationCount(quint16 v) +{ +#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT + return __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_CONSTEXPR inline uint qPopulationCount(quint64 v) +{ +#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT + return __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 +} + +Q_DECL_CONSTEXPR inline uint qPopulationCount(long unsigned int v) +{ + return qPopulationCount(static_cast<quint64>(v)); +} + +#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) +#undef QALGORITHMS_USE_BUILTIN_POPCOUNT +#endif + + QT_END_NAMESPACE #endif // QALGORITHMS_H diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc index cc544af868..7c3aa1a3b2 100644 --- a/src/corelib/tools/qalgorithms.qdoc +++ b/src/corelib/tools/qalgorithms.qdoc @@ -635,3 +635,34 @@ of \a value in the variable passed as a reference in argument \a n. \sa {qLess()}{qLess<T>()} */ + + +/*! + \fn uint qPopulationCount(quint8 v) + \relates <QtAlgorithms> + \since 5.2 + + Returns the number of bits set in \a v. This number also called + the Hamming Weight of \a v. + */ + +/*! + \fn uint qPopulationCount(quint16 v) + \relates <QtAlgorithms> + \since 5.2 + \overload + */ + +/*! + \fn uint qPopulationCount(quint32 v) + \relates <QtAlgorithms> + \since 5.2 + \overload + */ + +/*! + \fn uint qPopulationCount(quint64 v) + \relates <QtAlgorithms> + \since 5.2 + \overload + */ diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp index 2b459b2b1b..4949476f25 100644 --- a/src/corelib/tools/qbitarray.cpp +++ b/src/corelib/tools/qbitarray.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qbitarray.h" +#include <qalgorithms.h> #include <qdatastream.h> #include <qdebug.h> #include <string.h> @@ -159,24 +160,18 @@ int QBitArray::count(bool on) const for (int i = 0; i < len; ++i) numBits += testBit(i); #else - // See http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel const quint8 *bits = reinterpret_cast<const quint8 *>(d.data()) + 1; while (len >= 32) { quint32 v = quint32(bits[0]) | (quint32(bits[1]) << 8) | (quint32(bits[2]) << 16) | (quint32(bits[3]) << 24); - quint32 c = ((v & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f; - c += (((v & 0xfff000) >> 12) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f; - c += ((v >> 24) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f; len -= 32; bits += 4; - numBits += int(c); + numBits += int(qPopulationCount(v)); } while (len >= 24) { quint32 v = quint32(bits[0]) | (quint32(bits[1]) << 8) | (quint32(bits[2]) << 16); - quint32 c = ((v & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f; - c += (((v & 0xfff000) >> 12) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f; len -= 24; bits += 3; - numBits += int(c); + numBits += int(qPopulationCount(v)); } while (len >= 0) { if (bits[len / 8] & (1 << ((len - 1) & 7))) diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h index 1103712627..eaf9b2ff25 100644 --- a/src/corelib/tools/qbitarray.h +++ b/src/corelib/tools/qbitarray.h @@ -61,6 +61,7 @@ public: QBitArray(const QBitArray &other) : d(other.d) {} inline QBitArray &operator=(const QBitArray &other) { d = other.d; return *this; } #ifdef Q_COMPILER_RVALUE_REFS + inline QBitArray(QBitArray &&other) : d(std::move(other.d)) {} inline QBitArray &operator=(QBitArray &&other) { qSwap(d, other.d); return *this; } #endif diff --git a/src/corelib/tools/qharfbuzz_p.h b/src/corelib/tools/qharfbuzz_p.h index 27ddb44e91..1471fd5712 100644 --- a/src/corelib/tools/qharfbuzz_p.h +++ b/src/corelib/tools/qharfbuzz_p.h @@ -140,20 +140,6 @@ typedef enum { HB_ScriptCount = HB_Script_Inherited } HB_Script; -typedef enum { - HB_NoJustification= 0, /* Justification can't be applied after this glyph */ - HB_Arabic_Space = 1, /* This glyph represents a space inside arabic text */ - HB_Character = 2, /* Inter-character justification point follows this glyph */ - HB_Space = 4, /* This glyph represents a blank outside an Arabic run */ - HB_Arabic_Normal = 7, /* Normal Middle-Of-Word glyph that connects to the right (begin) */ - HB_Arabic_Waw = 8, /* Next character is final form of Waw/Ain/Qaf/Fa */ - HB_Arabic_BaRa = 9, /* Next two chars are Ba + Ra/Ya/AlefMaksura */ - HB_Arabic_Alef = 10, /* Next character is final form of Alef/Tah/Lam/Kaf/Gaf */ - HB_Arabic_HaaDal = 11, /* Next character is final form of Haa/Dal/Taa Marbutah */ - HB_Arabic_Seen = 12, /* Initial or Medial form Of Seen/Sad */ - HB_Arabic_Kashida = 13 /* Kashida(U+640) in middle of word */ -} HB_JustificationClass; - #ifdef __xlC__ typedef unsigned hb_bitfield; #else diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index d5c3637293..1390c67c80 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.h @@ -70,6 +70,7 @@ public: inline QSet<T> &operator=(const QSet<T> &other) { q_hash = other.q_hash; return *this; } #ifdef Q_COMPILER_RVALUE_REFS + inline QSet(QSet &&other) : q_hash(qMove(other.q_hash)) {} inline QSet<T> &operator=(QSet<T> &&other) { qSwap(q_hash, other.q_hash); return *this; } #endif |