summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2012-06-05 17:21:19 +0200
committerThiago Macieira <thiago.macieira@intel.com>2016-09-07 14:35:51 +0000
commit42f974f56b18e365c3343545a9491452683fed30 (patch)
tree8325af7fad8f19acad3ee34ea12e0591ded32162 /tests
parent8e5cd8017e9a88de426b3c23c328a68a70089b1c (diff)
Add QArrayData::reallocateUnaligned for QString and QByteArray
This function reallocates a QArrayData block with realloc() but, as the name says, it's only valid for types that do not increase the alignment requirements. I don't think it's worth doing this for types that do increase the alignment requirements, since we don't know the alignment of the pointer returned by realloc(). If the new pointer modulo the alignment is different from the old pointer modulo the alignment, we'd have to memmove data around, which would be quite inefficient (realloc might have memcpy'ed already and this memmove would copy data to nearby). This function is intended to be used especially in QString and QByteArray, which were already using realloc() on pointers created by QArrayData::allocate. Change-Id: I45b61247db2e84797ad794c1049c47a09c1fb29a Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
index 0c41f66357..65887e50d3 100644
--- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
+++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
@@ -65,6 +65,8 @@ private slots:
void simpleVectorReserve();
void allocate_data();
void allocate();
+ void reallocate_data() { allocate_data(); }
+ void reallocate();
void alignment_data();
void alignment();
void typedData();
@@ -742,6 +744,54 @@ void tst_QArrayData::allocate()
}
}
+void tst_QArrayData::reallocate()
+{
+ QFETCH(size_t, objectSize);
+ QFETCH(size_t, alignment);
+ QFETCH(QArrayData::AllocationOptions, allocateOptions);
+ QFETCH(bool, isCapacityReserved);
+ QFETCH(const QArrayData *, commonEmpty);
+
+ // Maximum alignment that can be requested is that of QArrayData,
+ // otherwise, we can't use reallocate().
+ Q_ASSERT(alignment <= Q_ALIGNOF(QArrayData));
+
+ // Minimum alignment that can be requested is that of QArrayData.
+ // Typically, this alignment is sizeof(void *) and ensured by malloc.
+ size_t minAlignment = qMax(alignment, Q_ALIGNOF(QArrayData));
+
+ int capacity = 10;
+ Deallocator keeper(objectSize, minAlignment);
+ QArrayData *data = QArrayData::allocate(objectSize, minAlignment, capacity,
+ QArrayData::AllocationOptions(allocateOptions) & ~QArrayData::Grow);
+ keeper.headers.append(data);
+
+ memset(data->data(), 'A', objectSize * capacity);
+ data->size = capacity;
+
+ // now try to reallocate
+ int newCapacity = 40;
+ data = QArrayData::reallocateUnaligned(data, objectSize, newCapacity,
+ QArrayData::AllocationOptions(allocateOptions));
+ QVERIFY(data);
+ keeper.headers.clear();
+ keeper.headers.append(data);
+
+ QCOMPARE(data->size, capacity);
+ if (allocateOptions & QArrayData::Grow)
+ QVERIFY(data->alloc > uint(newCapacity));
+ else
+ QCOMPARE(data->alloc, uint(newCapacity));
+ QCOMPARE(data->capacityReserved, uint(isCapacityReserved));
+#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
+ QFETCH(bool, isSharable);
+ QCOMPARE(data->ref.isSharable(), isSharable);
+#endif
+
+ for (int i = 0; i < capacity; ++i)
+ QCOMPARE(static_cast<char *>(data->data())[i], 'A');
+}
+
class Unaligned
{
char dummy[8];