summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/text/qbytearray.cpp21
-rw-r--r--src/corelib/text/qbytearray.h18
-rw-r--r--src/corelib/text/qstring.cpp18
-rw-r--r--src/corelib/text/qstring.h18
-rw-r--r--src/corelib/tools/qarraydata.cpp5
-rw-r--r--src/corelib/tools/qarraydata.h29
-rw-r--r--src/corelib/tools/qarraydataops.h27
-rw-r--r--src/corelib/tools/qarraydatapointer.h53
-rw-r--r--src/corelib/tools/qlist.h36
9 files changed, 77 insertions, 148 deletions
diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp
index 1a1b2d86b0e..1b5fa8e5eb5 100644
--- a/src/corelib/text/qbytearray.cpp
+++ b/src/corelib/text/qbytearray.cpp
@@ -1175,7 +1175,8 @@ QByteArray &QByteArray::operator=(const char *str)
const auto capacityAtEnd = d->allocatedCapacity() - d.freeSpaceAtBegin();
if (d->needsDetach() || len > capacityAtEnd
|| (len < size() && len < (capacityAtEnd >> 1)))
- reallocData(len, d->detachFlags());
+ // ### inefficient! reallocData() does copy the old data and we then overwrite it in the next line
+ reallocData(len, QArrayData::KeepSize);
memcpy(d.data(), str, len + 1); // include null terminator
d.size = len;
}
@@ -1676,7 +1677,7 @@ void QByteArray::resize(qsizetype size)
const auto capacityAtEnd = capacity() - d.freeSpaceAtBegin();
if (d->needsDetach() || size > capacityAtEnd)
- reallocData(size, d->detachFlags() | Data::GrowsForward);
+ reallocData(size, QArrayData::Grow);
d.size = size;
if (d->allocatedCapacity())
d.data()[size] = 0;
@@ -1700,7 +1701,7 @@ QByteArray &QByteArray::fill(char ch, qsizetype size)
return *this;
}
-void QByteArray::reallocData(qsizetype alloc, Data::ArrayOptions options)
+void QByteArray::reallocData(qsizetype alloc, QArrayData::AllocationOption option)
{
if (!alloc) {
d = DataPointer::fromRawData(&_empty, 0);
@@ -1713,13 +1714,13 @@ void QByteArray::reallocData(qsizetype alloc, Data::ArrayOptions options)
const bool slowReallocatePath = d.freeSpaceAtBegin() > 0;
if (d->needsDetach() || slowReallocatePath) {
- DataPointer dd(Data::allocate(alloc, options), qMin(alloc, d.size));
+ DataPointer dd(Data::allocate(alloc, option), qMin(alloc, d.size));
if (dd.size > 0)
::memcpy(dd.data(), d.data(), dd.size);
dd.data()[dd.size] = 0;
d = dd;
} else {
- d->reallocate(alloc, options & (QArrayData::GrowsBackwards|QArrayData::GrowsForward) ? QArrayData::Grow : QArrayData::KeepSize);
+ d->reallocate(alloc, option);
}
}
@@ -1729,7 +1730,7 @@ void QByteArray::reallocGrowData(qsizetype n)
n = 1;
if (d->needsDetach()) {
- DataPointer dd(DataPointer::allocateGrow(d, n, DataPointer::AllocateAtEnd));
+ DataPointer dd(DataPointer::allocateGrow(d, n, QArrayData::AllocateAtEnd));
dd->copyAppend(d.data(), d.data() + d.size);
dd.data()[dd.size] = 0;
d = dd;
@@ -1936,9 +1937,9 @@ QByteArray &QByteArray::insert(qsizetype i, QByteArrayView data)
sizeToGrow += i - oldSize;
if (d->needsDetach() || (sizeToGrow > d.freeSpaceAtBegin() && sizeToGrow > d.freeSpaceAtEnd())) {
- DataPointer::AllocationPosition pos = DataPointer::AllocateAtEnd;
+ QArrayData::AllocationPosition pos = QArrayData::AllocateAtEnd;
if (oldSize != 0 && i <= (oldSize >> 1))
- pos = DataPointer::AllocateAtBeginning;
+ pos = QArrayData::AllocateAtBeginning;
DataPointer detached(DataPointer::allocateGrow(d, sizeToGrow, pos));
auto where = d.constBegin() + qMin(i, d->size);
@@ -2000,9 +2001,9 @@ QByteArray &QByteArray::insert(qsizetype i, qsizetype count, char ch)
sizeToGrow += i - oldSize;
if (d->needsDetach() || (sizeToGrow > d.freeSpaceAtBegin() && sizeToGrow > d.freeSpaceAtEnd())) {
- DataPointer::AllocationPosition pos = DataPointer::AllocateAtEnd;
+ QArrayData::AllocationPosition pos = QArrayData::AllocateAtEnd;
if (oldSize != 0 && i <= (oldSize >> 1))
- pos = DataPointer::AllocateAtBeginning;
+ pos = QArrayData::AllocateAtBeginning;
DataPointer detached(DataPointer::allocateGrow(d, sizeToGrow, pos));
auto where = d.constBegin() + qMin(i, d->size);
diff --git a/src/corelib/text/qbytearray.h b/src/corelib/text/qbytearray.h
index c70a7a82d9b..95b607e9dc3 100644
--- a/src/corelib/text/qbytearray.h
+++ b/src/corelib/text/qbytearray.h
@@ -509,7 +509,7 @@ public:
}
private:
- void reallocData(qsizetype alloc, Data::ArrayOptions options);
+ void reallocData(qsizetype alloc, QArrayData::AllocationOption option);
void reallocGrowData(qsizetype n);
void expand(qsizetype i);
QByteArray nulTerminated() const;
@@ -562,7 +562,7 @@ inline const char *QByteArray::data() const
inline const char *QByteArray::constData() const
{ return data(); }
inline void QByteArray::detach()
-{ if (d->needsDetach()) reallocData(size(), d->detachFlags()); }
+{ if (d->needsDetach()) reallocData(size(), QArrayData::KeepSize); }
inline bool QByteArray::isDetached() const
{ return !d->isShared(); }
inline QByteArray::QByteArray(const QByteArray &a) noexcept : d(a.d)
@@ -572,22 +572,20 @@ inline qsizetype QByteArray::capacity() const { return qsizetype(d->constAllocat
inline void QByteArray::reserve(qsizetype asize)
{
- if (d->needsDetach() || asize > capacity() - d->freeSpaceAtBegin()) {
- reallocData(qMax(size(), asize), d->detachFlags() | Data::CapacityReserved);
- } else {
+ if (d->needsDetach() || asize > capacity() - d->freeSpaceAtBegin())
+ reallocData(qMax(size(), asize), QArrayData::KeepSize);
+ if (d->constAllocatedCapacity())
d->setFlag(Data::CapacityReserved);
- }
}
inline void QByteArray::squeeze()
{
if (!d.isMutable())
return;
- if (d->needsDetach() || size() < capacity()) {
- reallocData(size(), d->detachFlags() & ~Data::CapacityReserved);
- } else {
+ if (d->needsDetach() || size() < capacity())
+ reallocData(size(), QArrayData::KeepSize);
+ if (d->constAllocatedCapacity())
d->clearFlag(Data::CapacityReserved);
- }
}
inline char &QByteArray::operator[](qsizetype i)
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp
index ebdb5710414..40d69c9d9c6 100644
--- a/src/corelib/text/qstring.cpp
+++ b/src/corelib/text/qstring.cpp
@@ -2415,7 +2415,7 @@ void QString::resize(qsizetype size)
const auto capacityAtEnd = capacity() - d.freeSpaceAtBegin();
if (d->needsDetach() || size > capacityAtEnd)
- reallocData(size, d->detachFlags() | Data::GrowsForward);
+ reallocData(size, QArrayData::Grow);
d.size = size;
if (d->allocatedCapacity())
d.data()[size] = 0;
@@ -2497,7 +2497,7 @@ void QString::resize(qsizetype size, QChar fillChar)
\sa reserve(), capacity()
*/
-void QString::reallocData(qsizetype alloc, Data::ArrayOptions allocOptions)
+void QString::reallocData(qsizetype alloc, QArrayData::AllocationOption option)
{
if (!alloc) {
d = DataPointer::fromRawData(&_empty, 0);
@@ -2510,13 +2510,13 @@ void QString::reallocData(qsizetype alloc, Data::ArrayOptions allocOptions)
const bool slowReallocatePath = d.freeSpaceAtBegin() > 0;
if (d->needsDetach() || slowReallocatePath) {
- DataPointer dd(Data::allocate(alloc, allocOptions), qMin(alloc, d.size));
+ DataPointer dd(Data::allocate(alloc, option), qMin(alloc, d.size));
if (dd.size > 0)
::memcpy(dd.data(), d.data(), dd.size * sizeof(QChar));
dd.data()[dd.size] = 0;
d = dd;
} else {
- d->reallocate(alloc, allocOptions & (QArrayData::GrowsBackwards|QArrayData::GrowsForward) ? QArrayData::Grow : QArrayData::KeepSize);
+ d->reallocate(alloc, option);
}
}
@@ -2526,7 +2526,7 @@ void QString::reallocGrowData(qsizetype n)
n = 1;
if (d->needsDetach()) {
- DataPointer dd(DataPointer::allocateGrow(d, n, DataPointer::AllocateAtEnd));
+ DataPointer dd(DataPointer::allocateGrow(d, n, QArrayData::AllocateAtEnd));
dd->copyAppend(d.data(), d.data() + d.size);
dd.data()[dd.size] = 0;
d = dd;
@@ -2737,9 +2737,9 @@ QString& QString::insert(qsizetype i, const QChar *unicode, qsizetype size)
sizeToGrow += i - oldSize;
if (d->needsDetach() || (sizeToGrow > d.freeSpaceAtBegin() && sizeToGrow > d.freeSpaceAtEnd())) {
- DataPointer::AllocationPosition pos = DataPointer::AllocateAtEnd;
+ QArrayData::AllocationPosition pos = QArrayData::AllocateAtEnd;
if (oldSize != 0 && i <= (oldSize >> 1))
- pos = DataPointer::AllocateAtBeginning;
+ pos = QArrayData::AllocateAtBeginning;
DataPointer detached(DataPointer::allocateGrow(d, sizeToGrow, pos));
auto where = d.constBegin() + qMin(i, d->size);
@@ -4054,7 +4054,7 @@ QString &QString::replace(const QRegularExpression &re, const QString &after)
if (!iterator.hasNext()) // no matches at all
return *this;
- reallocData(d.size, d->detachFlags());
+ reallocData(d.size, QArrayData::KeepSize);
qsizetype numCaptures = re.captureCount();
@@ -6157,7 +6157,7 @@ const ushort *QString::utf16() const
{
if (!d->isMutable()) {
// ensure '\0'-termination for ::fromRawData strings
- const_cast<QString*>(this)->reallocData(d.size, d->detachFlags());
+ const_cast<QString*>(this)->reallocData(d.size, QArrayData::KeepSize);
}
return reinterpret_cast<const ushort *>(d.data());
}
diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h
index 66a99d4e43a..013b367b5ce 100644
--- a/src/corelib/text/qstring.h
+++ b/src/corelib/text/qstring.h
@@ -1058,7 +1058,7 @@ private:
DataPointer d;
static const char16_t _empty;
- void reallocData(qsizetype alloc, Data::ArrayOptions options);
+ void reallocData(qsizetype alloc, QArrayData::AllocationOption option);
void reallocGrowData(qsizetype n);
static int compare_helper(const QChar *data1, qsizetype length1,
const QChar *data2, qsizetype length2,
@@ -1195,7 +1195,7 @@ inline QChar *QString::data()
inline const QChar *QString::constData() const
{ return data(); }
inline void QString::detach()
-{ if (d->needsDetach()) reallocData(d.size, d->detachFlags()); }
+{ if (d->needsDetach()) reallocData(d.size, QArrayData::KeepSize); }
inline bool QString::isDetached() const
{ return !d->isShared(); }
inline void QString::clear()
@@ -1267,22 +1267,20 @@ inline QString::~QString() {}
inline void QString::reserve(qsizetype asize)
{
- if (d->needsDetach() || asize >= capacity() - d.freeSpaceAtBegin()) {
- reallocData(qMax(asize, size()), d->detachFlags() | Data::CapacityReserved);
- } else {
+ if (d->needsDetach() || asize >= capacity() - d.freeSpaceAtBegin())
+ reallocData(qMax(asize, size()), QArrayData::KeepSize);
+ if (d->constAllocatedCapacity())
d->setFlag(Data::CapacityReserved);
- }
}
inline void QString::squeeze()
{
if (!d.isMutable())
return;
- if (d->needsDetach() || size() < capacity()) {
- reallocData(d.size, d->detachFlags() & ~Data::CapacityReserved);
- } else {
+ if (d->needsDetach() || size() < capacity())
+ reallocData(d.size, QArrayData::KeepSize);
+ if (d->constAllocatedCapacity())
d->clearFlag(Data::CapacityReserved);
- }
}
inline QString &QString::setUtf16(const ushort *autf16, qsizetype asize)
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp
index 4feb52a7103..3217e87cc8e 100644
--- a/src/corelib/tools/qarraydata.cpp
+++ b/src/corelib/tools/qarraydata.cpp
@@ -185,7 +185,7 @@ static QArrayData *allocateData(qsizetype allocSize)
}
void *QArrayData::allocate(QArrayData **dptr, qsizetype objectSize, qsizetype alignment,
- qsizetype capacity, ArrayOptions options) noexcept
+ qsizetype capacity, QArrayData::AllocationOption option) noexcept
{
Q_ASSERT(dptr);
// Alignment is a power of two
@@ -208,7 +208,7 @@ void *QArrayData::allocate(QArrayData **dptr, qsizetype objectSize, qsizetype al
}
Q_ASSERT(headerSize > 0);
- qsizetype allocSize = calculateBlockSize(capacity, objectSize, headerSize, (options & (GrowsForward|GrowsBackwards)) ? QArrayData::Grow : QArrayData::KeepSize);
+ qsizetype allocSize = calculateBlockSize(capacity, objectSize, headerSize, option);
allocSize = reserveExtraBytes(allocSize);
if (Q_UNLIKELY(allocSize < 0)) { // handle overflow. cannot allocate reliably
*dptr = nullptr;
@@ -220,7 +220,6 @@ void *QArrayData::allocate(QArrayData **dptr, qsizetype objectSize, qsizetype al
if (header) {
// find where offset should point to so that data() is aligned to alignment bytes
data = QTypedArrayData<void>::dataStart(header, alignment);
- header->flags = options & CapacityReserved;
header->alloc = qsizetype(capacity);
}
diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h
index 76f2c330430..9ada91d04bf 100644
--- a/src/corelib/tools/qarraydata.h
+++ b/src/corelib/tools/qarraydata.h
@@ -56,12 +56,14 @@ struct Q_CORE_EXPORT QArrayData
KeepSize
};
- enum ArrayOption {
- /// this option is used by the allocate() function
- DefaultAllocationFlags = 0,
- CapacityReserved = 0x1, //!< the capacity was reserved by the user, try to keep it
- GrowsForward = 0x2, //!< allocate with eyes towards growing through append()
- GrowsBackwards = 0x4 //!< allocate with eyes towards growing through prepend()
+ enum AllocationPosition {
+ AllocateAtEnd,
+ AllocateAtBeginning
+ };
+
+ enum ArrayOption {
+ ArrayOptionDefault = 0,
+ CapacityReserved = 0x1 //!< the capacity was reserved by the user, try to keep it
};
Q_DECLARE_FLAGS(ArrayOptions, ArrayOption)
@@ -112,20 +114,12 @@ struct Q_CORE_EXPORT QArrayData
return newSize;
}
- ArrayOptions detachFlags() const noexcept
- {
- ArrayOptions result = DefaultAllocationFlags;
- if (flags & CapacityReserved)
- result |= CapacityReserved;
- return result;
- }
-
[[nodiscard]]
#if defined(Q_CC_GNU)
__attribute__((__malloc__))
#endif
static void *allocate(QArrayData **pdata, qsizetype objectSize, qsizetype alignment,
- qsizetype capacity, ArrayOptions options = DefaultAllocationFlags) noexcept;
+ qsizetype capacity, AllocationOption option = QArrayData::KeepSize) noexcept;
[[nodiscard]] static QPair<QArrayData *, void *> reallocateUnaligned(QArrayData *data, void *dataPointer,
qsizetype objectSize, qsizetype newCapacity, AllocationOption option) noexcept;
static void deallocate(QArrayData *data, qsizetype objectSize,
@@ -213,12 +207,11 @@ struct QTypedArrayData
struct AlignmentDummy { QArrayData header; T data; };
- [[nodiscard]] static QPair<QTypedArrayData *, T *> allocate(qsizetype capacity,
- ArrayOptions options = DefaultAllocationFlags)
+ [[nodiscard]] static QPair<QTypedArrayData *, T *> allocate(qsizetype capacity, AllocationOption option = QArrayData::KeepSize)
{
static_assert(sizeof(QTypedArrayData) == sizeof(QArrayData));
QArrayData *d;
- void *result = QArrayData::allocate(&d, sizeof(T), alignof(AlignmentDummy), capacity, options);
+ void *result = QArrayData::allocate(&d, sizeof(T), alignof(AlignmentDummy), capacity, option);
#if (defined(Q_CC_GNU) && Q_CC_GNU >= 407) || QT_HAS_BUILTIN(__builtin_assume_aligned)
result = __builtin_assume_aligned(result, Q_ALIGNOF(AlignmentDummy));
#endif
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h
index a904341effe..7121da66602 100644
--- a/src/corelib/tools/qarraydataops.h
+++ b/src/corelib/tools/qarraydataops.h
@@ -1094,33 +1094,6 @@ public:
}
}
- // Returns whether reallocation is desirable before adding more elements
- // into the container. This is a helper function that one can use to
- // theoretically improve average operations performance. Ignoring this
- // function does not affect the correctness of the array operations.
- bool shouldGrowBeforeInsert(const_iterator where, qsizetype n) const noexcept
- {
- if (this->d == nullptr)
- return true;
- if (this->d->flags & QArrayData::CapacityReserved)
- return false;
- if (!(this->d->flags & (QArrayData::GrowsForward | QArrayData::GrowsBackwards)))
- return false;
- Q_ASSERT(where >= this->begin() && where <= this->end()); // in range
-
- const qsizetype freeAtBegin = this->freeSpaceAtBegin();
- const qsizetype freeAtEnd = this->freeSpaceAtEnd();
-
- // Idea: always reallocate when not enough space at the corresponding end
- if (where == this->end()) { // append or size == 0
- return freeAtEnd < n;
- } else if (where == this->begin()) { // prepend
- return freeAtBegin < n;
- } else { // general insert
- return (freeAtBegin < n && freeAtEnd < n);
- }
- }
-
// using Base::truncate;
// using Base::destroyAll;
// using Base::assign;
diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h
index 398dc1a607c..d483a5a5e5b 100644
--- a/src/corelib/tools/qarraydatapointer.h
+++ b/src/corelib/tools/qarraydatapointer.h
@@ -165,7 +165,7 @@ public:
bool detach()
{
if (needsDetach()) {
- QPair<Data *, T *> copy = clone(detachFlags());
+ QPair<Data *, T *> copy = clone();
QArrayDataPointer old(d, ptr, size);
d = copy.first;
ptr = copy.second;
@@ -185,10 +185,9 @@ public:
bool isSharedWith(const QArrayDataPointer &other) const noexcept { return d && d == other.d; }
bool needsDetach() const noexcept { return !d || d->needsDetach(); }
qsizetype detachCapacity(qsizetype newSize) const noexcept { return d ? d->detachCapacity(newSize) : newSize; }
- const typename Data::ArrayOptions flags() const noexcept { return d ? typename Data::ArrayOption(d->flags) : Data::DefaultAllocationFlags; }
+ const typename Data::ArrayOptions flags() const noexcept { return d ? typename Data::ArrayOption(d->flags) : Data::ArrayOptionDefault; }
void setFlag(typename Data::ArrayOptions f) noexcept { Q_ASSERT(d); d->flags |= f; }
void clearFlag(typename Data::ArrayOptions f) noexcept { Q_ASSERT(d); d->flags &= ~f; }
- typename Data::ArrayOptions detachFlags() const noexcept { return d ? d->detachFlags() : Data::DefaultAllocationFlags; }
Data *d_ptr() noexcept { return d; }
void setBegin(T *begin) noexcept { ptr = begin; }
@@ -207,40 +206,8 @@ public:
return d->constAllocatedCapacity() - freeSpaceAtBegin() - this->size;
}
- static QArrayDataPointer allocateGrow(const QArrayDataPointer &from,
- qsizetype newSize, QArrayData::ArrayOptions options)
- {
- return allocateGrow(from, from.detachCapacity(newSize), newSize, options);
- }
-
- static QArrayDataPointer allocateGrow(const QArrayDataPointer &from, qsizetype capacity,
- qsizetype newSize, QArrayData::ArrayOptions options)
- {
- auto [header, dataPtr] = Data::allocate(capacity, options);
- const bool valid = header != nullptr && dataPtr != nullptr;
- const bool grows = (options & (Data::GrowsForward | Data::GrowsBackwards));
- if (!valid || !grows)
- return QArrayDataPointer(header, dataPtr);
-
- // must always hold true, as valid is the first condition we check and
- // if-statement short-circuits
- Q_ASSERT(valid);
-
- // Idea: * when growing backwards, adjust pointer to prepare free space at the beginning
- // * when growing forward, adjust by the previous data pointer offset
-
- // TODO: what's with CapacityReserved?
- dataPtr += (options & Data::GrowsBackwards) ? (header->alloc - newSize) / 2
- : from.freeSpaceAtBegin();
- return QArrayDataPointer(header, dataPtr);
- }
-
- enum AllocationPosition {
- AllocateAtEnd,
- AllocateAtBeginning
- };
// allocate and grow. Ensure that at the minimum requiredSpace is available at the requested end
- static QArrayDataPointer allocateGrow(const QArrayDataPointer &from, qsizetype n, AllocationPosition position)
+ static QArrayDataPointer allocateGrow(const QArrayDataPointer &from, qsizetype n, QArrayData::AllocationPosition position)
{
// calculate new capacity. We keep the free capacity at the side that does not have to grow
// to avoid quadratic behavior with mixed append/prepend cases
@@ -249,10 +216,10 @@ public:
qsizetype minimalCapacity = qMax(from.size, from.constAllocatedCapacity()) + n;
// subtract the free space at the side we want to allocate. This ensures that the total size requested is
// the existing allocation at the other side + size + n.
- minimalCapacity -= (position == AllocateAtEnd) ? from.freeSpaceAtEnd() : from.freeSpaceAtBegin();
+ minimalCapacity -= (position == QArrayData::AllocateAtEnd) ? from.freeSpaceAtEnd() : from.freeSpaceAtBegin();
qsizetype capacity = from.detachCapacity(minimalCapacity);
const bool grows = capacity > from.constAllocatedCapacity();
- auto [header, dataPtr] = Data::allocate(capacity, grows ? QArrayData::GrowsBackwards : QArrayData::DefaultAllocationFlags);
+ auto [header, dataPtr] = Data::allocate(capacity, grows ? QArrayData::Grow : QArrayData::KeepSize);
const bool valid = header != nullptr && dataPtr != nullptr;
if (!valid)
return QArrayDataPointer(header, dataPtr);
@@ -261,8 +228,9 @@ public:
// * when growing forward, adjust by the previous data pointer offset
// TODO: what's with CapacityReserved?
- dataPtr += (position == AllocateAtBeginning) ? qMax(0, (header->alloc - from.size - n) / 2)
+ dataPtr += (position == QArrayData::AllocateAtBeginning) ? qMax(0, (header->alloc - from.size - n) / 2)
: from.freeSpaceAtBegin();
+ header->flags = from.flags();
return QArrayDataPointer(header, dataPtr);
}
@@ -277,14 +245,15 @@ public:
}
private:
- [[nodiscard]] QPair<Data *, T *> clone(QArrayData::ArrayOptions options) const
+ [[nodiscard]] QPair<Data *, T *> clone() const
{
- QPair<Data *, T *> pair = Data::allocate(detachCapacity(size), options);
+ QPair<Data *, T *> pair = Data::allocate(detachCapacity(size), QArrayData::KeepSize);
QArrayDataPointer copy(pair.first, pair.second, 0);
if (size)
copy->copyAppend(begin(), end());
- pair.first = copy.d;
+ if (pair.first)
+ pair.first->flags = flags();
copy.d = nullptr;
copy.ptr = nullptr;
return pair;
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index e278b70b2d7..960bf18cacc 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -291,7 +291,7 @@ public:
return;
if (d->needsDetach()) {
// must allocate memory
- DataPointer detached(Data::allocate(d.allocatedCapacity(), d->detachFlags()));
+ DataPointer detached(Data::allocate(d.allocatedCapacity()));
d.swap(detached);
} else {
d->truncate(0);
@@ -582,8 +582,7 @@ inline void QList<T>::resize_internal(qsizetype newSize)
if (d->needsDetach() || newSize > capacity() - d.freeSpaceAtBegin()) {
// must allocate memory
- DataPointer detached(Data::allocate(d->detachCapacity(newSize),
- d->detachFlags()));
+ DataPointer detached(Data::allocate(d->detachCapacity(newSize)));
if (size() && newSize) {
detached->copyAppend(constBegin(), constBegin() + qMin(newSize, size()));
}
@@ -608,9 +607,10 @@ void QList<T>::reserve(qsizetype asize)
}
}
- DataPointer detached(Data::allocate(qMax(asize, size()),
- d->detachFlags() | Data::CapacityReserved));
+ DataPointer detached(Data::allocate(qMax(asize, size())));
detached->copyAppend(constBegin(), constEnd());
+ if (detached.d_ptr())
+ detached->setFlag(Data::CapacityReserved);
d.swap(detached);
}
@@ -621,15 +621,14 @@ inline void QList<T>::squeeze()
return;
if (d->needsDetach() || size() < capacity()) {
// must allocate memory
- DataPointer detached(Data::allocate(size(), d->detachFlags() & ~Data::CapacityReserved));
+ DataPointer detached(Data::allocate(size()));
if (size()) {
detached->copyAppend(constBegin(), constEnd());
}
d.swap(detached);
- } else {
- // We're detached so this is fine
- d->clearFlag(Data::CapacityReserved);
}
+ // We're detached so this is fine
+ d->clearFlag(Data::CapacityReserved);
}
template <typename T>
@@ -646,7 +645,7 @@ inline void QList<T>::remove(qsizetype i, qsizetype n)
((d->flags() & Data::CapacityReserved) == 0
&& newSize < d->allocatedCapacity()/2)) {
// allocate memory
- DataPointer detached(Data::allocate(d->detachCapacity(newSize), d->detachFlags()));
+ DataPointer detached(Data::allocate(d->detachCapacity(newSize)));
const_iterator where = constBegin() + i;
if (newSize) {
detached->copyAppend(constBegin(), where);
@@ -672,7 +671,7 @@ inline void QList<T>::append(const_iterator i1, const_iterator i2)
return;
const auto distance = std::distance(i1, i2);
if (d->needsDetach() || distance > d.freeSpaceAtEnd()) {
- DataPointer detached(DataPointer::allocateGrow(d, distance, DataPointer::AllocateAtEnd));
+ DataPointer detached(DataPointer::allocateGrow(d, distance, QArrayData::AllocateAtEnd));
detached->copyAppend(constBegin(), constEnd());
detached->copyAppend(i1, i2);
d.swap(detached);
@@ -691,7 +690,7 @@ inline void QList<T>::append(QList<T> &&other)
return append(other);
if (d->needsDetach() || other.size() > d.freeSpaceAtEnd()) {
- DataPointer detached(DataPointer::allocateGrow(d, other.size(), DataPointer::AllocateAtEnd));
+ DataPointer detached(DataPointer::allocateGrow(d, other.size(), QArrayData::AllocateAtEnd));
if (!d->needsDetach())
detached->moveAppend(begin(), end());
@@ -711,7 +710,7 @@ template<typename... Args>
inline typename QList<T>::reference QList<T>::emplaceFront(Args &&... args)
{
if (d->needsDetach() || !d.freeSpaceAtBegin()) {
- DataPointer detached(DataPointer::allocateGrow(d, 1, DataPointer::AllocateAtBeginning));
+ DataPointer detached(DataPointer::allocateGrow(d, 1, QArrayData::AllocateAtBeginning));
detached->emplace(detached.begin(), std::forward<Args>(args)...);
if (!d.needsDetach())
@@ -737,9 +736,9 @@ QList<T>::insert(qsizetype i, qsizetype n, parameter_type t)
// it's not worth wasting CPU cycles for that
if (d->needsDetach() || (n > d.freeSpaceAtBegin() && n > d.freeSpaceAtEnd())) {
- typename DataPointer::AllocationPosition pos = DataPointer::AllocateAtEnd;
+ typename QArrayData::AllocationPosition pos = QArrayData::AllocateAtEnd;
if (d.size != 0 && i <= (d.size >> 1))
- pos = DataPointer::AllocateAtBeginning;
+ pos = QArrayData::AllocateAtBeginning;
DataPointer detached(DataPointer::allocateGrow(d, n, pos));
const_iterator where = constBegin() + i;
@@ -767,9 +766,9 @@ QList<T>::emplace(qsizetype i, Args&&... args)
Q_ASSERT_X(i >= 0 && i <= d->size, "QList<T>::insert", "index out of range");
if (d->needsDetach() || (d.size == d.constAllocatedCapacity())) {
- typename DataPointer::AllocationPosition pos = DataPointer::AllocateAtEnd;
+ typename QArrayData::AllocationPosition pos = QArrayData::AllocateAtEnd;
if (d.size != 0 && i <= (d.size >> 1))
- pos = DataPointer::AllocateAtBeginning;
+ pos = QArrayData::AllocateAtBeginning;
DataPointer detached(DataPointer::allocateGrow(d, 1, pos));
const_iterator where = constBegin() + i;
@@ -810,8 +809,7 @@ inline QList<T> &QList<T>::fill(parameter_type t, qsizetype newSize)
newSize = size();
if (d->needsDetach() || newSize > capacity()) {
// must allocate memory
- DataPointer detached(Data::allocate(d->detachCapacity(newSize),
- d->detachFlags()));
+ DataPointer detached(Data::allocate(d->detachCapacity(newSize)));
detached->copyAppend(newSize, t);
d.swap(detached);
} else {