diff options
author | João Abecasis <joao.abecasis@nokia.com> | 2011-11-29 17:53:57 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-12-11 12:07:13 +0100 |
commit | 390eec325b25a142ce2204f1d1950621d4a519e3 (patch) | |
tree | 13d0a0f200fd19863b8746da1464442a04c4946b /tests/auto/corelib | |
parent | 0806bc2d1b518b53681b3d8023def95ba8122630 (diff) |
template<class T> struct QTypedArrayData
QTypedArrayData is a typed overlay for QArrayData, providing convenience
and type-safety. It adds no data members to QArrayData, thus avoiding
compiler-generated warnings for aliasing issues when casting back and
forth.
Change-Id: I969342a30989c4c14b3d03d0602e3d60a4cc0e9d
Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
Diffstat (limited to 'tests/auto/corelib')
-rw-r--r-- | tests/auto/corelib/tools/qarraydata/simplevector.h | 34 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 133 |
2 files changed, 152 insertions, 15 deletions
diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index ad08ad5fdb..099045dfbb 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -50,15 +50,15 @@ template <class T> struct SimpleVector { private: - typedef QArrayData Data; + typedef QTypedArrayData<T> Data; public: typedef T value_type; - typedef T *iterator; - typedef const T *const_iterator; + typedef typename Data::iterator iterator; + typedef typename Data::const_iterator const_iterator; SimpleVector() - : d(const_cast<QArrayData *>(&Data::shared_null)) + : d(Data::sharedNull()) { } @@ -68,6 +68,15 @@ public: d->ref.ref(); } + SimpleVector(size_t n, const T &t) + : d(Data::allocate(n)) + { + for (size_t i = 0; i < n; ++i) { + new (d->end()) T(t); + ++d->size; + } + } + explicit SimpleVector(Data *ptr) : d(ptr) { @@ -75,9 +84,12 @@ public: ~SimpleVector() { - if (!d->ref.deref()) - // Not implemented - Q_ASSERT(false); + if (!d->ref.deref()) { + const T *const data = d->data(); + while (d->size--) + data[d->size].~T(); + Data::deallocate(d); + } } SimpleVector &operator=(const SimpleVector &vec) @@ -88,7 +100,7 @@ public: } bool empty() const { return d->size == 0; } - bool isNull() const { return d == &Data::shared_null; } + bool isNull() const { return d == Data::sharedNull(); } bool isEmpty() const { return this->empty(); } bool isSharedWith(const SimpleVector &other) const { return d == other.d; } @@ -96,8 +108,8 @@ public: size_t size() const { return d->size; } size_t capacity() const { return d->alloc; } - const_iterator begin() const { return static_cast<T *>(d->data()); } - const_iterator end() const { return static_cast<T *>(d->data()) + d->size; } + const_iterator begin() const { return d->begin(); } + const_iterator end() const { return d->end(); } const_iterator constBegin() const { return begin(); } const_iterator constEnd() const { return end(); } @@ -125,7 +137,7 @@ public: void clear() { SimpleVector tmp(d); - d = const_cast<QArrayData *>(&Data::shared_empty); + d = Data::sharedEmpty(); } private: diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 7dfbd654a7..8bbef9bac9 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -58,6 +58,7 @@ private slots: void allocate(); void alignment_data(); void alignment(); + void typedData(); }; void tst_QArrayData::referenceCounting() @@ -165,10 +166,11 @@ void tst_QArrayData::simpleVector() SimpleVector<int> v1; SimpleVector<int> v2(v1); - SimpleVector<int> v3(&data0); - SimpleVector<int> v4(&data1.header); - SimpleVector<int> v5(&data0); - SimpleVector<int> v6(&data1.header); + SimpleVector<int> v3(static_cast<QTypedArrayData<int> *>(&data0)); + SimpleVector<int> v4(static_cast<QTypedArrayData<int> *>(&data1.header)); + SimpleVector<int> v5(static_cast<QTypedArrayData<int> *>(&data0)); + SimpleVector<int> v6(static_cast<QTypedArrayData<int> *>(&data1.header)); + SimpleVector<int> v7(10, 5); v3 = v1; v1.swap(v3); @@ -180,6 +182,7 @@ void tst_QArrayData::simpleVector() QVERIFY(!v4.isNull()); QVERIFY(!v5.isNull()); QVERIFY(!v6.isNull()); + QVERIFY(!v7.isNull()); QVERIFY(v1.isEmpty()); QVERIFY(v2.isEmpty()); @@ -187,6 +190,7 @@ void tst_QArrayData::simpleVector() QVERIFY(v4.isEmpty()); QVERIFY(v5.isEmpty()); QVERIFY(!v6.isEmpty()); + QVERIFY(!v7.isEmpty()); QCOMPARE(v1.size(), size_t(0)); QCOMPARE(v2.size(), size_t(0)); @@ -194,6 +198,7 @@ void tst_QArrayData::simpleVector() QCOMPARE(v4.size(), size_t(0)); QCOMPARE(v5.size(), size_t(0)); QCOMPARE(v6.size(), size_t(7)); + QCOMPARE(v7.size(), size_t(10)); QCOMPARE(v1.capacity(), size_t(0)); QCOMPARE(v2.capacity(), size_t(0)); @@ -201,6 +206,7 @@ void tst_QArrayData::simpleVector() QCOMPARE(v4.capacity(), size_t(0)); QCOMPARE(v5.capacity(), size_t(0)); // v6.capacity() is unspecified, for now + QVERIFY(v7.capacity() >= size_t(10)); QVERIFY(v1.isSharedWith(v2)); QVERIFY(v1.isSharedWith(v3)); @@ -211,6 +217,7 @@ void tst_QArrayData::simpleVector() QVERIFY(v1.constBegin() == v1.constEnd()); QVERIFY(v4.constBegin() == v4.constEnd()); QVERIFY(v6.constBegin() + v6.size() == v6.constEnd()); + QVERIFY(v7.constBegin() + v7.size() == v7.constEnd()); QVERIFY(v1 == v2); QVERIFY(v1 == v3); @@ -241,6 +248,16 @@ void tst_QArrayData::simpleVector() QCOMPARE(&v6[i], &v6.at(i)); } + { + int count = 0; + Q_FOREACH (int value, v7) { + QCOMPARE(value, 5); + ++count; + } + + QCOMPARE(count, 10); + } + v5 = v6; QVERIFY(v5.isSharedWith(v6)); QVERIFY(!v1.isSharedWith(v5)); @@ -397,5 +414,113 @@ void tst_QArrayData::alignment() } } +void tst_QArrayData::typedData() +{ + QStaticArrayData<int, 10> data = { + Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10), + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } + }; + QCOMPARE(data.header.size, 10); + + { + QTypedArrayData<int> *array = + static_cast<QTypedArrayData<int> *>(&data.header); + QCOMPARE(array->data(), data.data); + + int j = 0; + for (QTypedArrayData<int>::iterator iter = array->begin(); + iter != array->end(); ++iter, ++j) + QCOMPARE(iter, data.data + j); + QCOMPARE(j, 10); + } + + { + const QTypedArrayData<int> *array = + static_cast<const QTypedArrayData<int> *>(&data.header); + + QCOMPARE(array->data(), data.data); + + int j = 0; + for (QTypedArrayData<int>::const_iterator iter = array->begin(); + iter != array->end(); ++iter, ++j) + QCOMPARE(iter, data.data + j); + QCOMPARE(j, 10); + } + + { + QTypedArrayData<int> *null = QTypedArrayData<int>::sharedNull(); + QTypedArrayData<int> *empty = QTypedArrayData<int>::sharedEmpty(); + + QVERIFY(null != empty); + + QCOMPARE(null->size, 0); + QCOMPARE(empty->size, 0); + + QCOMPARE(null->begin(), null->end()); + QCOMPARE(empty->begin(), empty->end()); + } + + + { + Deallocator keeper(sizeof(char), + Q_ALIGNOF(QTypedArrayData<char>::AlignmentDummy)); + QArrayData *array = QTypedArrayData<char>::allocate(10, false); + keeper.headers.append(array); + + QVERIFY(array); + QCOMPARE(array->size, 0); + QCOMPARE(array->alloc, 10u); + + // Check that the allocated array can be used. Best tested with a + // memory checker, such as valgrind, running. + ::memset(array->data(), 0, 10 * sizeof(char)); + + keeper.headers.clear(); + QTypedArrayData<short>::deallocate(array); + + QVERIFY(true); + } + + { + Deallocator keeper(sizeof(short), + Q_ALIGNOF(QTypedArrayData<short>::AlignmentDummy)); + QArrayData *array = QTypedArrayData<short>::allocate(10, false); + keeper.headers.append(array); + + QVERIFY(array); + QCOMPARE(array->size, 0); + QCOMPARE(array->alloc, 10u); + + // Check that the allocated array can be used. Best tested with a + // memory checker, such as valgrind, running. + ::memset(array->data(), 0, 10 * sizeof(short)); + + keeper.headers.clear(); + QTypedArrayData<short>::deallocate(array); + + QVERIFY(true); + } + + { + Deallocator keeper(sizeof(double), + Q_ALIGNOF(QTypedArrayData<double>::AlignmentDummy)); + QArrayData *array = QTypedArrayData<double>::allocate(10, false); + keeper.headers.append(array); + + QVERIFY(array); + QCOMPARE(array->size, 0); + QCOMPARE(array->alloc, 10u); + + // Check that the allocated array can be used. Best tested with a + // memory checker, such as valgrind, running. + ::memset(array->data(), 0, 10 * sizeof(double)); + + keeper.headers.clear(); + QTypedArrayData<double>::deallocate(array); + + QVERIFY(true); + } +} + QTEST_APPLESS_MAIN(tst_QArrayData) #include "tst_qarraydata.moc" |