diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2012-06-05 17:21:19 +0200 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2016-09-07 14:35:51 +0000 |
commit | 42f974f56b18e365c3343545a9491452683fed30 (patch) | |
tree | 8325af7fad8f19acad3ee34ea12e0591ded32162 /tests | |
parent | 8e5cd8017e9a88de426b3c23c328a68a70089b1c (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.cpp | 50 |
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]; |