From 9b176281df15c6479510e5c13e12dba24ba31697 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 9 Nov 2023 20:12:36 -0800 Subject: [PATCH] QBitArray: refactor operator~() to write to an uninitialized buffer No functionality change otherwise. Change-Id: I85b3fc2dd45c4693be13fffd179627b2747c132b Reviewed-by: Marc Mutz --- src/corelib/tools/qbitarray.cpp | 28 ++++++++++++++++++---------- src/corelib/tools/qbitarray.h | 3 +++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp index 5c48b3b608c..4a3e929909f 100644 --- a/src/corelib/tools/qbitarray.cpp +++ b/src/corelib/tools/qbitarray.cpp @@ -594,18 +594,26 @@ QBitArray &QBitArray::operator^=(const QBitArray &other) QBitArray QBitArray::operator~() const { - qsizetype sz = size(); - QBitArray a(sz); - const uchar *a1 = reinterpret_cast(d.constData()) + 1; - uchar *a2 = reinterpret_cast(a.d.data()) + 1; - qsizetype n = d.size() - 1; + qsizetype n = d.size(); + QBitArray result(QByteArrayData(n, n)); + const uchar *src = reinterpret_cast(data_ptr().data()); + uchar *dst = reinterpret_cast(result.data_ptr().data()); - while (n-- > 0) - *a2++ = ~*a1++; + uchar bitdiff = 8; + if (n) + bitdiff = dst[0] = src[0]; // copy the count of bits in the last byte - if (sz && sz % 8) - *(a2 - 1) &= (1 << (sz % 8)) - 1; - return a; + for (qsizetype i = 1; i < n; ++i) + dst[i] = ~src[i]; + + if (int tailCount = 16 - bitdiff; tailCount != 8) { + // zero the bits beyond our size in the last byte + Q_ASSERT(n > 1); + uchar tailMask = (1U << tailCount) - 1; + dst[n - 1] &= tailMask; + } + + return result; } /*! diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h index b5b6638507d..a1dde3934c3 100644 --- a/src/corelib/tools/qbitarray.h +++ b/src/corelib/tools/qbitarray.h @@ -18,6 +18,8 @@ class Q_CORE_EXPORT QBitArray friend Q_CORE_EXPORT size_t qHash(const QBitArray &key, size_t seed) noexcept; QByteArray d; + QBitArray(QByteArrayData &&dd) : d(std::move(dd)) {} + template static auto bitLocation(BitArray &ba, qsizetype i) { Q_ASSERT(size_t(i) < size_t(ba.size())); @@ -95,6 +97,7 @@ public: public: typedef QByteArray::DataPointer DataPtr; inline DataPtr &data_ptr() { return d.data_ptr(); } + inline const DataPtr &data_ptr() const { return d.data_ptr(); } };