From 4da0b5fc02fe3a647d32892905c42928841d6487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 3 Nov 2011 12:52:26 +0100 Subject: QArrayDataOps: generic array operations This class, the selector and underlying implementations provide specialized operations on QArrayData, while allowing for optimized implementations that benefit from type-specific information. Currently, offering a generic implementation and specializations for PODs (trivial ctor, dtor and move operations) and movable types (can be trivially moved in memory). Change-Id: I2c5829b66c2aea79f12f21debe5c01f7104c7ea3 Reviewed-by: Bradley T. Hughes --- tests/auto/corelib/tools/qarraydata/simplevector.h | 20 ++-- .../corelib/tools/qarraydata/tst_qarraydata.cpp | 127 +++++++++++++++++++++ 2 files changed, 140 insertions(+), 7 deletions(-) (limited to 'tests/auto/corelib') diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 099045dfbb..36c9b7bc50 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -44,6 +44,8 @@ #define QARRAY_TEST_SIMPLE_VECTOR_H #include +#include + #include template @@ -51,6 +53,7 @@ struct SimpleVector { private: typedef QTypedArrayData Data; + typedef QArrayDataOps DataOps; public: typedef T value_type; @@ -71,10 +74,15 @@ public: 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; - } + if (n) + static_cast(d)->copyAppend(n, t); + } + + SimpleVector(const T *begin, const T *end) + : d(Data::allocate(end - begin)) + { + if (end - begin) + static_cast(d)->copyAppend(begin, end); } explicit SimpleVector(Data *ptr) @@ -85,9 +93,7 @@ public: ~SimpleVector() { if (!d->ref.deref()) { - const T *const data = d->data(); - while (d->size--) - data[d->size].~T(); + static_cast(d)->destroyAll(); Data::deallocate(d); } } diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index f7a2fa7979..2972f0a678 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -41,6 +41,7 @@ #include +#include #include #include "simplevector.h" @@ -60,6 +61,7 @@ private slots: void alignment(); void typedData(); void gccBug43247(); + void arrayOps(); }; void tst_QArrayData::referenceCounting() @@ -165,6 +167,8 @@ void tst_QArrayData::simpleVector() { 0, 1, 2, 3, 4, 5, 6 } }; + int array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + SimpleVector v1; SimpleVector v2(v1); SimpleVector v3(static_cast *>(&data0)); @@ -172,6 +176,7 @@ void tst_QArrayData::simpleVector() SimpleVector v5(static_cast *>(&data0)); SimpleVector v6(static_cast *>(&data1.header)); SimpleVector v7(10, 5); + SimpleVector v8(array, array + sizeof(array)/sizeof(*array)); v3 = v1; v1.swap(v3); @@ -184,6 +189,7 @@ void tst_QArrayData::simpleVector() QVERIFY(!v5.isNull()); QVERIFY(!v6.isNull()); QVERIFY(!v7.isNull()); + QVERIFY(!v8.isNull()); QVERIFY(v1.isEmpty()); QVERIFY(v2.isEmpty()); @@ -192,6 +198,7 @@ void tst_QArrayData::simpleVector() QVERIFY(v5.isEmpty()); QVERIFY(!v6.isEmpty()); QVERIFY(!v7.isEmpty()); + QVERIFY(!v8.isEmpty()); QCOMPARE(v1.size(), size_t(0)); QCOMPARE(v2.size(), size_t(0)); @@ -200,6 +207,7 @@ void tst_QArrayData::simpleVector() QCOMPARE(v5.size(), size_t(0)); QCOMPARE(v6.size(), size_t(7)); QCOMPARE(v7.size(), size_t(10)); + QCOMPARE(v8.size(), size_t(10)); QCOMPARE(v1.capacity(), size_t(0)); QCOMPARE(v2.capacity(), size_t(0)); @@ -208,6 +216,7 @@ void tst_QArrayData::simpleVector() QCOMPARE(v5.capacity(), size_t(0)); // v6.capacity() is unspecified, for now QVERIFY(v7.capacity() >= size_t(10)); + QVERIFY(v8.capacity() >= size_t(10)); QVERIFY(v1.isSharedWith(v2)); QVERIFY(v1.isSharedWith(v3)); @@ -219,6 +228,7 @@ void tst_QArrayData::simpleVector() QVERIFY(v4.constBegin() == v4.constEnd()); QVERIFY(v6.constBegin() + v6.size() == v6.constEnd()); QVERIFY(v7.constBegin() + v7.size() == v7.constEnd()); + QVERIFY(v8.constBegin() + v8.size() == v8.constEnd()); QVERIFY(v1 == v2); QVERIFY(v1 == v3); @@ -259,6 +269,16 @@ void tst_QArrayData::simpleVector() QCOMPARE(count, 10); } + { + int count = 0; + Q_FOREACH (int value, v8) { + QCOMPARE(value, count); + ++count; + } + + QCOMPARE(count, 10); + } + v5 = v6; QVERIFY(v5.isSharedWith(v6)); QVERIFY(!v1.isSharedWith(v5)); @@ -550,5 +570,112 @@ void tst_QArrayData::gccBug43247() } } +struct CountedObject +{ + CountedObject() + : id(liveCount++) + { + } + + CountedObject(const CountedObject &other) + : id(other.id) + { + ++liveCount; + } + + ~CountedObject() + { + --liveCount; + } + + CountedObject &operator=(const CountedObject &other) + { + id = other.id; + return *this; + } + + struct LeakChecker + { + LeakChecker() + : previousLiveCount(liveCount) + { + } + + ~LeakChecker() + { + QCOMPARE(liveCount, previousLiveCount); + } + + private: + const size_t previousLiveCount; + }; + + size_t id; // not unique + static size_t liveCount; +}; + +size_t CountedObject::liveCount = 0; + +void tst_QArrayData::arrayOps() +{ + CountedObject::LeakChecker leakChecker; Q_UNUSED(leakChecker) + + const int intArray[5] = { 80, 101, 100, 114, 111 }; + const QString stringArray[5] = { + QLatin1String("just"), + QLatin1String("for"), + QLatin1String("testing"), + QLatin1String("a"), + QLatin1String("vector") + }; + const CountedObject objArray[5]; + + QVERIFY(!QTypeInfo::isComplex && !QTypeInfo::isStatic); + QVERIFY(QTypeInfo::isComplex && !QTypeInfo::isStatic); + QVERIFY(QTypeInfo::isComplex && QTypeInfo::isStatic); + + QCOMPARE(CountedObject::liveCount, size_t(5)); + for (size_t i = 0; i < 5; ++i) + QCOMPARE(objArray[i].id, i); + + //////////////////////////////////////////////////////////////////////////// + // copyAppend (I) + SimpleVector vi(intArray, intArray + 5); + SimpleVector vs(stringArray, stringArray + 5); + SimpleVector vo(objArray, objArray + 5); + + QCOMPARE(CountedObject::liveCount, size_t(10)); + for (int i = 0; i < 5; ++i) { + QCOMPARE(vi[i], intArray[i]); + QVERIFY(vs[i].isSharedWith(stringArray[i])); + QCOMPARE(vo[i].id, objArray[i].id); + } + + //////////////////////////////////////////////////////////////////////////// + // destroyAll + vi.clear(); + vs.clear(); + vo.clear(); + + QCOMPARE(CountedObject::liveCount, size_t(5)); + + //////////////////////////////////////////////////////////////////////////// + // copyAppend (II) + int referenceInt = 7; + QString referenceString = QLatin1String("reference"); + CountedObject referenceObject; + + vi = SimpleVector(5, referenceInt); + vs = SimpleVector(5, referenceString); + vo = SimpleVector(5, referenceObject); + + QCOMPARE(CountedObject::liveCount, size_t(11)); + for (int i = 0; i < 5; ++i) { + QCOMPARE(vi[i], referenceInt); + QVERIFY(vs[i].isSharedWith(referenceString)); + QCOMPARE(vo[i].id, referenceObject.id); + } +} + QTEST_APPLESS_MAIN(tst_QArrayData) #include "tst_qarraydata.moc" -- cgit v1.2.3