summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qbitarray.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2023-11-09 20:12:36 -0800
committerThiago Macieira <thiago.macieira@intel.com>2023-12-07 14:55:07 -0800
commit9b176281df15c6479510e5c13e12dba24ba31697 (patch)
tree9d5a816847497ec4b103bd2cc9bd8278e3a8ca3b /src/corelib/tools/qbitarray.cpp
parent93233516957f71054c42ba843cdd57216834acd7 (diff)
QBitArray: refactor operator~() to write to an uninitialized buffer
No functionality change otherwise. Change-Id: I85b3fc2dd45c4693be13fffd179627b2747c132b Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Diffstat (limited to 'src/corelib/tools/qbitarray.cpp')
-rw-r--r--src/corelib/tools/qbitarray.cpp30
1 files changed, 19 insertions, 11 deletions
diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp
index 5c48b3b608..4a3e929909 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<const uchar *>(d.constData()) + 1;
- uchar *a2 = reinterpret_cast<uchar *>(a.d.data()) + 1;
- qsizetype n = d.size() - 1;
-
- while (n-- > 0)
- *a2++ = ~*a1++;
+ qsizetype n = d.size();
+ QBitArray result(QByteArrayData(n, n));
+ const uchar *src = reinterpret_cast<const uchar *>(data_ptr().data());
+ uchar *dst = reinterpret_cast<uchar *>(result.data_ptr().data());
+
+ uchar bitdiff = 8;
+ if (n)
+ bitdiff = dst[0] = src[0]; // copy the count of bits in the last byte
+
+ 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;
+ }
- if (sz && sz % 8)
- *(a2 - 1) &= (1 << (sz % 8)) - 1;
- return a;
+ return result;
}
/*!