From d17cf14185eb84863549e0119c8b7bd20db78580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Thu, 26 Apr 2012 12:06:17 +0200 Subject: Implement QVector with QArrayData interface. Change-Id: I109f46892aed2f6024459812d24922b12358814d Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qvector/tst_qvector.cpp | 1486 ++++++++++++++++++-- .../benchmarks/corelib/tools/qvector/outofline.cpp | 33 + .../benchmarks/corelib/tools/qvector/qrawvector.h | 26 + tests/benchmarks/corelib/tools/qvector/qvector.pro | 2 +- 4 files changed, 1422 insertions(+), 125 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index 67ca547736..56570b8e53 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -42,24 +42,181 @@ #include #include +struct Movable { + Movable(char input = 'j') + : i(input) + , state(Constructed) + { + ++counter; + } + Movable(const Movable &other) + : i(other.i) + , state(Constructed) + { + check(other.state, Constructed); + ++counter; + } + + ~Movable() + { + check(state, Constructed); + i = 0; + --counter; + state = Destructed; + } + + bool operator ==(const Movable &other) const + { + check(state, Constructed); + check(other.state, Constructed); + return i == other.i; + } + + Movable &operator=(const Movable &other) + { + check(state, Constructed); + check(other.state, Constructed); + i = other.i; + return *this; + } + char i; + static int counter; +private: + enum State { Constructed = 106, Destructed = 110 }; + State state; + + static void check(const State state1, const State state2) + { + QCOMPARE(state1, state2); + } +}; + +int Movable::counter = 0; +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE); +QT_END_NAMESPACE +Q_DECLARE_METATYPE(Movable); + +struct Custom { + Custom(char input = 'j') + : i(input) + , that(this) + , state(Constructed) + { + ++counter; + } + Custom(const Custom &other) + : that(this) + , state(Constructed) + { + check(&other); + ++counter; + this->i = other.i; + } + ~Custom() + { + check(this); + i = 0; + --counter; + state = Destructed; + } + + bool operator ==(const Custom &other) const + { + check(&other); + check(this); + return i == other.i; + } + + Custom &operator=(const Custom &other) + { + check(&other); + check(this); + i = other.i; + return *this; + } + static int counter; + + char i; // used to identify orgin of an instance +private: + Custom *that; // used to check if an instance was moved + + enum State { Constructed = 106, Destructed = 110 }; + State state; + + static void check(const Custom *c) + { + // check if c object has been moved + QCOMPARE(c, c->that); + QCOMPARE(c->state, Constructed); + } +}; +int Custom::counter = 0; + +Q_DECLARE_METATYPE(Custom); + +// tests depends on the fact that: +Q_STATIC_ASSERT(!QTypeInfo::isStatic); +Q_STATIC_ASSERT(!QTypeInfo::isComplex); +Q_STATIC_ASSERT(!QTypeInfo::isStatic); +Q_STATIC_ASSERT(QTypeInfo::isComplex); +Q_STATIC_ASSERT(QTypeInfo::isStatic); +Q_STATIC_ASSERT(QTypeInfo::isComplex); + + class tst_QVector : public QObject { Q_OBJECT private slots: - void constructors() const; - void append() const; + void constructors_empty() const; + void constructors_emptyReserveZero() const; + void constructors_emptyReserve() const; + void constructors_reserveAndInitialize() const; + void copyConstructorInt() const; + void copyConstructorMovable() const; + void copyConstructorCustom() const; + void addInt() const; + void addMovable() const; + void addCustom() const; + void appendInt() const; + void appendMovable() const; + void appendCustom() const; void at() const; - void capacity() const; - void clear() const; + void capacityInt() const; + void capacityMovable() const; + void capacityCustom() const; + void clearInt() const; + void clearMovable() const; + void clearCustom() const; void constData() const; void contains() const; - void count() const; + void countInt() const; + void countMovable() const; + void countCustom() const; void data() const; - void empty() const; + void emptyInt() const; + void emptyMovable() const; + void emptyCustom() const; void endsWith() const; - void fill() const; + void eraseEmptyInt() const; + void eraseEmptyMovable() const; + void eraseEmptyCustom() const; + void eraseEmptyReservedInt() const; + void eraseEmptyReservedMovable() const; + void eraseEmptyReservedCustom() const; + void eraseInt() const; + void eraseMovable() const; + void eraseCustom() const; + void eraseReservedInt() const; + void eraseReservedMovable() const; + void eraseReservedCustom() const; + void fillInt() const; + void fillMovable() const; + void fillCustom() const; void first() const; - void fromList() const; + void fromListInt() const; + void fromListMovable() const; + void fromListCustom() const; void fromStdVector() const; void indexOf() const; void insert() const; @@ -67,11 +224,26 @@ private slots: void last() const; void lastIndexOf() const; void mid() const; - void prepend() const; - void remove() const; - void size() const; + void prependInt() const; + void prependMovable() const; + void prependCustom() const; + void removeInt() const; + void removeMovable() const; + void removeCustom() const; + void resizePOD_data() const; + void resizePOD() const; + void resizeComplexMovable_data() const; + void resizeComplexMovable() const; + void resizeComplex_data() const; + void resizeComplex() const; + void resizeCtorAndDtor() const; + void sizeInt() const; + void sizeMovable() const; + void sizeCustom() const; void startsWith() const; - void swap() const; + void swapInt() const; + void swapMovable() const; + void swapCustom() const; void toList() const; void toStdVector() const; void value() const; @@ -82,44 +254,272 @@ private slots: void reserve(); void reallocAfterCopy_data(); void reallocAfterCopy(); - void initializeList(); + void initializeListInt(); + void initializeListMovable(); + void initializeListCustom(); void const_shared_null(); - void setSharable_data(); - void setSharable(); + void setSharableInt_data(); + void setSharableInt(); + void setSharableMovable_data(); + void setSharableMovable(); + void setSharableCustom_data(); + void setSharableCustom(); + + void detachInt() const; + void detachMovable() const; + void detachCustom() const; +private: + template void copyConstructor() const; + template void add() const; + template void append() const; + template void capacity() const; + template void clear() const; + template void count() const; + template void empty() const; + template void eraseEmpty() const; + template void eraseEmptyReserved() const; + template void erase() const; + template void eraseReserved() const; + template void fill() const; + template void fromList() const; + template void prepend() const; + template void remove() const; + template void size() const; + template void swap() const; + template void initializeList(); + template void setSharable_data() const; + template void setSharable() const; + template void detach() const; }; -void tst_QVector::constructors() const +template struct SimpleValue { - // pre-reserve capacity + static T at(int index) { - QVector myvec(5); - - QVERIFY(myvec.capacity() == 5); + return Values[index % MaxIndex]; } + static const uint MaxIndex = 6; + static const T Values[MaxIndex]; +}; +template<> +const int SimpleValue::Values[] = { 110, 105, 101, 114, 111, 98 }; +template<> +const Movable SimpleValue::Values[] = { 110, 105, 101, 114, 111, 98 }; +template<> +const Custom SimpleValue::Values[] = { 110, 105, 101, 114, 111, 98 }; + +void tst_QVector::constructors_empty() const +{ + QVector emptyInt; + QVector emptyMovable; + QVector emptyCustom; +} + +void tst_QVector::constructors_emptyReserveZero() const +{ + QVector emptyInt(0); + QVector emptyMovable(0); + QVector emptyCustom(0); +} + +void tst_QVector::constructors_emptyReserve() const +{ + // pre-reserve capacity + QVector myInt(5); + QVERIFY(myInt.capacity() == 5); + QVector myMovable(5); + QVERIFY(myMovable.capacity() == 5); + QVector myCustom(4); + QVERIFY(myCustom.capacity() == 4); +} + +void tst_QVector::constructors_reserveAndInitialize() const +{ // default-initialise items + + QVector myInt(5, 42); + QVERIFY(myInt.capacity() == 5); + foreach (int meaningoflife, myInt) { + QCOMPARE(meaningoflife, 42); + } + + QVector myString(5, QString::fromLatin1("c++")); + QVERIFY(myString.capacity() == 5); + // make sure all items are initialised ok + foreach (QString meaningoflife, myString) { + QCOMPARE(meaningoflife, QString::fromLatin1("c++")); + } + + QVector myCustom(5, Custom('n')); + QVERIFY(myCustom.capacity() == 5); + // make sure all items are initialised ok + foreach (Custom meaningoflife, myCustom) { + QCOMPARE(meaningoflife.i, 'n'); + } +} + +template +void tst_QVector::copyConstructor() const +{ + T value1(SimpleValue::at(0)); + T value2(SimpleValue::at(1)); + T value3(SimpleValue::at(2)); + T value4(SimpleValue::at(3)); { - QVector myvec(5, 42); + QVector v1; + QVector v2(v1); + QCOMPARE(v1, v2); + } + { + QVector v1; + v1.setSharable(false); + QVector v2(v1); + QVERIFY(!v1.isSharedWith(v2)); + QCOMPARE(v1, v2); + } + { + QVector v1; + v1 << value1 << value2 << value3 << value4; + QVector v2(v1); + QCOMPARE(v1, v2); + } + { + QVector v1; + v1 << value1 << value2 << value3 << value4; + v1.setSharable(false); + QVector v2(v1); + QVERIFY(!v1.isSharedWith(v2)); + QCOMPARE(v1, v2); + } +} - QVERIFY(myvec.capacity() == 5); +void tst_QVector::copyConstructorInt() const +{ + copyConstructor(); +} - // make sure all items are initialised ok - foreach (int meaningoflife, myvec) { - QCOMPARE(meaningoflife, 42); - } +void tst_QVector::copyConstructorMovable() const +{ + const int instancesCount = Movable::counter; + copyConstructor(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::copyConstructorCustom() const +{ + const int instancesCount = Custom::counter; + copyConstructor(); + QCOMPARE(instancesCount, Custom::counter); +} + +template +void tst_QVector::add() const +{ + { + QVector empty1; + QVector empty2; + QVERIFY((empty1 + empty2).isEmpty()); + empty1 += empty2; + QVERIFY(empty1.isEmpty()); + QVERIFY(empty2.isEmpty()); } + { + QVector v(12); + QVector empty; + QCOMPARE((v + empty), v); + v += empty; + QVERIFY(!v.isEmpty()); + QCOMPARE(v.size(), 12); + QVERIFY(empty.isEmpty()); + } + { + QVector v1(12); + QVector v2; + v2 += v1; + QVERIFY(!v1.isEmpty()); + QCOMPARE(v1.size(), 12); + QVERIFY(!v2.isEmpty()); + QCOMPARE(v2.size(), 12); + } +} + +void tst_QVector::addInt() const +{ + add(); +} + +void tst_QVector::addMovable() const +{ + const int instancesCount = Movable::counter; + add(); + QCOMPARE(instancesCount, Movable::counter); } +void tst_QVector::addCustom() const +{ + const int instancesCount = Custom::counter; + add(); + QCOMPARE(instancesCount, Custom::counter); +} + +template void tst_QVector::append() const { - QVector myvec; - myvec.append(42); - myvec.append(43); - myvec.append(44); + { + QVector myvec; + myvec.append(SimpleValue::at(0)); + QVERIFY(myvec.size() == 1); + myvec.append(SimpleValue::at(1)); + QVERIFY(myvec.size() == 2); + myvec.append(SimpleValue::at(2)); + QVERIFY(myvec.size() == 3); - QVERIFY(myvec.size() == 3); - QCOMPARE(myvec, QVector() << 42 << 43 << 44); + QCOMPARE(myvec, QVector() << SimpleValue::at(0) + << SimpleValue::at(1) + << SimpleValue::at(2)); + } + { + QVector v(2); + v.append(SimpleValue::at(0)); + QVERIFY(v.size() == 3); + QCOMPARE(v.at(v.size() - 1), SimpleValue::at(0)); + } + { + QVector v(2); + v.reserve(12); + v.append(SimpleValue::at(0)); + QVERIFY(v.size() == 3); + QCOMPARE(v.at(v.size() - 1), SimpleValue::at(0)); + } + { + QVector v(2); + v.reserve(12); + v.setSharable(false); + v.append(SimpleValue::at(0)); + QVERIFY(v.size() == 3); + QCOMPARE(v.last(), SimpleValue::at(0)); + } +} + +void tst_QVector::appendInt() const +{ + append(); +} + +void tst_QVector::appendMovable() const +{ + const int instancesCount = Movable::counter; + append(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::appendCustom() const +{ + const int instancesCount = Custom::counter; + append(); + QCOMPARE(instancesCount, Custom::counter); } void tst_QVector::at() const @@ -148,20 +548,21 @@ void tst_QVector::at() const QCOMPARE(myvec.at(2), QLatin1String("hello")); } +template void tst_QVector::capacity() const { - QVector myvec; + QVector myvec; // TODO: is this guaranteed? seems a safe assumption, but I suppose preallocation of a // few items isn't an entirely unforseeable possibility. QVERIFY(myvec.capacity() == 0); // test it gets a size - myvec << "aaa" << "bbb" << "ccc"; + myvec << SimpleValue::at(0) << SimpleValue::at(1) << SimpleValue::at(2); QVERIFY(myvec.capacity() >= 3); // make sure it grows ok - myvec << "aaa" << "bbb" << "ccc"; + myvec << SimpleValue::at(0) << SimpleValue::at(1) << SimpleValue::at(2); QVERIFY(myvec.capacity() >= 6); // let's try squeeze a bit @@ -182,10 +583,30 @@ void tst_QVector::capacity() const QVERIFY(myvec.capacity() == 0); } +void tst_QVector::capacityInt() const +{ + capacity(); +} + +void tst_QVector::capacityMovable() const +{ + const int instancesCount = Movable::counter; + capacity(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::capacityCustom() const +{ + const int instancesCount = Custom::counter; + capacity(); + QCOMPARE(instancesCount, Custom::counter); +} + +template void tst_QVector::clear() const { - QVector myvec; - myvec << "aaa" << "bbb" << "ccc"; + QVector myvec; + myvec << SimpleValue::at(0) << SimpleValue::at(1) << SimpleValue::at(2); QVERIFY(myvec.size() == 3); myvec.clear(); @@ -193,6 +614,25 @@ void tst_QVector::clear() const QVERIFY(myvec.capacity() == 0); } +void tst_QVector::clearInt() const +{ + clear(); +} + +void tst_QVector::clearMovable() const +{ + const int instancesCount = Movable::counter; + clear(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::clearCustom() const +{ + const int instancesCount = Custom::counter; + clear(); + QCOMPARE(instancesCount, Custom::counter); +} + void tst_QVector::constData() const { int arr[] = { 42, 43, 44 }; @@ -217,18 +657,19 @@ void tst_QVector::contains() const QVERIFY(myvec.contains(QLatin1String("I don't exist"))); } +template void tst_QVector::count() const { // total size { // zero size - QVector myvec; + QVector myvec; QVERIFY(myvec.count() == 0); // grow - myvec.append(42); + myvec.append(SimpleValue::at(0)); QVERIFY(myvec.count() == 1); - myvec.append(42); + myvec.append(SimpleValue::at(1)); QVERIFY(myvec.count() == 2); // shrink @@ -240,23 +681,42 @@ void tst_QVector::count() const // count of items { - QVector myvec; - myvec << "aaa" << "bbb" << "ccc"; + QVector myvec; + myvec << SimpleValue::at(0) << SimpleValue::at(1) << SimpleValue::at(2); // initial tests - QVERIFY(myvec.count(QLatin1String("aaa")) == 1); - QVERIFY(myvec.count(QLatin1String("pirates")) == 0); + QVERIFY(myvec.count(SimpleValue::at(0)) == 1); + QVERIFY(myvec.count(SimpleValue::at(3)) == 0); // grow - myvec.append(QLatin1String("aaa")); - QVERIFY(myvec.count(QLatin1String("aaa")) == 2); + myvec.append(SimpleValue::at(0)); + QVERIFY(myvec.count(SimpleValue::at(0)) == 2); // shrink myvec.remove(0); - QVERIFY(myvec.count(QLatin1String("aaa")) == 1); + QVERIFY(myvec.count(SimpleValue::at(0)) == 1); } } +void tst_QVector::countInt() const +{ + count(); +} + +void tst_QVector::countMovable() const +{ + const int instancesCount = Movable::counter; + count(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::countCustom() const +{ + const int instancesCount = Custom::counter; + count(); + QCOMPARE(instancesCount, Custom::counter); +} + void tst_QVector::data() const { QVector myvec; @@ -275,15 +735,16 @@ void tst_QVector::data() const QVERIFY(memcmp(myvec.data(), reinterpret_cast(&arr), sizeof(int) * 3) == 0); } +template void tst_QVector::empty() const { - QVector myvec; + QVector myvec; // starts empty QVERIFY(myvec.empty()); // not empty - myvec.append(1); + myvec.append(SimpleValue::at(2)); QVERIFY(!myvec.empty()); // empty again @@ -291,6 +752,25 @@ void tst_QVector::empty() const QVERIFY(myvec.empty()); } +void tst_QVector::emptyInt() const +{ + empty(); +} + +void tst_QVector::emptyMovable() const +{ + const int instancesCount = Movable::counter; + empty(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::emptyCustom() const +{ + const int instancesCount = Custom::counter; + empty(); + QCOMPARE(instancesCount, Custom::counter); +} + void tst_QVector::endsWith() const { QVector myvec; @@ -311,18 +791,244 @@ void tst_QVector::endsWith() const QVERIFY(myvec.endsWith(1)); } +template +void tst_QVector::eraseEmpty() const +{ + { + QVector v; + v.erase(v.begin()); + QCOMPARE(v.size(), 0); + v.erase(v.begin(), v.end()); + QCOMPARE(v.size(), 0); + } + { + QVector v; + v.setSharable(false); + v.erase(v.begin()); + QCOMPARE(v.size(), 0); + v.erase(v.begin(), v.end()); + QCOMPARE(v.size(), 0); + } +} + +void tst_QVector::eraseEmptyInt() const +{ + eraseEmpty(); +} + +void tst_QVector::eraseEmptyMovable() const +{ + const int instancesCount = Movable::counter; + eraseEmpty(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::eraseEmptyCustom() const +{ + const int instancesCount = Custom::counter; + eraseEmpty(); + QCOMPARE(instancesCount, Custom::counter); +} + +template +void tst_QVector::eraseEmptyReserved() const +{ + { + QVector v; + v.reserve(10); + v.erase(v.begin()); + QCOMPARE(v.size(), 0); + v.erase(v.begin(), v.end()); + QCOMPARE(v.size(), 0); + } + { + QVector v; + v.reserve(10); + v.setSharable(false); + v.erase(v.begin()); + QCOMPARE(v.size(), 0); + v.erase(v.begin(), v.end()); + QCOMPARE(v.size(), 0); + } +} + +void tst_QVector::eraseEmptyReservedInt() const +{ + eraseEmptyReserved(); +} + +void tst_QVector::eraseEmptyReservedMovable() const +{ + const int instancesCount = Movable::counter; + eraseEmptyReserved(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::eraseEmptyReservedCustom() const +{ + const int instancesCount = Custom::counter; + eraseEmptyReserved(); + QCOMPARE(instancesCount, Custom::counter); +} + +template +void tst_QVector::erase() const +{ + { + QVector v(12); + v.erase(v.begin()); + QCOMPARE(v.size(), 11); + v.erase(v.begin(), v.end()); + QCOMPARE(v.size(), 0); + } + { + QVector v(12); + v.erase(v.begin() + 1); + QCOMPARE(v.size(), 11); + v.erase(v.begin() + 1, v.end()); + QCOMPARE(v.size(), 1); + } + { + QVector v(12); + v.erase(v.begin(), v.end() - 1); + QCOMPARE(v.size(), 1); + } + { + QVector v(12); + v.erase(v.begin() + 5); + QCOMPARE(v.size(), 11); + v.erase(v.begin() + 1, v.end() - 1); + QCOMPARE(v.size(), 2); + } + { + QVector v(10); + v.setSharable(false); + v.erase(v.begin() + 3); + QCOMPARE(v.size(), 9); + v.erase(v.begin(), v.end() - 1); + QCOMPARE(v.size(), 1); + } +} + +void tst_QVector::eraseInt() const +{ + erase(); +} + +void tst_QVector::eraseMovable() const +{ + const int instancesCount = Movable::counter; + erase(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::eraseCustom() const +{ + const int instancesCount = Custom::counter; + erase(); + QCOMPARE(instancesCount, Custom::counter); +} + +template void tst_QVector::eraseReserved() const +{ + { + QVector v(12); + v.reserve(16); + v.erase(v.begin()); + QCOMPARE(v.size(), 11); + v.erase(v.begin(), v.end()); + QCOMPARE(v.size(), 0); + } + { + QVector v(12); + v.reserve(16); + v.erase(v.begin() + 1); + QCOMPARE(v.size(), 11); + v.erase(v.begin() + 1, v.end()); + QCOMPARE(v.size(), 1); + } + { + QVector v(12); + v.reserve(16); + v.erase(v.begin(), v.end() - 1); + QCOMPARE(v.size(), 1); + } + { + QVector v(12); + v.reserve(16); + v.erase(v.begin() + 5); + QCOMPARE(v.size(), 11); + v.erase(v.begin() + 1, v.end() - 1); + QCOMPARE(v.size(), 2); + } + { + QVector v(10); + v.reserve(16); + v.setSharable(false); + v.erase(v.begin() + 3); + QCOMPARE(v.size(), 9); + v.erase(v.begin(), v.end() - 1); + QCOMPARE(v.size(), 1); + } +} + +void tst_QVector::eraseReservedInt() const +{ + eraseReserved(); +} + +void tst_QVector::eraseReservedMovable() const +{ + const int instancesCount = Movable::counter; + eraseReserved(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::eraseReservedCustom() const +{ + const int instancesCount = Custom::counter; + eraseReserved(); + QCOMPARE(instancesCount, Custom::counter); +} + +template void tst_QVector::fill() const { - QVector myvec; + QVector myvec; // resize myvec.resize(5); - myvec.fill(69); - QCOMPARE(myvec, QVector() << 69 << 69 << 69 << 69 << 69); + myvec.fill(SimpleValue::at(1)); + QCOMPARE(myvec, QVector() << SimpleValue::at(1) << SimpleValue::at(1) + << SimpleValue::at(1) << SimpleValue::at(1) + << SimpleValue::at(1)); // make sure it can resize itself too - myvec.fill(42, 10); - QCOMPARE(myvec, QVector() << 42 << 42 << 42 << 42 << 42 << 42 << 42 << 42 << 42 << 42); + myvec.fill(SimpleValue::at(2), 10); + QCOMPARE(myvec, QVector() << SimpleValue::at(2) << SimpleValue::at(2) + << SimpleValue::at(2) << SimpleValue::at(2) + << SimpleValue::at(2) << SimpleValue::at(2) + << SimpleValue::at(2) << SimpleValue::at(2) + << SimpleValue::at(2) << SimpleValue::at(2)); +} + +void tst_QVector::fillInt() const +{ + fill(); +} + +void tst_QVector::fillMovable() const +{ + const int instancesCount = Movable::counter; + fill(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::fillCustom() const +{ + const int instancesCount = Custom::counter; + fill(); + QCOMPARE(instancesCount, Custom::counter); } void tst_QVector::first() const @@ -342,17 +1048,37 @@ void tst_QVector::first() const QCOMPARE(myvec.first(), 23); } +template void tst_QVector::fromList() const { - QList list; - list << "aaa" << "bbb" << "ninjas" << "pirates"; + QList list; + list << SimpleValue::at(0) << SimpleValue::at(1) << SimpleValue::at(2) << SimpleValue::at(3); - QVector myvec; - myvec = QVector::fromList(list); + QVector myvec; + myvec = QVector::fromList(list); // test it worked ok - QCOMPARE(myvec, QVector() << "aaa" << "bbb" << "ninjas" << "pirates"); - QCOMPARE(list, QList() << "aaa" << "bbb" << "ninjas" << "pirates"); + QCOMPARE(myvec, QVector() << SimpleValue::at(0) << SimpleValue::at(1) << SimpleValue::at(2) << SimpleValue::at(3)); + QCOMPARE(list, QList() << SimpleValue::at(0) << SimpleValue::at(1) << SimpleValue::at(2) << SimpleValue::at(3)); +} + +void tst_QVector::fromListInt() const +{ + fromList(); +} + +void tst_QVector::fromListMovable() const +{ + const int instancesCount = Movable::counter; + fromList(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::fromListCustom() const +{ + const int instancesCount = Custom::counter; + fromList(); + QCOMPARE(instancesCount, Custom::counter); } void tst_QVector::fromStdVector() const @@ -486,73 +1212,382 @@ void tst_QVector::mid() const QCOMPARE(list.mid(4), QVector() << "buck" << "hello" << "kitty"); } +template void tst_QVector::prepend() const { - QVector myvec; - myvec << "A" << "B" << "C"; + QVector myvec; + T val1 = SimpleValue::at(0); + T val2 = SimpleValue::at(1); + T val3 = SimpleValue::at(2); + T val4 = SimpleValue::at(3); + T val5 = SimpleValue::at(4); + myvec << val1 << val2 << val3; // starts ok QVERIFY(myvec.size() == 3); - QCOMPARE(myvec.at(0), QLatin1String("A")); + QCOMPARE(myvec.at(0), val1); // add something - myvec.prepend(QLatin1String("X")); - QCOMPARE(myvec.at(0), QLatin1String("X")); - QCOMPARE(myvec.at(1), QLatin1String("A")); + myvec.prepend(val4); + QCOMPARE(myvec.at(0), val4); + QCOMPARE(myvec.at(1), val1); QVERIFY(myvec.size() == 4); // something else - myvec.prepend(QLatin1String("Z")); - QCOMPARE(myvec.at(0), QLatin1String("Z")); - QCOMPARE(myvec.at(1), QLatin1String("X")); - QCOMPARE(myvec.at(2), QLatin1String("A")); + myvec.prepend(val5); + QCOMPARE(myvec.at(0), val5); + QCOMPARE(myvec.at(1), val4); + QCOMPARE(myvec.at(2), val1); QVERIFY(myvec.size() == 5); - // clear and append to an empty vector + // clear and prepend to an empty vector myvec.clear(); QVERIFY(myvec.size() == 0); - myvec.prepend(QLatin1String("ninjas")); + myvec.prepend(val5); QVERIFY(myvec.size() == 1); - QCOMPARE(myvec.at(0), QLatin1String("ninjas")); + QCOMPARE(myvec.at(0), val5); } -void tst_QVector::remove() const +void tst_QVector::prependInt() const { - QVector myvec; - myvec << "A" << "B" << "C"; + prepend(); +} + +void tst_QVector::prependMovable() const +{ + const int instancesCount = Movable::counter; + prepend(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::prependCustom() const +{ + const int instancesCount = Custom::counter; + prepend(); + QCOMPARE(instancesCount, Custom::counter); +} +template +void tst_QVector::remove() const +{ + QVector myvec; + T val1 = SimpleValue::at(1); + T val2 = SimpleValue::at(2); + T val3 = SimpleValue::at(3); + myvec << val1 << val2 << val3; // remove middle myvec.remove(1); - QCOMPARE(myvec, QVector() << "A" << "C"); + QCOMPARE(myvec, QVector() << val1 << val3); // remove rest myvec.remove(0, 2); - QCOMPARE(myvec, QVector()); + QCOMPARE(myvec, QVector()); } -// ::reserve() is really hard to think of tests for, so not doing it. -// ::resize() is tested in ::capacity(). +void tst_QVector::removeInt() const +{ + remove(); +} -void tst_QVector::size() const +void tst_QVector::removeMovable() const { - // total size + const int instancesCount = Movable::counter; + remove(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::removeCustom() const +{ + const int instancesCount = Custom::counter; + remove(); + QCOMPARE(instancesCount, Custom::counter); +} + +void tst_QVector::resizePOD_data() const +{ + QTest::addColumn >("vector"); + QTest::addColumn("size"); + + QVERIFY(!QTypeInfo::isComplex); + QVERIFY(!QTypeInfo::isStatic); + + QVector null; + QVector empty(0, 5); + QVector emptyReserved; + QVector nonEmpty; + QVector nonEmptyReserved; + + emptyReserved.reserve(10); + nonEmptyReserved.reserve(15); + nonEmpty << 0 << 1 << 2 << 3 << 4; + nonEmptyReserved << 0 << 1 << 2 << 3 << 4 << 5 << 6; + QVERIFY(emptyReserved.capacity() >= 10); + QVERIFY(nonEmptyReserved.capacity() >= 15); + + QVector nullNotShared; + QVector emptyNotShared(0, 5); + QVector emptyReservedNotShared; + QVector nonEmptyNotShared; + QVector nonEmptyReservedNotShared; + + emptyReservedNotShared.reserve(10); + nonEmptyReservedNotShared.reserve(15); + nonEmptyNotShared << 0 << 1 << 2 << 3 << 4; + nonEmptyReservedNotShared << 0 << 1 << 2 << 3 << 4 << 5 << 6; + QVERIFY(emptyReservedNotShared.capacity() >= 10); + QVERIFY(nonEmptyReservedNotShared.capacity() >= 15); + + emptyNotShared.setSharable(false); + emptyReservedNotShared.setSharable(false); + nonEmptyNotShared.setSharable(false); + nonEmptyReservedNotShared.setSharable(false); + + QTest::newRow("null") << null << 10; + QTest::newRow("empty") << empty << 10; + QTest::newRow("emptyReserved") << emptyReserved << 10; + QTest::newRow("nonEmpty") << nonEmpty << 10; + QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; + QTest::newRow("nullNotShared") << nullNotShared << 10; + QTest::newRow("emptyNotShared") << emptyNotShared << 10; + QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10; + QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10; + QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10; +} + +void tst_QVector::resizePOD() const +{ + QFETCH(QVector, vector); + QFETCH(int, size); + + const int oldSize = vector.size(); + + vector.resize(size); + QCOMPARE(vector.size(), size); + QVERIFY(vector.capacity() >= size); + for (int i = oldSize; i < size; ++i) + QVERIFY(vector[i] == 0); // check initialization + + const int capacity = vector.capacity(); + + vector.resize(0); + QCOMPARE(vector.size(), 0); + QVERIFY(vector.capacity() <= capacity); +} + +void tst_QVector::resizeComplexMovable_data() const +{ + QTest::addColumn >("vector"); + QTest::addColumn("size"); + + QVERIFY(QTypeInfo::isComplex); + QVERIFY(!QTypeInfo::isStatic); + + QVector null; + QVector empty(0, 'Q'); + QVector emptyReserved; + QVector nonEmpty; + QVector nonEmptyReserved; + + emptyReserved.reserve(10); + nonEmptyReserved.reserve(15); + nonEmpty << '0' << '1' << '2' << '3' << '4'; + nonEmptyReserved << '0' << '1' << '2' << '3' << '4' << '5' << '6'; + QVERIFY(emptyReserved.capacity() >= 10); + QVERIFY(nonEmptyReserved.capacity() >= 15); + + QVector nullNotShared; + QVector emptyNotShared(0, 'Q'); + QVector emptyReservedNotShared; + QVector nonEmptyNotShared; + QVector nonEmptyReservedNotShared; + + emptyReservedNotShared.reserve(10); + nonEmptyReservedNotShared.reserve(15); + nonEmptyNotShared << '0' << '1' << '2' << '3' << '4'; + nonEmptyReservedNotShared << '0' << '1' << '2' << '3' << '4' << '5' << '6'; + QVERIFY(emptyReservedNotShared.capacity() >= 10); + QVERIFY(nonEmptyReservedNotShared.capacity() >= 15); + + emptyNotShared.setSharable(false); + emptyReservedNotShared.setSharable(false); + nonEmptyNotShared.setSharable(false); + nonEmptyReservedNotShared.setSharable(false); + + QTest::newRow("null") << null << 10; + QTest::newRow("empty") << empty << 10; + QTest::newRow("emptyReserved") << emptyReserved << 10; + QTest::newRow("nonEmpty") << nonEmpty << 10; + QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; + QTest::newRow("nullNotShared") << nullNotShared << 10; + QTest::newRow("emptyNotShared") << emptyNotShared << 10; + QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10; + QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10; + QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10; +} + +void tst_QVector::resizeComplexMovable() const +{ + const int items = Movable::counter; { - // zero size - QVector myvec; - QVERIFY(myvec.size() == 0); + QFETCH(QVector, vector); + QFETCH(int, size); - // grow - myvec.append(42); - QVERIFY(myvec.size() == 1); - myvec.append(42); - QVERIFY(myvec.size() == 2); + const int oldSize = vector.size(); - // shrink - myvec.remove(0); - QVERIFY(myvec.size() == 1); - myvec.remove(0); - QVERIFY(myvec.size() == 0); + vector.resize(size); + QCOMPARE(vector.size(), size); + QVERIFY(vector.capacity() >= size); + for (int i = oldSize; i < size; ++i) + QVERIFY(vector[i] == 'j'); // check initialization + + const int capacity = vector.capacity(); + + vector.resize(0); + QCOMPARE(vector.size(), 0); + QVERIFY(vector.capacity() <= capacity); + } + QCOMPARE(items, Movable::counter); +} + +void tst_QVector::resizeComplex_data() const +{ + QTest::addColumn >("vector"); + QTest::addColumn("size"); + + QVERIFY(QTypeInfo::isComplex); + QVERIFY(QTypeInfo::isStatic); + + QVector null; + QVector empty(0, '0'); + QVector emptyReserved; + QVector nonEmpty; + QVector nonEmptyReserved; + + emptyReserved.reserve(10); + nonEmptyReserved.reserve(15); + nonEmpty << '0' << '1' << '2' << '3' << '4'; + nonEmptyReserved << '0' << '1' << '2' << '3' << '4' << '5' << '6'; + QVERIFY(emptyReserved.capacity() >= 10); + QVERIFY(nonEmptyReserved.capacity() >= 15); + + QVector nullNotShared; + QVector emptyNotShared(0, '0'); + QVector emptyReservedNotShared; + QVector nonEmptyNotShared; + QVector nonEmptyReservedNotShared; + + emptyReservedNotShared.reserve(10); + nonEmptyReservedNotShared.reserve(15); + nonEmptyNotShared << '0' << '1' << '2' << '3' << '4'; + nonEmptyReservedNotShared << '0' << '1' << '2' << '3' << '4' << '5' << '6'; + QVERIFY(emptyReservedNotShared.capacity() >= 10); + QVERIFY(nonEmptyReservedNotShared.capacity() >= 15); + + emptyNotShared.setSharable(false); + emptyReservedNotShared.setSharable(false); + nonEmptyNotShared.setSharable(false); + nonEmptyReservedNotShared.setSharable(false); + + QTest::newRow("null") << null << 10; + QTest::newRow("empty") << empty << 10; + QTest::newRow("emptyReserved") << emptyReserved << 10; + QTest::newRow("nonEmpty") << nonEmpty << 10; + QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; + QTest::newRow("nullNotShared") << nullNotShared << 10; + QTest::newRow("emptyNotShared") << emptyNotShared << 10; + QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10; + QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10; + QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10; +} + +void tst_QVector::resizeComplex() const +{ + const int items = Custom::counter; + { + QFETCH(QVector, vector); + QFETCH(int, size); + + int oldSize = vector.size(); + vector.resize(size); + QCOMPARE(vector.size(), size); + QVERIFY(vector.capacity() >= size); + for (int i = oldSize; i < size; ++i) + QVERIFY(vector[i].i == 'j'); // check default initialization + + const int capacity = vector.capacity(); + + vector.resize(0); + QCOMPARE(vector.size(), 0); + QVERIFY(vector.isEmpty()); + QVERIFY(vector.capacity() <= capacity); } + QCOMPARE(Custom::counter, items); +} + +void tst_QVector::resizeCtorAndDtor() const +{ + const int items = Custom::counter; + { + QVector null; + QVector empty(0, '0'); + QVector emptyReserved; + QVector nonEmpty; + QVector nonEmptyReserved; + + emptyReserved.reserve(10); + nonEmptyReserved.reserve(15); + nonEmpty << '0' << '1' << '2' << '3' << '4'; + nonEmptyReserved << '0' << '1' << '2' << '3' << '4' << '5' << '6'; + QVERIFY(emptyReserved.capacity() >= 10); + QVERIFY(nonEmptyReserved.capacity() >= 15); + + // start playing with vectors + null.resize(21); + nonEmpty.resize(2); + emptyReserved.resize(0); + nonEmpty.resize(0); + nonEmptyReserved.resize(2); + } + QCOMPARE(Custom::counter, items); +} + +template +void tst_QVector::size() const +{ + // zero size + QVector myvec; + QVERIFY(myvec.size() == 0); + + // grow + myvec.append(SimpleValue::at(0)); + QVERIFY(myvec.size() == 1); + myvec.append(SimpleValue::at(1)); + QVERIFY(myvec.size() == 2); + + // shrink + myvec.remove(0); + QVERIFY(myvec.size() == 1); + myvec.remove(0); + QVERIFY(myvec.size() == 0); +} + +void tst_QVector::sizeInt() const +{ + size(); +} + +void tst_QVector::sizeMovable() const +{ + const int instancesCount = Movable::counter; + size(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::sizeCustom() const +{ + const int instancesCount = Custom::counter; + size(); + QCOMPARE(instancesCount, Custom::counter); } // ::squeeze() is tested in ::capacity(). @@ -577,15 +1612,41 @@ void tst_QVector::startsWith() const QVERIFY(myvec.startsWith(1)); } +template void tst_QVector::swap() const { - QVector v1, v2; - v1 << 1 << 2 << 3; - v2 << 4 << 5 << 6; + QVector v1, v2; + T val1 = SimpleValue::at(0); + T val2 = SimpleValue::at(1); + T val3 = SimpleValue::at(2); + T val4 = SimpleValue::at(3); + T val5 = SimpleValue::at(4); + T val6 = SimpleValue::at(5); + v1 << val1 << val2 << val3; + v2 << val4 << val5 << val6; v1.swap(v2); - QCOMPARE(v1,QVector() << 4 << 5 << 6); - QCOMPARE(v2,QVector() << 1 << 2 << 3); + QCOMPARE(v1,QVector() << val4 << val5 << val6); + QCOMPARE(v2,QVector() << val1 << val2 << val3); +} + +void tst_QVector::swapInt() const +{ + swap(); +} + +void tst_QVector::swapMovable() const +{ + const int instancesCount = Movable::counter; + swap(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::swapCustom() const +{ + const int instancesCount = Custom::counter; + swap(); + QCOMPARE(instancesCount, Custom::counter); } void tst_QVector::toList() const @@ -923,20 +1984,45 @@ void tst_QVector::reallocAfterCopy() QCOMPARE(v2.size(), result4); } +template void tst_QVector::initializeList() { #ifdef Q_COMPILER_INITIALIZER_LISTS - QVector v1{2,3,4}; - QCOMPARE(v1, QVector() << 2 << 3 << 4); - QCOMPARE(v1, (QVector{2,3,4})); - - QVector> v2{ v1, {1}, QVector(), {2,3,4} }; - QVector> v3; - v3 << v1 << (QVector() << 1) << QVector() << v1; + T val1(SimpleValue::at(1)); + T val2(SimpleValue::at(2)); + T val3(SimpleValue::at(3)); + T val4(SimpleValue::at(4)); + + QVector v1 {val1, val2, val3}; + QCOMPARE(v1, QVector() << val1 << val2 << val3); + QCOMPARE(v1, (QVector {val1, val2, val3})); + + QVector> v2{ v1, {val4}, QVector(), {val1, val2, val3} }; + QVector> v3; + v3 << v1 << (QVector() << val4) << QVector() << v1; QCOMPARE(v3, v2); #endif } +void tst_QVector::initializeListInt() +{ + initializeList(); +} + +void tst_QVector::initializeListMovable() +{ + const int instancesCount = Movable::counter; + initializeList(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::initializeListCustom() +{ + const int instancesCount = Custom::counter; + initializeList(); + QCOMPARE(instancesCount, Custom::counter); +} + void tst_QVector::const_shared_null() { QVector v1; @@ -950,24 +2036,25 @@ void tst_QVector::const_shared_null() Q_DECLARE_METATYPE(QVector); -void tst_QVector::setSharable_data() +template +void tst_QVector::setSharable_data() const { - QTest::addColumn >("vector"); + QTest::addColumn >("vector"); QTest::addColumn("size"); QTest::addColumn("capacity"); QTest::addColumn("isCapacityReserved"); - QVector null; - QVector empty(0, 5); - QVector emptyReserved; - QVector nonEmpty; - QVector nonEmptyReserved; + QVector null; + QVector empty(0, SimpleValue::at(1)); + QVector emptyReserved; + QVector nonEmpty; + QVector nonEmptyReserved; emptyReserved.reserve(10); nonEmptyReserved.reserve(15); - nonEmpty << 0 << 1 << 2 << 3 << 4; - nonEmptyReserved << 0 << 1 << 2 << 3 << 4 << 5 << 6; + nonEmpty << SimpleValue::at(0) << SimpleValue::at(1) << SimpleValue::at(2) << SimpleValue::at(3) << SimpleValue::at(4); + nonEmptyReserved << SimpleValue::at(0) << SimpleValue::at(1) << SimpleValue::at(2) << SimpleValue::at(3) << SimpleValue::at(4) << SimpleValue::at(5) << SimpleValue::at(6); QVERIFY(emptyReserved.capacity() >= 10); QVERIFY(nonEmptyReserved.capacity() >= 15); @@ -979,9 +2066,25 @@ void tst_QVector::setSharable_data() QTest::newRow("non-empty, Reserved") << nonEmptyReserved << 7 << 15 << true; } -void tst_QVector::setSharable() +void tst_QVector::setSharableInt_data() { - QFETCH(QVector, vector); + setSharable_data(); +} + +void tst_QVector::setSharableMovable_data() +{ + setSharable_data(); +} + +void tst_QVector::setSharableCustom_data() +{ + setSharable_data(); +} + +template +void tst_QVector::setSharable() const +{ + QFETCH(QVector, vector); QFETCH(int, size); QFETCH(int, capacity); QFETCH(bool, isCapacityReserved); @@ -998,19 +2101,19 @@ void tst_QVector::setSharable() .arg(capacity))); { - QVector copy(vector); + QVector copy(vector); QVERIFY(!copy.isDetached()); QVERIFY(copy.isSharedWith(vector)); } vector.setSharable(false); - QVERIFY(vector.isDetached() || vector.isSharedWith(QVector())); + QVERIFY(vector.isDetached() || vector.isSharedWith(QVector())); { - QVector copy(vector); + QVector copy(vector); - QVERIFY(copy.isDetached() || copy.isSharedWith(QVector())); + QVERIFY(copy.isDetached() || copy.isEmpty() || copy.isSharedWith(QVector())); QCOMPARE(copy.size(), size); if (isCapacityReserved) QVERIFY2(copy.capacity() >= capacity, @@ -1023,14 +2126,14 @@ void tst_QVector::setSharable() vector.setSharable(true); { - QVector copy(vector); + QVector copy(vector); QVERIFY(!copy.isDetached()); QVERIFY(copy.isSharedWith(vector)); } for (int i = 0; i < vector.size(); ++i) - QCOMPARE(vector[i], i); + QCOMPARE(vector[i], SimpleValue::at(i)); QCOMPARE(vector.size(), size); if (isCapacityReserved) @@ -1040,5 +2143,140 @@ void tst_QVector::setSharable() .arg(capacity))); } +void tst_QVector::setSharableInt() +{ + setSharable(); +} + +void tst_QVector::setSharableMovable() +{ + const int instancesCount = Movable::counter; + setSharable(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::setSharableCustom() +{ + const int instancesCount = Custom::counter; + setSharable(); + QCOMPARE(instancesCount, Custom::counter); +} + +template +void tst_QVector::detach() const +{ + { + // detach an empty vector + QVector v; + v.detach(); + QVERIFY(v.isDetached()); + QCOMPARE(v.size(), 0); + QCOMPARE(v.capacity(), 0); + } + { + // detach an empty referenced vector + QVector v; + QVector ref(v); + QVERIFY(!v.isDetached()); + v.detach(); + QVERIFY(v.isDetached()); + QCOMPARE(v.size(), 0); + QCOMPARE(v.capacity(), 0); + } + { + // detach a not empty referenced vector + QVector v(31); + QVector ref(v); + QVERIFY(!v.isDetached()); + v.detach(); + QVERIFY(v.isDetached()); + QCOMPARE(v.size(), 31); + QCOMPARE(v.capacity(), 31); + } + { + // detach a not empty vector + QVector v(31); + QVERIFY(v.isDetached()); + v.detach(); // detaching a detached vector + QVERIFY(v.isDetached()); + QCOMPARE(v.size(), 31); + QCOMPARE(v.capacity(), 31); + } + { + // detach a not empty vector with preallocated space + QVector v(3); + v.reserve(8); + QVector ref(v); + QVERIFY(!v.isDetached()); + v.detach(); + QVERIFY(v.isDetached()); + QCOMPARE(v.size(), 3); + QCOMPARE(v.capacity(), 8); + } + { + // detach a not empty vector with preallocated space + QVector v(3); + v.reserve(8); + QVERIFY(v.isDetached()); + v.detach(); // detaching a detached vector + QVERIFY(v.isDetached()); + QCOMPARE(v.size(), 3); + QCOMPARE(v.capacity(), 8); + } + { + // detach a not empty, initialized vector + QVector v(7, SimpleValue::at(1)); + QVector ref(v); + QVERIFY(!v.isDetached()); + v.detach(); + QVERIFY(v.isDetached()); + QCOMPARE(v.size(), 7); + for (int i = 0; i < v.size(); ++i) + QCOMPARE(v[i], SimpleValue::at(1)); + } + { + // detach a not empty, initialized vector + QVector v(7, SimpleValue::at(2)); + QVERIFY(v.isDetached()); + v.detach(); // detaching a detached vector + QVERIFY(v.isDetached()); + QCOMPARE(v.size(), 7); + for (int i = 0; i < v.size(); ++i) + QCOMPARE(v[i], SimpleValue::at(2)); + } + { + // detach a not empty, initialized vector with preallocated space + QVector v(7, SimpleValue::at(3)); + v.reserve(31); + QVector ref(v); + QVERIFY(!v.isDetached()); + v.detach(); + QVERIFY(v.isDetached()); + QCOMPARE(v.size(), 7); + QCOMPARE(v.capacity(), 31); + for (int i = 0; i < v.size(); ++i) + QCOMPARE(v[i], SimpleValue::at(3)); + } +} + +void tst_QVector::detachInt() const +{ + detach(); +} + +void tst_QVector::detachMovable() const +{ + const int instancesCount = Movable::counter; + detach(); + QCOMPARE(instancesCount, Movable::counter); +} + +void tst_QVector::detachCustom() const +{ + const int instancesCount = Custom::counter; + detach(); + QCOMPARE(instancesCount, Custom::counter); +} + QTEST_APPLESS_MAIN(tst_QVector) #include "tst_qvector.moc" diff --git a/tests/benchmarks/corelib/tools/qvector/outofline.cpp b/tests/benchmarks/corelib/tools/qvector/outofline.cpp index bf929780a5..138812833f 100644 --- a/tests/benchmarks/corelib/tools/qvector/outofline.cpp +++ b/tests/benchmarks/corelib/tools/qvector/outofline.cpp @@ -79,3 +79,36 @@ std::vector stdvector_fill_and_return_helper() return v; } +const QVectorData QVectorData::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, false, 0 }; + +static inline int alignmentThreshold() +{ + // malloc on 32-bit platforms should return pointers that are 8-byte aligned or more + // while on 64-bit platforms they should be 16-byte aligned or more + return 2 * sizeof(void*); +} + +QVectorData *QVectorData::allocate(int size, int alignment) +{ + return static_cast(alignment > alignmentThreshold() ? qMallocAligned(size, alignment) : ::malloc(size)); +} + +QVectorData *QVectorData::reallocate(QVectorData *x, int newsize, int oldsize, int alignment) +{ + if (alignment > alignmentThreshold()) + return static_cast(qReallocAligned(x, newsize, oldsize, alignment)); + return static_cast(realloc(x, newsize)); +} + +void QVectorData::free(QVectorData *x, int alignment) +{ + if (alignment > alignmentThreshold()) + qFreeAligned(x); + else + ::free(x); +} + +int QVectorData::grow(int sizeOfHeader, int size, int sizeOfT) +{ + return qAllocMore(size * sizeOfT, sizeOfHeader) / sizeOfT; +} diff --git a/tests/benchmarks/corelib/tools/qvector/qrawvector.h b/tests/benchmarks/corelib/tools/qvector/qrawvector.h index 18d9847c95..7d80c125ea 100644 --- a/tests/benchmarks/corelib/tools/qvector/qrawvector.h +++ b/tests/benchmarks/corelib/tools/qvector/qrawvector.h @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -59,7 +60,32 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +struct QVectorData +{ + QtPrivate::RefCount ref; + int size; + uint alloc : 31; + uint capacityReserved : 1; + + qptrdiff offset; + + void* data() { return reinterpret_cast(this) + this->offset; } + + static const QVectorData shared_null; + static QVectorData *allocate(int size, int alignment); + static QVectorData *reallocate(QVectorData *old, int newsize, int oldsize, int alignment); + static void free(QVectorData *data, int alignment); + static int grow(int sizeOfHeader, int size, int sizeOfT); +}; +template +struct QVectorTypedData : QVectorData +{ + T* begin() { return reinterpret_cast(this->data()); } + T* end() { return begin() + this->size; } + + static QVectorTypedData *sharedNull() { return static_cast(const_cast(&QVectorData::shared_null)); } +}; template class QRawVector diff --git a/tests/benchmarks/corelib/tools/qvector/qvector.pro b/tests/benchmarks/corelib/tools/qvector/qvector.pro index e24b16230a..24a65d8ee8 100644 --- a/tests/benchmarks/corelib/tools/qvector/qvector.pro +++ b/tests/benchmarks/corelib/tools/qvector/qvector.pro @@ -1,5 +1,5 @@ TARGET = tst_bench_vector -QT = core testlib +QT = core testlib core-private INCLUDEPATH += . SOURCES += main.cpp outofline.cpp CONFIG += release -- cgit v1.2.3