summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorJędrzej Nowacki <jedrzej.nowacki@nokia.com>2012-04-26 12:06:17 +0200
committerQt by Nokia <qt-info@nokia.com>2012-05-30 17:07:27 +0200
commitd17cf14185eb84863549e0119c8b7bd20db78580 (patch)
tree843efdf2b591293fabf8c5a7cf448d9514f35495 /tests
parent5131aefc1f0c04936e3ef19c9870d884775471e5 (diff)
Implement QVector with QArrayData interface.
Change-Id: I109f46892aed2f6024459812d24922b12358814d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/tools/qvector/tst_qvector.cpp1486
-rw-r--r--tests/benchmarks/corelib/tools/qvector/outofline.cpp33
-rw-r--r--tests/benchmarks/corelib/tools/qvector/qrawvector.h26
-rw-r--r--tests/benchmarks/corelib/tools/qvector/qvector.pro2
4 files changed, 1422 insertions, 125 deletions
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 <QtTest/QtTest>
#include <qvector.h>
+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<int>::isStatic);
+Q_STATIC_ASSERT(!QTypeInfo<int>::isComplex);
+Q_STATIC_ASSERT(!QTypeInfo<Movable>::isStatic);
+Q_STATIC_ASSERT(QTypeInfo<Movable>::isComplex);
+Q_STATIC_ASSERT(QTypeInfo<Custom>::isStatic);
+Q_STATIC_ASSERT(QTypeInfo<Custom>::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<typename T> void copyConstructor() const;
+ template<typename T> void add() const;
+ template<typename T> void append() const;
+ template<typename T> void capacity() const;
+ template<typename T> void clear() const;
+ template<typename T> void count() const;
+ template<typename T> void empty() const;
+ template<typename T> void eraseEmpty() const;
+ template<typename T> void eraseEmptyReserved() const;
+ template<typename T> void erase() const;
+ template<typename T> void eraseReserved() const;
+ template<typename T> void fill() const;
+ template<typename T> void fromList() const;
+ template<typename T> void prepend() const;
+ template<typename T> void remove() const;
+ template<typename T> void size() const;
+ template<typename T> void swap() const;
+ template<typename T> void initializeList();
+ template<typename T> void setSharable_data() const;
+ template<typename T> void setSharable() const;
+ template<typename T> void detach() const;
};
-void tst_QVector::constructors() const
+template<typename T> struct SimpleValue
{
- // pre-reserve capacity
+ static T at(int index)
{
- QVector<int> myvec(5);
-
- QVERIFY(myvec.capacity() == 5);
+ return Values[index % MaxIndex];
}
+ static const uint MaxIndex = 6;
+ static const T Values[MaxIndex];
+};
+template<>
+const int SimpleValue<int>::Values[] = { 110, 105, 101, 114, 111, 98 };
+template<>
+const Movable SimpleValue<Movable>::Values[] = { 110, 105, 101, 114, 111, 98 };
+template<>
+const Custom SimpleValue<Custom>::Values[] = { 110, 105, 101, 114, 111, 98 };
+
+void tst_QVector::constructors_empty() const
+{
+ QVector<int> emptyInt;
+ QVector<Movable> emptyMovable;
+ QVector<Custom> emptyCustom;
+}
+
+void tst_QVector::constructors_emptyReserveZero() const
+{
+ QVector<int> emptyInt(0);
+ QVector<Movable> emptyMovable(0);
+ QVector<Custom> emptyCustom(0);
+}
+
+void tst_QVector::constructors_emptyReserve() const
+{
+ // pre-reserve capacity
+ QVector<int> myInt(5);
+ QVERIFY(myInt.capacity() == 5);
+ QVector<Movable> myMovable(5);
+ QVERIFY(myMovable.capacity() == 5);
+ QVector<Custom> myCustom(4);
+ QVERIFY(myCustom.capacity() == 4);
+}
+
+void tst_QVector::constructors_reserveAndInitialize() const
+{
// default-initialise items
+
+ QVector<int> myInt(5, 42);
+ QVERIFY(myInt.capacity() == 5);
+ foreach (int meaningoflife, myInt) {
+ QCOMPARE(meaningoflife, 42);
+ }
+
+ QVector<QString> 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<Custom> myCustom(5, Custom('n'));
+ QVERIFY(myCustom.capacity() == 5);
+ // make sure all items are initialised ok
+ foreach (Custom meaningoflife, myCustom) {
+ QCOMPARE(meaningoflife.i, 'n');
+ }
+}
+
+template<typename T>
+void tst_QVector::copyConstructor() const
+{
+ T value1(SimpleValue<T>::at(0));
+ T value2(SimpleValue<T>::at(1));
+ T value3(SimpleValue<T>::at(2));
+ T value4(SimpleValue<T>::at(3));
{
- QVector<int> myvec(5, 42);
+ QVector<T> v1;
+ QVector<T> v2(v1);
+ QCOMPARE(v1, v2);
+ }
+ {
+ QVector<T> v1;
+ v1.setSharable(false);
+ QVector<T> v2(v1);
+ QVERIFY(!v1.isSharedWith(v2));
+ QCOMPARE(v1, v2);
+ }
+ {
+ QVector<T> v1;
+ v1 << value1 << value2 << value3 << value4;
+ QVector<T> v2(v1);
+ QCOMPARE(v1, v2);
+ }
+ {
+ QVector<T> v1;
+ v1 << value1 << value2 << value3 << value4;
+ v1.setSharable(false);
+ QVector<T> v2(v1);
+ QVERIFY(!v1.isSharedWith(v2));
+ QCOMPARE(v1, v2);
+ }
+}
- QVERIFY(myvec.capacity() == 5);
+void tst_QVector::copyConstructorInt() const
+{
+ copyConstructor<int>();
+}
- // 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<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::copyConstructorCustom() const
+{
+ const int instancesCount = Custom::counter;
+ copyConstructor<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
+}
+
+template<typename T>
+void tst_QVector::add() const
+{
+ {
+ QVector<T> empty1;
+ QVector<T> empty2;
+ QVERIFY((empty1 + empty2).isEmpty());
+ empty1 += empty2;
+ QVERIFY(empty1.isEmpty());
+ QVERIFY(empty2.isEmpty());
}
+ {
+ QVector<T> v(12);
+ QVector<T> empty;
+ QCOMPARE((v + empty), v);
+ v += empty;
+ QVERIFY(!v.isEmpty());
+ QCOMPARE(v.size(), 12);
+ QVERIFY(empty.isEmpty());
+ }
+ {
+ QVector<T> v1(12);
+ QVector<T> v2;
+ v2 += v1;
+ QVERIFY(!v1.isEmpty());
+ QCOMPARE(v1.size(), 12);
+ QVERIFY(!v2.isEmpty());
+ QCOMPARE(v2.size(), 12);
+ }
+}
+
+void tst_QVector::addInt() const
+{
+ add<int>();
+}
+
+void tst_QVector::addMovable() const
+{
+ const int instancesCount = Movable::counter;
+ add<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
}
+void tst_QVector::addCustom() const
+{
+ const int instancesCount = Custom::counter;
+ add<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
+}
+
+template<typename T>
void tst_QVector::append() const
{
- QVector<int> myvec;
- myvec.append(42);
- myvec.append(43);
- myvec.append(44);
+ {
+ QVector<T> myvec;
+ myvec.append(SimpleValue<T>::at(0));
+ QVERIFY(myvec.size() == 1);
+ myvec.append(SimpleValue<T>::at(1));
+ QVERIFY(myvec.size() == 2);
+ myvec.append(SimpleValue<T>::at(2));
+ QVERIFY(myvec.size() == 3);
- QVERIFY(myvec.size() == 3);
- QCOMPARE(myvec, QVector<int>() << 42 << 43 << 44);
+ QCOMPARE(myvec, QVector<T>() << SimpleValue<T>::at(0)
+ << SimpleValue<T>::at(1)
+ << SimpleValue<T>::at(2));
+ }
+ {
+ QVector<T> v(2);
+ v.append(SimpleValue<T>::at(0));
+ QVERIFY(v.size() == 3);
+ QCOMPARE(v.at(v.size() - 1), SimpleValue<T>::at(0));
+ }
+ {
+ QVector<T> v(2);
+ v.reserve(12);
+ v.append(SimpleValue<T>::at(0));
+ QVERIFY(v.size() == 3);
+ QCOMPARE(v.at(v.size() - 1), SimpleValue<T>::at(0));
+ }
+ {
+ QVector<T> v(2);
+ v.reserve(12);
+ v.setSharable(false);
+ v.append(SimpleValue<T>::at(0));
+ QVERIFY(v.size() == 3);
+ QCOMPARE(v.last(), SimpleValue<T>::at(0));
+ }
+}
+
+void tst_QVector::appendInt() const
+{
+ append<int>();
+}
+
+void tst_QVector::appendMovable() const
+{
+ const int instancesCount = Movable::counter;
+ append<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::appendCustom() const
+{
+ const int instancesCount = Custom::counter;
+ append<Custom>();
+ 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<typename T>
void tst_QVector::capacity() const
{
- QVector<QString> myvec;
+ QVector<T> 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<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
QVERIFY(myvec.capacity() >= 3);
// make sure it grows ok
- myvec << "aaa" << "bbb" << "ccc";
+ myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::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<int>();
+}
+
+void tst_QVector::capacityMovable() const
+{
+ const int instancesCount = Movable::counter;
+ capacity<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::capacityCustom() const
+{
+ const int instancesCount = Custom::counter;
+ capacity<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
+}
+
+template<typename T>
void tst_QVector::clear() const
{
- QVector<QString> myvec;
- myvec << "aaa" << "bbb" << "ccc";
+ QVector<T> myvec;
+ myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::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<int>();
+}
+
+void tst_QVector::clearMovable() const
+{
+ const int instancesCount = Movable::counter;
+ clear<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::clearCustom() const
+{
+ const int instancesCount = Custom::counter;
+ clear<Custom>();
+ 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<typename T>
void tst_QVector::count() const
{
// total size
{
// zero size
- QVector<int> myvec;
+ QVector<T> myvec;
QVERIFY(myvec.count() == 0);
// grow
- myvec.append(42);
+ myvec.append(SimpleValue<T>::at(0));
QVERIFY(myvec.count() == 1);
- myvec.append(42);
+ myvec.append(SimpleValue<T>::at(1));
QVERIFY(myvec.count() == 2);
// shrink
@@ -240,23 +681,42 @@ void tst_QVector::count() const
// count of items
{
- QVector<QString> myvec;
- myvec << "aaa" << "bbb" << "ccc";
+ QVector<T> myvec;
+ myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
// initial tests
- QVERIFY(myvec.count(QLatin1String("aaa")) == 1);
- QVERIFY(myvec.count(QLatin1String("pirates")) == 0);
+ QVERIFY(myvec.count(SimpleValue<T>::at(0)) == 1);
+ QVERIFY(myvec.count(SimpleValue<T>::at(3)) == 0);
// grow
- myvec.append(QLatin1String("aaa"));
- QVERIFY(myvec.count(QLatin1String("aaa")) == 2);
+ myvec.append(SimpleValue<T>::at(0));
+ QVERIFY(myvec.count(SimpleValue<T>::at(0)) == 2);
// shrink
myvec.remove(0);
- QVERIFY(myvec.count(QLatin1String("aaa")) == 1);
+ QVERIFY(myvec.count(SimpleValue<T>::at(0)) == 1);
}
}
+void tst_QVector::countInt() const
+{
+ count<int>();
+}
+
+void tst_QVector::countMovable() const
+{
+ const int instancesCount = Movable::counter;
+ count<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::countCustom() const
+{
+ const int instancesCount = Custom::counter;
+ count<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
+}
+
void tst_QVector::data() const
{
QVector<int> myvec;
@@ -275,15 +735,16 @@ void tst_QVector::data() const
QVERIFY(memcmp(myvec.data(), reinterpret_cast<int *>(&arr), sizeof(int) * 3) == 0);
}
+template<typename T>
void tst_QVector::empty() const
{
- QVector<int> myvec;
+ QVector<T> myvec;
// starts empty
QVERIFY(myvec.empty());
// not empty
- myvec.append(1);
+ myvec.append(SimpleValue<T>::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<int>();
+}
+
+void tst_QVector::emptyMovable() const
+{
+ const int instancesCount = Movable::counter;
+ empty<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::emptyCustom() const
+{
+ const int instancesCount = Custom::counter;
+ empty<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
+}
+
void tst_QVector::endsWith() const
{
QVector<int> myvec;
@@ -311,18 +791,244 @@ void tst_QVector::endsWith() const
QVERIFY(myvec.endsWith(1));
}
+template<typename T>
+void tst_QVector::eraseEmpty() const
+{
+ {
+ QVector<T> v;
+ v.erase(v.begin());
+ QCOMPARE(v.size(), 0);
+ v.erase(v.begin(), v.end());
+ QCOMPARE(v.size(), 0);
+ }
+ {
+ QVector<T> 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<int>();
+}
+
+void tst_QVector::eraseEmptyMovable() const
+{
+ const int instancesCount = Movable::counter;
+ eraseEmpty<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::eraseEmptyCustom() const
+{
+ const int instancesCount = Custom::counter;
+ eraseEmpty<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
+}
+
+template<typename T>
+void tst_QVector::eraseEmptyReserved() const
+{
+ {
+ QVector<T> v;
+ v.reserve(10);
+ v.erase(v.begin());
+ QCOMPARE(v.size(), 0);
+ v.erase(v.begin(), v.end());
+ QCOMPARE(v.size(), 0);
+ }
+ {
+ QVector<T> 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<int>();
+}
+
+void tst_QVector::eraseEmptyReservedMovable() const
+{
+ const int instancesCount = Movable::counter;
+ eraseEmptyReserved<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::eraseEmptyReservedCustom() const
+{
+ const int instancesCount = Custom::counter;
+ eraseEmptyReserved<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
+}
+
+template<typename T>
+void tst_QVector::erase() const
+{
+ {
+ QVector<T> v(12);
+ v.erase(v.begin());
+ QCOMPARE(v.size(), 11);
+ v.erase(v.begin(), v.end());
+ QCOMPARE(v.size(), 0);
+ }
+ {
+ QVector<T> v(12);
+ v.erase(v.begin() + 1);
+ QCOMPARE(v.size(), 11);
+ v.erase(v.begin() + 1, v.end());
+ QCOMPARE(v.size(), 1);
+ }
+ {
+ QVector<T> v(12);
+ v.erase(v.begin(), v.end() - 1);
+ QCOMPARE(v.size(), 1);
+ }
+ {
+ QVector<T> v(12);
+ v.erase(v.begin() + 5);
+ QCOMPARE(v.size(), 11);
+ v.erase(v.begin() + 1, v.end() - 1);
+ QCOMPARE(v.size(), 2);
+ }
+ {
+ QVector<T> 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<int>();
+}
+
+void tst_QVector::eraseMovable() const
+{
+ const int instancesCount = Movable::counter;
+ erase<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::eraseCustom() const
+{
+ const int instancesCount = Custom::counter;
+ erase<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
+}
+
+template<typename T> void tst_QVector::eraseReserved() const
+{
+ {
+ QVector<T> v(12);
+ v.reserve(16);
+ v.erase(v.begin());
+ QCOMPARE(v.size(), 11);
+ v.erase(v.begin(), v.end());
+ QCOMPARE(v.size(), 0);
+ }
+ {
+ QVector<T> 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<T> v(12);
+ v.reserve(16);
+ v.erase(v.begin(), v.end() - 1);
+ QCOMPARE(v.size(), 1);
+ }
+ {
+ QVector<T> 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<T> 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<int>();
+}
+
+void tst_QVector::eraseReservedMovable() const
+{
+ const int instancesCount = Movable::counter;
+ eraseReserved<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::eraseReservedCustom() const
+{
+ const int instancesCount = Custom::counter;
+ eraseReserved<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
+}
+
+template<typename T>
void tst_QVector::fill() const
{
- QVector<int> myvec;
+ QVector<T> myvec;
// resize
myvec.resize(5);
- myvec.fill(69);
- QCOMPARE(myvec, QVector<int>() << 69 << 69 << 69 << 69 << 69);
+ myvec.fill(SimpleValue<T>::at(1));
+ QCOMPARE(myvec, QVector<T>() << SimpleValue<T>::at(1) << SimpleValue<T>::at(1)
+ << SimpleValue<T>::at(1) << SimpleValue<T>::at(1)
+ << SimpleValue<T>::at(1));
// make sure it can resize itself too
- myvec.fill(42, 10);
- QCOMPARE(myvec, QVector<int>() << 42 << 42 << 42 << 42 << 42 << 42 << 42 << 42 << 42 << 42);
+ myvec.fill(SimpleValue<T>::at(2), 10);
+ QCOMPARE(myvec, QVector<T>() << SimpleValue<T>::at(2) << SimpleValue<T>::at(2)
+ << SimpleValue<T>::at(2) << SimpleValue<T>::at(2)
+ << SimpleValue<T>::at(2) << SimpleValue<T>::at(2)
+ << SimpleValue<T>::at(2) << SimpleValue<T>::at(2)
+ << SimpleValue<T>::at(2) << SimpleValue<T>::at(2));
+}
+
+void tst_QVector::fillInt() const
+{
+ fill<int>();
+}
+
+void tst_QVector::fillMovable() const
+{
+ const int instancesCount = Movable::counter;
+ fill<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::fillCustom() const
+{
+ const int instancesCount = Custom::counter;
+ fill<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
}
void tst_QVector::first() const
@@ -342,17 +1048,37 @@ void tst_QVector::first() const
QCOMPARE(myvec.first(), 23);
}
+template<typename T>
void tst_QVector::fromList() const
{
- QList<QString> list;
- list << "aaa" << "bbb" << "ninjas" << "pirates";
+ QList<T> list;
+ list << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3);
- QVector<QString> myvec;
- myvec = QVector<QString>::fromList(list);
+ QVector<T> myvec;
+ myvec = QVector<T>::fromList(list);
// test it worked ok
- QCOMPARE(myvec, QVector<QString>() << "aaa" << "bbb" << "ninjas" << "pirates");
- QCOMPARE(list, QList<QString>() << "aaa" << "bbb" << "ninjas" << "pirates");
+ QCOMPARE(myvec, QVector<T>() << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3));
+ QCOMPARE(list, QList<T>() << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3));
+}
+
+void tst_QVector::fromListInt() const
+{
+ fromList<int>();
+}
+
+void tst_QVector::fromListMovable() const
+{
+ const int instancesCount = Movable::counter;
+ fromList<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::fromListCustom() const
+{
+ const int instancesCount = Custom::counter;
+ fromList<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
}
void tst_QVector::fromStdVector() const
@@ -486,73 +1212,382 @@ void tst_QVector::mid() const
QCOMPARE(list.mid(4), QVector<QString>() << "buck" << "hello" << "kitty");
}
+template<typename T>
void tst_QVector::prepend() const
{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C";
+ QVector<T> myvec;
+ T val1 = SimpleValue<T>::at(0);
+ T val2 = SimpleValue<T>::at(1);
+ T val3 = SimpleValue<T>::at(2);
+ T val4 = SimpleValue<T>::at(3);
+ T val5 = SimpleValue<T>::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<QString> myvec;
- myvec << "A" << "B" << "C";
+ prepend<int>();
+}
+
+void tst_QVector::prependMovable() const
+{
+ const int instancesCount = Movable::counter;
+ prepend<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::prependCustom() const
+{
+ const int instancesCount = Custom::counter;
+ prepend<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
+}
+template<typename T>
+void tst_QVector::remove() const
+{
+ QVector<T> myvec;
+ T val1 = SimpleValue<T>::at(1);
+ T val2 = SimpleValue<T>::at(2);
+ T val3 = SimpleValue<T>::at(3);
+ myvec << val1 << val2 << val3;
// remove middle
myvec.remove(1);
- QCOMPARE(myvec, QVector<QString>() << "A" << "C");
+ QCOMPARE(myvec, QVector<T>() << val1 << val3);
// remove rest
myvec.remove(0, 2);
- QCOMPARE(myvec, QVector<QString>());
+ QCOMPARE(myvec, QVector<T>());
}
-// ::reserve() is really hard to think of tests for, so not doing it.
-// ::resize() is tested in ::capacity().
+void tst_QVector::removeInt() const
+{
+ remove<int>();
+}
-void tst_QVector::size() const
+void tst_QVector::removeMovable() const
{
- // total size
+ const int instancesCount = Movable::counter;
+ remove<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::removeCustom() const
+{
+ const int instancesCount = Custom::counter;
+ remove<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
+}
+
+void tst_QVector::resizePOD_data() const
+{
+ QTest::addColumn<QVector<int> >("vector");
+ QTest::addColumn<int>("size");
+
+ QVERIFY(!QTypeInfo<int>::isComplex);
+ QVERIFY(!QTypeInfo<int>::isStatic);
+
+ QVector<int> null;
+ QVector<int> empty(0, 5);
+ QVector<int> emptyReserved;
+ QVector<int> nonEmpty;
+ QVector<int> 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<int> nullNotShared;
+ QVector<int> emptyNotShared(0, 5);
+ QVector<int> emptyReservedNotShared;
+ QVector<int> nonEmptyNotShared;
+ QVector<int> 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<int>, 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<QVector<Movable> >("vector");
+ QTest::addColumn<int>("size");
+
+ QVERIFY(QTypeInfo<Movable>::isComplex);
+ QVERIFY(!QTypeInfo<Movable>::isStatic);
+
+ QVector<Movable> null;
+ QVector<Movable> empty(0, 'Q');
+ QVector<Movable> emptyReserved;
+ QVector<Movable> nonEmpty;
+ QVector<Movable> 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<Movable> nullNotShared;
+ QVector<Movable> emptyNotShared(0, 'Q');
+ QVector<Movable> emptyReservedNotShared;
+ QVector<Movable> nonEmptyNotShared;
+ QVector<Movable> 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<int> myvec;
- QVERIFY(myvec.size() == 0);
+ QFETCH(QVector<Movable>, 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<QVector<Custom> >("vector");
+ QTest::addColumn<int>("size");
+
+ QVERIFY(QTypeInfo<Custom>::isComplex);
+ QVERIFY(QTypeInfo<Custom>::isStatic);
+
+ QVector<Custom> null;
+ QVector<Custom> empty(0, '0');
+ QVector<Custom> emptyReserved;
+ QVector<Custom> nonEmpty;
+ QVector<Custom> 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<Custom> nullNotShared;
+ QVector<Custom> emptyNotShared(0, '0');
+ QVector<Custom> emptyReservedNotShared;
+ QVector<Custom> nonEmptyNotShared;
+ QVector<Custom> 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<Custom>, 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<Custom> null;
+ QVector<Custom> empty(0, '0');
+ QVector<Custom> emptyReserved;
+ QVector<Custom> nonEmpty;
+ QVector<Custom> 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<typename T>
+void tst_QVector::size() const
+{
+ // zero size
+ QVector<T> myvec;
+ QVERIFY(myvec.size() == 0);
+
+ // grow
+ myvec.append(SimpleValue<T>::at(0));
+ QVERIFY(myvec.size() == 1);
+ myvec.append(SimpleValue<T>::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<int>();
+}
+
+void tst_QVector::sizeMovable() const
+{
+ const int instancesCount = Movable::counter;
+ size<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::sizeCustom() const
+{
+ const int instancesCount = Custom::counter;
+ size<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
}
// ::squeeze() is tested in ::capacity().
@@ -577,15 +1612,41 @@ void tst_QVector::startsWith() const
QVERIFY(myvec.startsWith(1));
}
+template<typename T>
void tst_QVector::swap() const
{
- QVector<int> v1, v2;
- v1 << 1 << 2 << 3;
- v2 << 4 << 5 << 6;
+ QVector<T> v1, v2;
+ T val1 = SimpleValue<T>::at(0);
+ T val2 = SimpleValue<T>::at(1);
+ T val3 = SimpleValue<T>::at(2);
+ T val4 = SimpleValue<T>::at(3);
+ T val5 = SimpleValue<T>::at(4);
+ T val6 = SimpleValue<T>::at(5);
+ v1 << val1 << val2 << val3;
+ v2 << val4 << val5 << val6;
v1.swap(v2);
- QCOMPARE(v1,QVector<int>() << 4 << 5 << 6);
- QCOMPARE(v2,QVector<int>() << 1 << 2 << 3);
+ QCOMPARE(v1,QVector<T>() << val4 << val5 << val6);
+ QCOMPARE(v2,QVector<T>() << val1 << val2 << val3);
+}
+
+void tst_QVector::swapInt() const
+{
+ swap<int>();
+}
+
+void tst_QVector::swapMovable() const
+{
+ const int instancesCount = Movable::counter;
+ swap<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::swapCustom() const
+{
+ const int instancesCount = Custom::counter;
+ swap<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
}
void tst_QVector::toList() const
@@ -923,20 +1984,45 @@ void tst_QVector::reallocAfterCopy()
QCOMPARE(v2.size(), result4);
}
+template<typename T>
void tst_QVector::initializeList()
{
#ifdef Q_COMPILER_INITIALIZER_LISTS
- QVector<int> v1{2,3,4};
- QCOMPARE(v1, QVector<int>() << 2 << 3 << 4);
- QCOMPARE(v1, (QVector<int>{2,3,4}));
-
- QVector<QVector<int>> v2{ v1, {1}, QVector<int>(), {2,3,4} };
- QVector<QVector<int>> v3;
- v3 << v1 << (QVector<int>() << 1) << QVector<int>() << v1;
+ T val1(SimpleValue<T>::at(1));
+ T val2(SimpleValue<T>::at(2));
+ T val3(SimpleValue<T>::at(3));
+ T val4(SimpleValue<T>::at(4));
+
+ QVector<T> v1 {val1, val2, val3};
+ QCOMPARE(v1, QVector<T>() << val1 << val2 << val3);
+ QCOMPARE(v1, (QVector<T> {val1, val2, val3}));
+
+ QVector<QVector<T>> v2{ v1, {val4}, QVector<T>(), {val1, val2, val3} };
+ QVector<QVector<T>> v3;
+ v3 << v1 << (QVector<T>() << val4) << QVector<T>() << v1;
QCOMPARE(v3, v2);
#endif
}
+void tst_QVector::initializeListInt()
+{
+ initializeList<int>();
+}
+
+void tst_QVector::initializeListMovable()
+{
+ const int instancesCount = Movable::counter;
+ initializeList<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::initializeListCustom()
+{
+ const int instancesCount = Custom::counter;
+ initializeList<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
+}
+
void tst_QVector::const_shared_null()
{
QVector<int> v1;
@@ -950,24 +2036,25 @@ void tst_QVector::const_shared_null()
Q_DECLARE_METATYPE(QVector<int>);
-void tst_QVector::setSharable_data()
+template<typename T>
+void tst_QVector::setSharable_data() const
{
- QTest::addColumn<QVector<int> >("vector");
+ QTest::addColumn<QVector<T> >("vector");
QTest::addColumn<int>("size");
QTest::addColumn<int>("capacity");
QTest::addColumn<bool>("isCapacityReserved");
- QVector<int> null;
- QVector<int> empty(0, 5);
- QVector<int> emptyReserved;
- QVector<int> nonEmpty;
- QVector<int> nonEmptyReserved;
+ QVector<T> null;
+ QVector<T> empty(0, SimpleValue<T>::at(1));
+ QVector<T> emptyReserved;
+ QVector<T> nonEmpty;
+ QVector<T> nonEmptyReserved;
emptyReserved.reserve(10);
nonEmptyReserved.reserve(15);
- nonEmpty << 0 << 1 << 2 << 3 << 4;
- nonEmptyReserved << 0 << 1 << 2 << 3 << 4 << 5 << 6;
+ nonEmpty << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3) << SimpleValue<T>::at(4);
+ nonEmptyReserved << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3) << SimpleValue<T>::at(4) << SimpleValue<T>::at(5) << SimpleValue<T>::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<int>, vector);
+ setSharable_data<int>();
+}
+
+void tst_QVector::setSharableMovable_data()
+{
+ setSharable_data<Movable>();
+}
+
+void tst_QVector::setSharableCustom_data()
+{
+ setSharable_data<Custom>();
+}
+
+template<typename T>
+void tst_QVector::setSharable() const
+{
+ QFETCH(QVector<T>, vector);
QFETCH(int, size);
QFETCH(int, capacity);
QFETCH(bool, isCapacityReserved);
@@ -998,19 +2101,19 @@ void tst_QVector::setSharable()
.arg(capacity)));
{
- QVector<int> copy(vector);
+ QVector<T> copy(vector);
QVERIFY(!copy.isDetached());
QVERIFY(copy.isSharedWith(vector));
}
vector.setSharable(false);
- QVERIFY(vector.isDetached() || vector.isSharedWith(QVector<int>()));
+ QVERIFY(vector.isDetached() || vector.isSharedWith(QVector<T>()));
{
- QVector<int> copy(vector);
+ QVector<T> copy(vector);
- QVERIFY(copy.isDetached() || copy.isSharedWith(QVector<int>()));
+ QVERIFY(copy.isDetached() || copy.isEmpty() || copy.isSharedWith(QVector<T>()));
QCOMPARE(copy.size(), size);
if (isCapacityReserved)
QVERIFY2(copy.capacity() >= capacity,
@@ -1023,14 +2126,14 @@ void tst_QVector::setSharable()
vector.setSharable(true);
{
- QVector<int> copy(vector);
+ QVector<T> 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<T>::at(i));
QCOMPARE(vector.size(), size);
if (isCapacityReserved)
@@ -1040,5 +2143,140 @@ void tst_QVector::setSharable()
.arg(capacity)));
}
+void tst_QVector::setSharableInt()
+{
+ setSharable<int>();
+}
+
+void tst_QVector::setSharableMovable()
+{
+ const int instancesCount = Movable::counter;
+ setSharable<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::setSharableCustom()
+{
+ const int instancesCount = Custom::counter;
+ setSharable<Custom>();
+ QCOMPARE(instancesCount, Custom::counter);
+}
+
+template<typename T>
+void tst_QVector::detach() const
+{
+ {
+ // detach an empty vector
+ QVector<T> v;
+ v.detach();
+ QVERIFY(v.isDetached());
+ QCOMPARE(v.size(), 0);
+ QCOMPARE(v.capacity(), 0);
+ }
+ {
+ // detach an empty referenced vector
+ QVector<T> v;
+ QVector<T> 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<T> v(31);
+ QVector<T> ref(v);
+ QVERIFY(!v.isDetached());
+ v.detach();
+ QVERIFY(v.isDetached());
+ QCOMPARE(v.size(), 31);
+ QCOMPARE(v.capacity(), 31);
+ }
+ {
+ // detach a not empty vector
+ QVector<T> 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<T> v(3);
+ v.reserve(8);
+ QVector<T> 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<T> 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<T> v(7, SimpleValue<T>::at(1));
+ QVector<T> 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<T>::at(1));
+ }
+ {
+ // detach a not empty, initialized vector
+ QVector<T> v(7, SimpleValue<T>::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<T>::at(2));
+ }
+ {
+ // detach a not empty, initialized vector with preallocated space
+ QVector<T> v(7, SimpleValue<T>::at(3));
+ v.reserve(31);
+ QVector<T> 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<T>::at(3));
+ }
+}
+
+void tst_QVector::detachInt() const
+{
+ detach<int>();
+}
+
+void tst_QVector::detachMovable() const
+{
+ const int instancesCount = Movable::counter;
+ detach<Movable>();
+ QCOMPARE(instancesCount, Movable::counter);
+}
+
+void tst_QVector::detachCustom() const
+{
+ const int instancesCount = Custom::counter;
+ detach<Custom>();
+ 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<double> 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<QVectorData *>(alignment > alignmentThreshold() ? qMallocAligned(size, alignment) : ::malloc(size));
+}
+
+QVectorData *QVectorData::reallocate(QVectorData *x, int newsize, int oldsize, int alignment)
+{
+ if (alignment > alignmentThreshold())
+ return static_cast<QVectorData *>(qReallocAligned(x, newsize, oldsize, alignment));
+ return static_cast<QVectorData *>(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 <QtCore/qatomic.h>
#include <QtCore/qalgorithms.h>
#include <QtCore/qlist.h>
+#include <QtCore/private/qtools_p.h>
#include <iterator>
#include <vector>
@@ -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<char *>(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 <typename T>
+struct QVectorTypedData : QVectorData
+{
+ T* begin() { return reinterpret_cast<T *>(this->data()); }
+ T* end() { return begin() + this->size; }
+
+ static QVectorTypedData *sharedNull() { return static_cast<QVectorTypedData *>(const_cast<QVectorData *>(&QVectorData::shared_null)); }
+};
template <typename T>
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