Introduce QArrayData::detachCapacity
This follows QArrayData::detachFlags's lead. Given the (known) size for a detached container, the function helps determine capacity, ensuring the capacityReserved flag is respected. This further helps aggregating behaviour on detach in QArrayData itself. SimpleVector was previously using qMax(capacity(), newSize), but there's no reason to pin the previous capacity value if reserve() wasn't requested. It now uses detachCapacity(). Change-Id: Ide2d99ea7ecd2cd98ae4c1aa397b4475d09c8485 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
646dc6c5da
commit
8c413f3eff
@ -91,6 +91,13 @@ struct Q_CORE_EXPORT QArrayData
|
||||
|
||||
Q_DECLARE_FLAGS(AllocationOptions, AllocationOption)
|
||||
|
||||
size_t detachCapacity(size_t newSize) const
|
||||
{
|
||||
if (capacityReserved && newSize < alloc)
|
||||
return alloc;
|
||||
return newSize;
|
||||
}
|
||||
|
||||
AllocationOptions detachFlags() const
|
||||
{
|
||||
AllocationOptions result;
|
||||
|
@ -171,7 +171,7 @@ public:
|
||||
private:
|
||||
Data *clone(QArrayData::AllocationOptions options) const Q_REQUIRED_RESULT
|
||||
{
|
||||
QArrayDataPointer copy(Data::allocate(d->alloc ? d->alloc : d->size,
|
||||
QArrayDataPointer copy(Data::allocate(d->detachCapacity(d->size),
|
||||
options));
|
||||
if (d->size)
|
||||
copy->copyAppend(d->begin(), d->end());
|
||||
|
@ -184,7 +184,7 @@ public:
|
||||
if (d->ref.isShared()
|
||||
|| capacity() - size() < size_t(last - first)) {
|
||||
SimpleVector detached(Data::allocate(
|
||||
qMax(capacity(), size() + (last - first)),
|
||||
d->detachCapacity(size() + (last - first)),
|
||||
d->detachFlags() | Data::Grow));
|
||||
|
||||
detached.d->copyAppend(first, last);
|
||||
@ -205,7 +205,7 @@ public:
|
||||
if (d->ref.isShared()
|
||||
|| capacity() - size() < size_t(last - first)) {
|
||||
SimpleVector detached(Data::allocate(
|
||||
qMax(capacity(), size() + (last - first)),
|
||||
d->detachCapacity(size() + (last - first)),
|
||||
d->detachFlags() | Data::Grow));
|
||||
|
||||
if (d->size) {
|
||||
@ -245,7 +245,7 @@ public:
|
||||
if (d->ref.isShared()
|
||||
|| capacity() - size() < size_t(last - first)) {
|
||||
SimpleVector detached(Data::allocate(
|
||||
qMax(capacity(), size() + (last - first)),
|
||||
d->detachCapacity(size() + (last - first)),
|
||||
d->detachFlags() | Data::Grow));
|
||||
|
||||
if (position)
|
||||
|
@ -1175,8 +1175,10 @@ void tst_QArrayData::setSharable_data()
|
||||
|
||||
QArrayDataPointer<int> emptyReserved(QTypedArrayData<int>::allocate(5,
|
||||
QArrayData::CapacityReserved));
|
||||
QArrayDataPointer<int> nonEmpty(QTypedArrayData<int>::allocate(10,
|
||||
QArrayDataPointer<int> nonEmpty(QTypedArrayData<int>::allocate(5,
|
||||
QArrayData::Default));
|
||||
QArrayDataPointer<int> nonEmptyExtraCapacity(
|
||||
QTypedArrayData<int>::allocate(10, QArrayData::Default));
|
||||
QArrayDataPointer<int> nonEmptyReserved(QTypedArrayData<int>::allocate(15,
|
||||
QArrayData::CapacityReserved));
|
||||
QArrayDataPointer<int> staticArray(
|
||||
@ -1185,13 +1187,15 @@ void tst_QArrayData::setSharable_data()
|
||||
QTypedArrayData<int>::fromRawData(staticArrayData.data, 10));
|
||||
|
||||
nonEmpty->copyAppend(5, 1);
|
||||
nonEmptyExtraCapacity->copyAppend(5, 1);
|
||||
nonEmptyReserved->copyAppend(7, 2);
|
||||
|
||||
QTest::newRow("shared-null") << null << size_t(0) << size_t(0) << false << 0;
|
||||
QTest::newRow("shared-empty") << empty << size_t(0) << size_t(0) << false << 0;
|
||||
// unsharable-empty implicitly tested in shared-empty
|
||||
QTest::newRow("empty-reserved") << emptyReserved << size_t(0) << size_t(5) << true << 0;
|
||||
QTest::newRow("non-empty") << nonEmpty << size_t(5) << size_t(10) << false << 1;
|
||||
QTest::newRow("non-empty") << nonEmpty << size_t(5) << size_t(5) << false << 1;
|
||||
QTest::newRow("non-empty-extra-capacity") << nonEmptyExtraCapacity << size_t(5) << size_t(10) << false << 1;
|
||||
QTest::newRow("non-empty-reserved") << nonEmptyReserved << size_t(7) << size_t(15) << true << 2;
|
||||
QTest::newRow("static-array") << staticArray << size_t(10) << size_t(0) << false << 3;
|
||||
QTest::newRow("raw-data") << rawData << size_t(10) << size_t(0) << false << 3;
|
||||
@ -1229,8 +1233,10 @@ void tst_QArrayData::setSharable()
|
||||
// Unshare, must detach
|
||||
array.setSharable(false);
|
||||
|
||||
// Immutability (alloc == 0) is lost on detach
|
||||
if (capacity == 0 && size != 0)
|
||||
// Immutability (alloc == 0) is lost on detach, as is additional capacity
|
||||
// if capacityReserved flag is not set.
|
||||
if ((capacity == 0 && size != 0)
|
||||
|| (!isCapacityReserved && capacity > size))
|
||||
capacity = size;
|
||||
|
||||
QVERIFY(!array->ref.isShared());
|
||||
|
Loading…
Reference in New Issue
Block a user