summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/tools/qarraydata
diff options
context:
space:
mode:
authorJoão Abecasis <joao.abecasis@nokia.com>2011-11-24 17:15:11 +0100
committerQt by Nokia <qt-info@nokia.com>2012-01-06 17:25:09 +0100
commit3d61c5ca8f00b489435d5bea776b4a4c97c39793 (patch)
tree45480cd94b6dbb0899398c0abb692bc1ebba3aca /tests/auto/corelib/tools/qarraydata
parent51048e1f31df5be45e71a75fc535111dd36c4c9e (diff)
Add setSharable support in QArrayData stack
Making use of the same feature added in RefCount. To keep with the intention of avoiding the allocation of "empty" array headers, this introduces an unsharable_empty, which allows users to maintain the "unsharable bit" on empty containers, without imposing any actual allocations. (Before anyone asks, there is no point to a zero-sized capacity-reserved container so no other combinations are needed for now.) Change-Id: Icaa40ac3100ad954fdc20dee0c991861136a5b19 Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
Diffstat (limited to 'tests/auto/corelib/tools/qarraydata')
-rw-r--r--tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp152
1 files changed, 146 insertions, 6 deletions
diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
index e9a3218331..e8edab20e4 100644
--- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
+++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
@@ -79,6 +79,8 @@ private slots:
void typedData();
void gccBug43247();
void arrayOps();
+ void setSharable_data();
+ void setSharable();
};
template <class T> const T &const_(const T &t) { return t; }
@@ -477,6 +479,7 @@ void tst_QArrayData::allocate_data()
QTest::addColumn<size_t>("objectSize");
QTest::addColumn<size_t>("alignment");
QTest::addColumn<bool>("isCapacityReserved");
+ QTest::addColumn<bool>("isSharable");
QTest::addColumn<const QArrayData *>("commonEmpty");
struct {
@@ -492,10 +495,13 @@ void tst_QArrayData::allocate_data()
struct {
char const *description;
bool isCapacityReserved;
+ bool isSharable;
const QArrayData *commonEmpty;
} options[] = {
- { "Default", false, &QArrayData::shared_empty },
- { "Reserved", true, &QArrayData::shared_empty },
+ { "Default", false, true, &QArrayData::shared_empty },
+ { "Reserved", true, true, &QArrayData::shared_empty },
+ { "Reserved | Unsharable", true, false, &QArrayData::unsharable_empty },
+ { "Unsharable", false, false, &QArrayData::unsharable_empty },
};
for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i)
@@ -505,7 +511,8 @@ void tst_QArrayData::allocate_data()
+ QLatin1String(": ")
+ QLatin1String(options[j].description)))
<< types[i].objectSize << types[i].alignment
- << options[j].isCapacityReserved << options[j].commonEmpty;
+ << options[j].isCapacityReserved << options[j].isSharable
+ << options[j].commonEmpty;
}
void tst_QArrayData::allocate()
@@ -513,6 +520,7 @@ void tst_QArrayData::allocate()
QFETCH(size_t, objectSize);
QFETCH(size_t, alignment);
QFETCH(bool, isCapacityReserved);
+ QFETCH(bool, isSharable);
QFETCH(const QArrayData *, commonEmpty);
// Minimum alignment that can be requested is that of QArrayData.
@@ -521,19 +529,20 @@ void tst_QArrayData::allocate()
// Shared Empty
QCOMPARE(QArrayData::allocate(objectSize, minAlignment, 0,
- isCapacityReserved), commonEmpty);
+ isCapacityReserved, isSharable), commonEmpty);
Deallocator keeper(objectSize, minAlignment);
keeper.headers.reserve(1024);
for (int capacity = 1; capacity <= 1024; capacity <<= 1) {
QArrayData *data = QArrayData::allocate(objectSize, minAlignment,
- capacity, isCapacityReserved);
+ capacity, isCapacityReserved, isSharable);
keeper.headers.append(data);
QCOMPARE(data->size, 0);
QVERIFY(data->alloc >= uint(capacity));
QCOMPARE(data->capacityReserved, uint(isCapacityReserved));
+ QCOMPARE(data->ref.isSharable(), isSharable);
// Check that the allocated array can be used. Best tested with a
// memory checker, such as valgrind, running.
@@ -569,7 +578,7 @@ void tst_QArrayData::alignment()
for (int i = 0; i < 100; ++i) {
QArrayData *data = QArrayData::allocate(sizeof(Unaligned),
- minAlignment, 8, false);
+ minAlignment, 8, false, true);
keeper.headers.append(data);
QVERIFY(data);
@@ -903,5 +912,136 @@ void tst_QArrayData::arrayOps()
}
}
+Q_DECLARE_METATYPE(QArrayDataPointer<int>)
+
+static inline bool arrayIsFilledWith(const QArrayDataPointer<int> &array,
+ int fillValue, size_t size)
+{
+ const int *iter = array->begin();
+ const int *const end = array->end();
+
+ for (size_t i = 0; i < size; ++i, ++iter)
+ if (*iter != fillValue)
+ return false;
+
+ if (iter != end)
+ return false;
+
+ return true;
+}
+
+void tst_QArrayData::setSharable_data()
+{
+ QTest::addColumn<QArrayDataPointer<int> >("array");
+ QTest::addColumn<size_t>("size");
+ QTest::addColumn<size_t>("capacity");
+ QTest::addColumn<bool>("isCapacityReserved");
+ QTest::addColumn<int>("fillValue");
+
+ QArrayDataPointer<int> null;
+ QArrayDataPointer<int> empty; empty.clear();
+
+ static QStaticArrayData<int, 10> staticArrayData = {
+ Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10),
+ { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }
+ };
+
+ QArrayDataPointer<int> emptyReserved(QTypedArrayData<int>::allocate(5, true, true));
+ QArrayDataPointer<int> nonEmpty(QTypedArrayData<int>::allocate(10, false, true));
+ QArrayDataPointer<int> nonEmptyReserved(QTypedArrayData<int>::allocate(15, true, true));
+ QArrayDataPointer<int> staticArray(static_cast<QTypedArrayData<int> *>(&staticArrayData.header));
+
+ nonEmpty->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-reserved") << nonEmptyReserved << size_t(7) << size_t(15) << true << 2;
+ QTest::newRow("static-array") << staticArray << size_t(10) << size_t(0) << false << 3;
+}
+
+void tst_QArrayData::setSharable()
+{
+ QFETCH(QArrayDataPointer<int>, array);
+ QFETCH(size_t, size);
+ QFETCH(size_t, capacity);
+ QFETCH(bool, isCapacityReserved);
+ QFETCH(int, fillValue);
+
+ QVERIFY(array->ref.isShared()); // QTest has a copy
+ QVERIFY(array->ref.isSharable());
+
+ QCOMPARE(size_t(array->size), size);
+ QCOMPARE(size_t(array->alloc), capacity);
+ QCOMPARE(bool(array->capacityReserved), isCapacityReserved);
+ QVERIFY(arrayIsFilledWith(array, fillValue, size));
+
+ // shared-null becomes shared-empty, may otherwise detach
+ array.setSharable(true);
+
+ QVERIFY(array->ref.isSharable());
+ QVERIFY(arrayIsFilledWith(array, fillValue, size));
+
+ {
+ QArrayDataPointer<int> copy(array);
+ QVERIFY(array->ref.isShared());
+ QVERIFY(array->ref.isSharable());
+ QCOMPARE(copy.data(), array.data());
+ }
+
+ // Unshare, must detach
+ array.setSharable(false);
+
+ // Immutability (alloc == 0) is lost on detach
+ if (capacity == 0 && size != 0)
+ capacity = size;
+
+ QVERIFY(!array->ref.isShared());
+ QVERIFY(!array->ref.isSharable());
+
+ QCOMPARE(size_t(array->size), size);
+ QCOMPARE(size_t(array->alloc), capacity);
+ QCOMPARE(bool(array->capacityReserved), isCapacityReserved);
+ QVERIFY(arrayIsFilledWith(array, fillValue, size));
+
+ {
+ QArrayDataPointer<int> copy(array);
+ QVERIFY(!array->ref.isShared());
+ QVERIFY(!array->ref.isSharable());
+
+ // Null/empty is always shared
+ QCOMPARE(copy->ref.isShared(), !(size || isCapacityReserved));
+ QVERIFY(copy->ref.isSharable());
+
+ QCOMPARE(size_t(copy->size), size);
+ QCOMPARE(size_t(copy->alloc), capacity);
+ QCOMPARE(bool(copy->capacityReserved), isCapacityReserved);
+ QVERIFY(arrayIsFilledWith(copy, fillValue, size));
+ }
+
+ // Make sharable, again
+ array.setSharable(true);
+
+ QCOMPARE(array->ref.isShared(), !(size || isCapacityReserved));
+ QVERIFY(array->ref.isSharable());
+
+ QCOMPARE(size_t(array->size), size);
+ QCOMPARE(size_t(array->alloc), capacity);
+ QCOMPARE(bool(array->capacityReserved), isCapacityReserved);
+ QVERIFY(arrayIsFilledWith(array, fillValue, size));
+
+ {
+ QArrayDataPointer<int> copy(array);
+ QVERIFY(array->ref.isShared());
+ QCOMPARE(copy.data(), array.data());
+ }
+
+ QCOMPARE(array->ref.isShared(), !(size || isCapacityReserved));
+ QVERIFY(array->ref.isSharable());
+}
+
QTEST_APPLESS_MAIN(tst_QArrayData)
#include "tst_qarraydata.moc"