summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qarraydatapointer.h
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2022-01-12 12:49:02 -0800
committerThiago Macieira <thiago.macieira@intel.com>2022-01-17 19:56:41 -0800
commit86b346823e114ac0b6b1c2ab6065ce53b1393de0 (patch)
tree567c2eb6c50caca1c438d855b14f53de0b9ab8bd /src/corelib/tools/qarraydatapointer.h
parenta59e7361714d50687d82a2d9abae9e95825a23b6 (diff)
QString::toLatin1_helper_inplace: simplify the code
Hot function, so help the compiler out. In particular, this removes any touch to the ref count, so there are no atomic operations or dead code leading to memory allocations and deallocations. Change-Id: I0e5f6bec596a4a78bd3bfffd16c9a0fbd8dd2c12 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Diffstat (limited to 'src/corelib/tools/qarraydatapointer.h')
-rw-r--r--src/corelib/tools/qarraydatapointer.h22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h
index 4d83b890cc..dda3cf13eb 100644
--- a/src/corelib/tools/qarraydatapointer.h
+++ b/src/corelib/tools/qarraydatapointer.h
@@ -168,6 +168,28 @@ public:
/*! \internal
+ Reinterprets the data of this QArrayDataPointer to type X. It's the
+ caller's responsibility to ensure that the data contents are valid and
+ properly aligned, particularly if T and X are not trivial types (i.e,
+ don't do that). The current size is kept and the allocated capacity is
+ updated to account for the difference in the element type's size.
+
+ This is used in QString::fromLatin1 to perform in-place conversion of
+ QString to QByteArray.
+ */
+ template <typename X> QArrayDataPointer<X> reinterpreted() &&
+ {
+ if (sizeof(T) != sizeof(X)) {
+ Q_ASSERT(!d->isShared());
+ d->alloc = d->alloc * sizeof(T) / sizeof(X);
+ }
+ auto od = reinterpret_cast<QTypedArrayData<X> *>(std::exchange(d, nullptr));
+ auto optr = reinterpret_cast<X *>(std::exchange(ptr, nullptr));
+ return { od, optr, std::exchange(size, 0) };
+ }
+
+ /*! \internal
+
Detaches this (optionally) and grows to accommodate the free space for
\a n elements at the required side. The side is determined from \a pos.