summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/tools/qvector/tst_qvector.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-05-27 09:58:12 +0200
committerLars Knoll <lars.knoll@qt.io>2020-06-20 20:01:33 +0200
commit03326a2fec416405b437089874f6439e937bbada (patch)
tree48d7137c3cd5e6f537e06e97380d3c1e76a56af9 /tests/auto/corelib/tools/qvector/tst_qvector.cpp
parent1a9a4af388477efd9f7008d5c0bb74432c20279d (diff)
Move implementation of QVector/List back to qlist.h
And name the main class QList. That's also the one we document. This gives less porting pain for our users, and a lot less churn in our API, as we use QList in Qt 5 in 95% of our API. In addition, it gives more consistent naming with QStringList and QByteArrayList and disambiguates QList vs QVector(2|3|4)D. Fixes: QTBUG-84468 Change-Id: I3cba9d1d3179969d8bf9320b31be2230d021d1a9 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'tests/auto/corelib/tools/qvector/tst_qvector.cpp')
-rw-r--r--tests/auto/corelib/tools/qvector/tst_qvector.cpp2834
1 files changed, 0 insertions, 2834 deletions
diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp
deleted file mode 100644
index 899156545d..0000000000
--- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp
+++ /dev/null
@@ -1,2834 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QAtomicInt>
-#include <QThread>
-#include <QSemaphore>
-#include <qvector.h>
-
-struct Movable {
- Movable(char input = 'j')
- : i(input)
- , that(this)
- , state(Constructed)
- {
- counter.fetchAndAddRelaxed(1);
- }
- Movable(const Movable &other)
- : i(other.i)
- , that(this)
- , state(Constructed)
- {
- check(other.state, Constructed);
- counter.fetchAndAddRelaxed(1);
- }
- Movable(Movable &&other)
- : i(other.i)
- , that(other.that)
- , state(Constructed)
- {
- check(other.state, Constructed);
- counter.fetchAndAddRelaxed(1);
- other.that = nullptr;
- }
-
- ~Movable()
- {
- check(state, Constructed);
- i = 0;
- counter.fetchAndAddRelaxed(-1);
- 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;
- that = this;
- return *this;
- }
- Movable &operator=(Movable &&other)
- {
- check(state, Constructed);
- check(other.state, Constructed);
- i = other.i;
- that = other.that;
- other.that = nullptr;
- return *this;
- }
- bool wasConstructedAt(const Movable *other) const
- {
- return that == other;
- }
- char i;
- static QAtomicInt counter;
-private:
- Movable *that; // used to check if an instance was moved
-
- enum State { Constructed = 106, Destructed = 110 };
- State state;
-
- static void check(const State state1, const State state2)
- {
- QCOMPARE(int(state1), int(state2));
- }
-};
-
-inline size_t qHash(const Movable &key, size_t seed = 0) { return qHash(key.i, seed); }
-
-QAtomicInt 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.fetchAndAddRelaxed(1);
- }
- Custom(const Custom &other)
- : that(this)
- , state(Constructed)
- {
- check(&other);
- counter.fetchAndAddRelaxed(1);
- this->i = other.i;
- }
- ~Custom()
- {
- check(this);
- i = 0;
- counter.fetchAndAddRelaxed(-1);
- state = Destructed;
- }
-
- bool operator ==(const Custom &other) const
- {
- check(&other);
- check(this);
- return i == other.i;
- }
-
- 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 QAtomicInt 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(int(c->state), int(Constructed));
- }
-};
-QAtomicInt Custom::counter = 0;
-
-inline size_t qHash(const Custom &key, size_t seed = 0) { return qHash(key.i, seed); }
-
-Q_DECLARE_METATYPE(Custom);
-
-// tests depends on the fact that:
-static_assert(!QTypeInfo<int>::isStatic);
-static_assert(!QTypeInfo<int>::isComplex);
-static_assert(!QTypeInfo<Movable>::isStatic);
-static_assert(QTypeInfo<Movable>::isComplex);
-static_assert(QTypeInfo<Custom>::isStatic);
-static_assert(QTypeInfo<Custom>::isComplex);
-
-
-class tst_QVector : public QObject
-{
- Q_OBJECT
-private slots:
- 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 assignmentInt() const;
- void assignmentMovable() const;
- void assignmentCustom() const;
- void assignFromInitializerListInt() const;
- void assignFromInitializerListMovable() const;
- void assignFromInitializerListCustom() const;
- void addInt() const;
- void addMovable() const;
- void addCustom() const;
- void appendInt() const;
- void appendMovable() const;
- void appendCustom() const;
- void appendRvalue() const;
- void at() const;
- void capacityInt() const;
- void capacityMovable() const;
- void capacityCustom() const;
- void clearInt() const;
- void clearMovable() const;
- void clearCustom() const;
- void constData() const;
- void constFirst() const;
- void constLast() const;
- void contains() const;
- void countInt() const;
- void countMovable() const;
- void countCustom() const;
- void cpp17ctad() const;
- void data() const;
- void emptyInt() const;
- void emptyMovable() const;
- void emptyCustom() const;
- void endsWith() const;
- void eraseEmptyInt() const;
- void eraseEmptyMovable() const;
- void eraseEmptyCustom() const;
- void eraseEmptyReservedInt() const;
- void eraseEmptyReservedMovable() const;
- void eraseEmptyReservedCustom() const;
- void eraseInt() const;
- void eraseIntShared() const;
- void eraseMovable() const;
- void eraseMovableShared() const;
- void eraseCustom() const;
- void eraseCustomShared() const;
- void eraseReservedInt() const;
- void eraseReservedMovable() const;
- void eraseReservedCustom() const;
- void fillInt() const;
- void fillMovable() const;
- void fillCustom() const;
- void fillDetaches() const;
- void first() const;
- void fromListInt() const;
- void fromListMovable() const;
- void fromListCustom() const;
- void indexOf() const;
- void insertInt() const;
- void insertMovable() const;
- void insertCustom() const;
- void isEmpty() const;
- void last() const;
- void lastIndexOf() const;
- void mid() const;
- void moveInt() const;
- void moveMovable() const;
- void moveCustom() const;
- void prependInt() const;
- void prependMovable() const;
- void prependCustom() const;
- void qhashInt() const { qhash<int>(); }
- void qhashMovable() const { qhash<Movable>(); }
- void qhashCustom() const { qhash<Custom>(); }
- void removeAllWithAlias() const;
- void removeInt() const;
- void removeMovable() const;
- void removeCustom() const;
- void removeFirstLast() 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 reverseIterators() const;
- void sizeInt() const;
- void sizeMovable() const;
- void sizeCustom() const;
- void startsWith() const;
- void swapInt() const;
- void swapMovable() const;
- void swapCustom() const;
- void toList() const;
-#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
- void fromStdVector() const;
- void toStdVector() const;
-#endif
- void value() const;
-
- void testOperators() const;
-
- void reserve();
- void reserveZero();
- void initializeListInt();
- void initializeListMovable();
- void initializeListCustom();
-
- void const_shared_null();
-
- void detachInt() const;
- void detachMovable() const;
- void detachCustom() const;
- void detachThreadSafetyInt() const;
- void detachThreadSafetyMovable() const;
- void detachThreadSafetyCustom() const;
-
- void insertMove() const;
-
- void swapItemsAt() const;
-
- void emplaceInt();
- void emplaceCustom();
- void emplaceMovable();
- void emplaceConsistentWithStdVectorInt();
- void emplaceConsistentWithStdVectorCustom();
- void emplaceConsistentWithStdVectorMovable();
- void emplaceReturnsIterator();
- void emplaceBack();
- void emplaceBackReturnsRef();
- void emplaceWithElementFromTheSameContainer();
- void emplaceWithElementFromTheSameContainer_data();
-
-private:
- template<typename T> void copyConstructor() const;
- template<typename T> void add() const;
- template<typename T> void append() const;
- template<typename T> void assignFromInitializerList() 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(bool shared) const;
- template<typename T> void eraseReserved() const;
- template<typename T> void fill() const;
- template<typename T> void fromList() const;
- template<typename T> void insert() const;
- template<typename T> void qhash() const;
- template<typename T> void move() 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 detach() const;
- template<typename T> void detachThreadSafety() const;
- template<typename T> void emplaceImpl() const;
- template<typename T> void emplaceConsistentWithStdVectorImpl() const;
-};
-
-
-template<typename T> struct SimpleValue
-{
- static T at(int index)
- {
- return Values[index % MaxIndex];
- }
-
- static QVector<T> vector(int size)
- {
- QVector<T> ret;
- for (int i = 0; i < size; i++)
- ret.append(at(i));
- return ret;
- }
-
- 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 };
-
-// Make some macros for the tests to use in order to be slightly more readable...
-#define T_FOO SimpleValue<T>::at(0)
-#define T_BAR SimpleValue<T>::at(1)
-#define T_BAZ SimpleValue<T>::at(2)
-#define T_CAT SimpleValue<T>::at(3)
-#define T_DOG SimpleValue<T>::at(4)
-#define T_BLAH SimpleValue<T>::at(5)
-
-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<T> v1;
- QVector<T> v2(v1);
- QCOMPARE(v1, v2);
- }
- {
- QVector<T> v1;
- v1 << value1 << value2 << value3 << value4;
- QVector<T> v2(v1);
- QCOMPARE(v1, v2);
- }
-}
-
-void tst_QVector::copyConstructorInt() const
-{
- copyConstructor<int>();
-}
-
-void tst_QVector::copyConstructorMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- copyConstructor<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::copyConstructorCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- copyConstructor<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template <class T>
-static inline void testAssignment()
-{
- QVector<T> v1(5);
- QCOMPARE(v1.size(), 5);
- QVERIFY(v1.isDetached());
-
- QVector<T> v2(7);
- QCOMPARE(v2.size(), 7);
- QVERIFY(v2.isDetached());
-
- QVERIFY(!v1.isSharedWith(v2));
-
- v1 = v2;
-
- QVERIFY(!v1.isDetached());
- QVERIFY(!v2.isDetached());
- QVERIFY(v1.isSharedWith(v2));
-
- const void *const data1 = v1.constData();
- const void *const data2 = v2.constData();
-
- QCOMPARE(data1, data2);
-
- v1.clear();
-
- QVERIFY(v2.isDetached());
- QVERIFY(!v1.isSharedWith(v2));
- QCOMPARE((void *)v2.constData(), data2);
-}
-
-void tst_QVector::assignmentInt() const
-{
- testAssignment<int>();
-}
-
-void tst_QVector::assignmentMovable() const
-{
- testAssignment<Movable>();
-}
-
-void tst_QVector::assignmentCustom() const
-{
- testAssignment<Custom>();
-}
-
-template<typename T>
-void tst_QVector::assignFromInitializerList() const
-{
- T val1(SimpleValue<T>::at(1));
- T val2(SimpleValue<T>::at(2));
- T val3(SimpleValue<T>::at(3));
-
- QVector<T> v1 = {val1, val2, val3};
- QCOMPARE(v1, QVector<T>() << val1 << val2 << val3);
- QCOMPARE(v1, (QVector<T> {val1, val2, val3}));
-
- v1 = {};
- QCOMPARE(v1.size(), 0);
-}
-
-void tst_QVector::assignFromInitializerListInt() const
-{
- assignFromInitializerList<int>();
-}
-
-void tst_QVector::assignFromInitializerListMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- assignFromInitializerList<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::assignFromInitializerListCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- assignFromInitializerList<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-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.loadAcquire();
- add<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::addCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- add<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template<typename T>
-void tst_QVector::append() const
-{
- {
- 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);
-
- 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<int> v;
- v << 1 << 2 << 3;
- QVector<int> x;
- x << 4 << 5 << 6;
- v.append(x);
-
- QVector<int> combined;
- combined << 1 << 2 << 3 << 4 << 5 << 6;
-
- QCOMPARE(v, combined);
- }
-}
-
-void tst_QVector::appendInt() const
-{
- append<int>();
-}
-
-void tst_QVector::appendMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- append<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::appendCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- append<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::appendRvalue() const
-{
- QVector<QString> v;
- v.append("hello");
- QString world = "world";
- v.append(std::move(world));
- QVERIFY(world.isEmpty());
- QCOMPARE(v.front(), QString("hello"));
- QCOMPARE(v.back(), QString("world"));
-}
-
-void tst_QVector::at() const
-{
- QVector<QString> myvec;
- myvec << "foo" << "bar" << "baz";
-
- QVERIFY(myvec.size() == 3);
- QCOMPARE(myvec.at(0), QLatin1String("foo"));
- QCOMPARE(myvec.at(1), QLatin1String("bar"));
- QCOMPARE(myvec.at(2), QLatin1String("baz"));
-
- // append an item
- myvec << "hello";
- QVERIFY(myvec.size() == 4);
- QCOMPARE(myvec.at(0), QLatin1String("foo"));
- QCOMPARE(myvec.at(1), QLatin1String("bar"));
- QCOMPARE(myvec.at(2), QLatin1String("baz"));
- QCOMPARE(myvec.at(3), QLatin1String("hello"));
-
- // remove an item
- myvec.remove(1);
- QVERIFY(myvec.size() == 3);
- QCOMPARE(myvec.at(0), QLatin1String("foo"));
- QCOMPARE(myvec.at(1), QLatin1String("baz"));
- QCOMPARE(myvec.at(2), QLatin1String("hello"));
-}
-
-template<typename T>
-void tst_QVector::capacity() const
-{
- 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 << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
- QVERIFY(myvec.capacity() >= 3);
-
- // make sure it grows ok
- myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
- QVERIFY(myvec.capacity() >= 6);
- // let's try squeeze a bit
- myvec.remove(3);
- myvec.remove(3);
- myvec.remove(3);
- myvec.squeeze();
- QVERIFY(myvec.capacity() >= 3);
-
- myvec.remove(0);
- myvec.remove(0);
- myvec.remove(0);
- myvec.squeeze();
- QVERIFY(myvec.capacity() == 0);
-}
-
-void tst_QVector::capacityInt() const
-{
- capacity<int>();
-}
-
-void tst_QVector::capacityMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- capacity<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::capacityCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- capacity<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template<typename T>
-void tst_QVector::clear() const
-{
- QVector<T> myvec;
- myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
-
- const auto oldCapacity = myvec.capacity();
- QCOMPARE(myvec.size(), 3);
- myvec.clear();
- QCOMPARE(myvec.size(), 0);
- QCOMPARE(myvec.capacity(), oldCapacity);
-}
-
-void tst_QVector::clearInt() const
-{
- clear<int>();
-}
-
-void tst_QVector::clearMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- clear<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::clearCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- clear<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::constData() const
-{
- int arr[] = { 42, 43, 44 };
- QVector<int> myvec;
- myvec << 42 << 43 << 44;
-
- QVERIFY(memcmp(myvec.constData(), reinterpret_cast<const int *>(&arr), sizeof(int) * 3) == 0);
-}
-
-void tst_QVector::contains() const
-{
- QVector<QString> myvec;
- myvec << "aaa" << "bbb" << "ccc";
-
- QVERIFY(myvec.contains(QLatin1String("aaa")));
- QVERIFY(myvec.contains(QLatin1String("bbb")));
- QVERIFY(myvec.contains(QLatin1String("ccc")));
- QVERIFY(!myvec.contains(QLatin1String("I don't exist")));
-
- // add it and make sure it does :)
- myvec.append(QLatin1String("I don't exist"));
- QVERIFY(myvec.contains(QLatin1String("I don't exist")));
-}
-
-template<typename T>
-void tst_QVector::count() const
-{
- // total size
- {
- // zero size
- QVector<T> myvec;
- QVERIFY(myvec.count() == 0);
-
- // grow
- myvec.append(SimpleValue<T>::at(0));
- QVERIFY(myvec.count() == 1);
- myvec.append(SimpleValue<T>::at(1));
- QVERIFY(myvec.count() == 2);
-
- // shrink
- myvec.remove(0);
- QVERIFY(myvec.count() == 1);
- myvec.remove(0);
- QVERIFY(myvec.count() == 0);
- }
-
- // count of items
- {
- QVector<T> myvec;
- myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
-
- // initial tests
- QVERIFY(myvec.count(SimpleValue<T>::at(0)) == 1);
- QVERIFY(myvec.count(SimpleValue<T>::at(3)) == 0);
-
- // grow
- myvec.append(SimpleValue<T>::at(0));
- QVERIFY(myvec.count(SimpleValue<T>::at(0)) == 2);
-
- // shrink
- myvec.remove(0);
- 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.loadAcquire();
- count<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::countCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- count<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::cpp17ctad() const
-{
-#ifdef __cpp_deduction_guides
-#define QVERIFY_IS_VECTOR_OF(obj, Type) \
- QVERIFY2((std::is_same<decltype(obj), QVector<Type>>::value), \
- QMetaType::typeName(qMetaTypeId<decltype(obj)::value_type>()))
-#define CHECK(Type, One, Two, Three) \
- do { \
- const Type v[] = {One, Two, Three}; \
- QVector v1 = {One, Two, Three}; \
- QVERIFY_IS_VECTOR_OF(v1, Type); \
- QVector v2(v1.begin(), v1.end()); \
- QVERIFY_IS_VECTOR_OF(v2, Type); \
- QVector v3(std::begin(v), std::end(v)); \
- QVERIFY_IS_VECTOR_OF(v3, Type); \
- } while (false) \
- /*end*/
- CHECK(int, 1, 2, 3);
- CHECK(double, 1.0, 2.0, 3.0);
- CHECK(QString, QStringLiteral("one"), QStringLiteral("two"), QStringLiteral("three"));
-#undef QVERIFY_IS_VECTOR_OF
-#undef CHECK
-#else
- QSKIP("This test requires C++17 Constructor Template Argument Deduction support enabled in the compiler.");
-#endif
-}
-
-void tst_QVector::data() const
-{
- QVector<int> myvec;
- myvec << 42 << 43 << 44;
-
- // make sure it starts off ok
- QCOMPARE(*(myvec.data() + 1), 43);
-
- // alter it
- *(myvec.data() + 1) = 69;
-
- // check it altered
- QCOMPARE(*(myvec.data() + 1), 69);
-
- int arr[] = { 42, 69, 44 };
- QVERIFY(memcmp(myvec.data(), reinterpret_cast<int *>(&arr), sizeof(int) * 3) == 0);
-}
-
-template<typename T>
-void tst_QVector::empty() const
-{
- QVector<T> myvec;
-
- // starts empty
- QVERIFY(myvec.empty());
-
- // not empty
- myvec.append(SimpleValue<T>::at(2));
- QVERIFY(!myvec.empty());
-
- // empty again
- myvec.remove(0);
- QVERIFY(myvec.empty());
-}
-
-void tst_QVector::emptyInt() const
-{
- empty<int>();
-}
-
-void tst_QVector::emptyMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- empty<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::emptyCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- empty<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::endsWith() const
-{
- QVector<int> myvec;
-
- // empty vector
- QVERIFY(!myvec.endsWith(1));
-
- // add the one, should work
- myvec.append(1);
- QVERIFY(myvec.endsWith(1));
-
- // add something else, fails now
- myvec.append(3);
- QVERIFY(!myvec.endsWith(1));
-
- // remove it again :)
- myvec.remove(1);
- QVERIFY(myvec.endsWith(1));
-}
-
-template<typename T>
-void tst_QVector::eraseEmpty() const
-{
- QVector<T> v;
- 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.loadAcquire();
- eraseEmpty<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::eraseEmptyCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- eraseEmpty<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template<typename T>
-void tst_QVector::eraseEmptyReserved() const
-{
- QVector<T> v;
- v.reserve(10);
- 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.loadAcquire();
- eraseEmptyReserved<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::eraseEmptyReservedCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- eraseEmptyReserved<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template<typename T>
-struct SharedVectorChecker
-{
- SharedVectorChecker(const QVector<T> &original, bool doCopyVector)
- : originalSize(-1),
- copy(0)
- {
- if (doCopyVector) {
- originalSize = original.size();
- copy = new QVector<T>(original);
- // this is unlikely to fail, but if the check in the destructor fails it's good to know that
- // we were still alright here.
- QCOMPARE(originalSize, copy->size());
- }
- }
-
- ~SharedVectorChecker()
- {
- if (copy)
- QCOMPARE(copy->size(), originalSize);
- delete copy;
- }
-
- int originalSize;
- QVector<T> *copy;
-};
-
-template<typename T>
-void tst_QVector::erase(bool shared) const
-{
- // note: remove() is actually more efficient, and more dangerous, because it uses the non-detaching
- // begin() / end() internally. you can also use constBegin() and constEnd() with erase(), but only
- // using reinterpret_cast... because both iterator types are really just pointers.
- // so we use a mix of erase() and remove() to cover more cases.
- {
- QVector<T> v = SimpleValue<T>::vector(12);
- SharedVectorChecker<T> svc(v, shared);
- v.erase(v.begin());
- QCOMPARE(v.size(), 11);
- for (int i = 0; i < 11; i++)
- QCOMPARE(v.at(i), SimpleValue<T>::at(i + 1));
- v.erase(v.begin(), v.end());
- QCOMPARE(v.size(), 0);
- if (shared)
- QCOMPARE(SimpleValue<T>::vector(12), *svc.copy);
- }
- {
- QVector<T> v = SimpleValue<T>::vector(12);
- SharedVectorChecker<T> svc(v, shared);
- v.remove(1);
- QCOMPARE(v.size(), 11);
- QCOMPARE(v.at(0), SimpleValue<T>::at(0));
- for (int i = 1; i < 11; i++)
- QCOMPARE(v.at(i), SimpleValue<T>::at(i + 1));
- v.erase(v.begin() + 1, v.end());
- QCOMPARE(v.size(), 1);
- QCOMPARE(v.at(0), SimpleValue<T>::at(0));
- if (shared)
- QCOMPARE(SimpleValue<T>::vector(12), *svc.copy);
- }
- {
- QVector<T> v = SimpleValue<T>::vector(12);
- SharedVectorChecker<T> svc(v, shared);
- v.erase(v.begin(), v.end() - 1);
- QCOMPARE(v.size(), 1);
- QCOMPARE(v.at(0), SimpleValue<T>::at(11));
- if (shared)
- QCOMPARE(SimpleValue<T>::vector(12), *svc.copy);
- }
- {
- QVector<T> v = SimpleValue<T>::vector(12);
- SharedVectorChecker<T> svc(v, shared);
- v.remove(5);
- QCOMPARE(v.size(), 11);
- for (int i = 0; i < 5; i++)
- QCOMPARE(v.at(i), SimpleValue<T>::at(i));
- for (int i = 5; i < 11; i++)
- QCOMPARE(v.at(i), SimpleValue<T>::at(i + 1));
- v.erase(v.begin() + 1, v.end() - 1);
- QCOMPARE(v.at(0), SimpleValue<T>::at(0));
- QCOMPARE(v.at(1), SimpleValue<T>::at(11));
- QCOMPARE(v.size(), 2);
- if (shared)
- QCOMPARE(SimpleValue<T>::vector(12), *svc.copy);
- }
-}
-
-void tst_QVector::eraseInt() const
-{
- erase<int>(false);
-}
-
-void tst_QVector::eraseIntShared() const
-{
- erase<int>(true);
-}
-
-void tst_QVector::eraseMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- erase<Movable>(false);
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::eraseMovableShared() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- erase<Movable>(true);
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::eraseCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- erase<Custom>(false);
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::eraseCustomShared() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- erase<Custom>(true);
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-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);
- }
-}
-
-void tst_QVector::eraseReservedInt() const
-{
- eraseReserved<int>();
-}
-
-void tst_QVector::eraseReservedMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- eraseReserved<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::eraseReservedCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- eraseReserved<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template<typename T>
-void tst_QVector::fill() const
-{
- QVector<T> myvec;
-
- // resize
- myvec.resize(5);
- 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(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.loadAcquire();
- fill<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::fillCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- fill<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::fillDetaches() const
-{
- QVector<int> test = { 1, 2, 3 };
- QVector<int> copy = test;
- copy.fill(42);
-
- QCOMPARE(test, QVector<int>({1, 2, 3}));
- QCOMPARE(copy, QVector<int>({42, 42, 42}));
-}
-
-void tst_QVector::first() const
-{
- QVector<int> myvec;
- myvec << 69 << 42 << 3;
-
- // test it starts ok
- QCOMPARE(myvec.first(), 69);
- QCOMPARE(myvec.constFirst(), 69);
-
- // test removal changes
- myvec.remove(0);
- QCOMPARE(myvec.first(), 42);
- QCOMPARE(myvec.constFirst(), 42);
-
- // test prepend changes
- myvec.prepend(23);
- QCOMPARE(myvec.first(), 23);
- QCOMPARE(myvec.constFirst(), 23);
-}
-
-void tst_QVector::constFirst() const
-{
- QVector<int> myvec;
- myvec << 69 << 42 << 3;
-
- // test it starts ok
- QCOMPARE(myvec.constFirst(), 69);
- QVERIFY(myvec.isDetached());
-
- QVector<int> myvecCopy = myvec;
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- QCOMPARE(myvec.constFirst(), 69);
- QCOMPARE(myvecCopy.constFirst(), 69);
-
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- // test removal changes
- myvec.remove(0);
- QVERIFY(myvec.isDetached());
- QVERIFY(!myvec.isSharedWith(myvecCopy));
- QCOMPARE(myvec.constFirst(), 42);
- QCOMPARE(myvecCopy.constFirst(), 69);
-
- myvecCopy = myvec;
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- QCOMPARE(myvec.constFirst(), 42);
- QCOMPARE(myvecCopy.constFirst(), 42);
-
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- // test prepend changes
- myvec.prepend(23);
- QVERIFY(myvec.isDetached());
- QVERIFY(!myvec.isSharedWith(myvecCopy));
- QCOMPARE(myvec.constFirst(), 23);
- QCOMPARE(myvecCopy.constFirst(), 42);
-
- myvecCopy = myvec;
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- QCOMPARE(myvec.constFirst(), 23);
- QCOMPARE(myvecCopy.constFirst(), 23);
-
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-}
-
-
-template<typename T>
-void tst_QVector::fromList() const
-{
- QList<T> list;
- list << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3);
-
- QVector<T> myvec;
- myvec = QVector<T>::fromList(list);
-
- // test it worked ok
- 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.loadAcquire();
- fromList<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::fromListCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- fromList<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
-void tst_QVector::fromStdVector() const
-{
- // stl = :(
- std::vector<QString> svec;
- svec.push_back(QLatin1String("aaa"));
- svec.push_back(QLatin1String("bbb"));
- svec.push_back(QLatin1String("ninjas"));
- svec.push_back(QLatin1String("pirates"));
- QVector<QString> myvec = QVector<QString>::fromStdVector(svec);
-
- // test it converts ok
- QCOMPARE(myvec, QVector<QString>() << "aaa" << "bbb" << "ninjas" << "pirates");
-}
-#endif
-
-void tst_QVector::indexOf() const
-{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C" << "B" << "A";
-
- QVERIFY(myvec.indexOf("B") == 1);
- QVERIFY(myvec.indexOf("B", 1) == 1);
- QVERIFY(myvec.indexOf("B", 2) == 3);
- QVERIFY(myvec.indexOf("X") == -1);
- QVERIFY(myvec.indexOf("X", 2) == -1);
-
- // add an X
- myvec << "X";
- QVERIFY(myvec.indexOf("X") == 5);
- QVERIFY(myvec.indexOf("X", 5) == 5);
- QVERIFY(myvec.indexOf("X", 6) == -1);
-
- // remove first A
- myvec.remove(0);
- QVERIFY(myvec.indexOf("A") == 3);
- QVERIFY(myvec.indexOf("A", 3) == 3);
- QVERIFY(myvec.indexOf("A", 4) == -1);
-}
-
-template <typename T>
-void tst_QVector::insert() const
-{
- QVector<T> myvec;
- const T
- tA = SimpleValue<T>::at(0),
- tB = SimpleValue<T>::at(1),
- tC = SimpleValue<T>::at(2),
- tX = SimpleValue<T>::at(3),
- tZ = SimpleValue<T>::at(4),
- tT = SimpleValue<T>::at(5),
- ti = SimpleValue<T>::at(6);
- myvec << tA << tB << tC;
- QVector<T> myvec2 = myvec;
-
- // first position
- QCOMPARE(myvec.at(0), tA);
- myvec.insert(0, tX);
- QCOMPARE(myvec.at(0), tX);
- QCOMPARE(myvec.at(1), tA);
-
- QCOMPARE(myvec2.at(0), tA);
- myvec2.insert(myvec2.begin(), tX);
- QCOMPARE(myvec2.at(0), tX);
- QCOMPARE(myvec2.at(1), tA);
-
- // middle
- myvec.insert(1, tZ);
- QCOMPARE(myvec.at(0), tX);
- QCOMPARE(myvec.at(1), tZ);
- QCOMPARE(myvec.at(2), tA);
-
- myvec2.insert(myvec2.begin() + 1, tZ);
- QCOMPARE(myvec2.at(0), tX);
- QCOMPARE(myvec2.at(1), tZ);
- QCOMPARE(myvec2.at(2), tA);
-
- // end
- myvec.insert(5, tT);
- QCOMPARE(myvec.at(5), tT);
- QCOMPARE(myvec.at(4), tC);
-
- myvec2.insert(myvec2.end(), tT);
- QCOMPARE(myvec2.at(5), tT);
- QCOMPARE(myvec2.at(4), tC);
-
- // insert a lot of garbage in the middle
- myvec.insert(2, 2, ti);
- QCOMPARE(myvec, QVector<T>() << tX << tZ << ti << ti
- << tA << tB << tC << tT);
-
- myvec2.insert(myvec2.begin() + 2, 2, ti);
- QCOMPARE(myvec2, myvec);
-
- // insert from references to the same container:
- myvec.insert(0, 1, myvec[5]); // inserts tB
- myvec2.insert(0, 1, myvec2[5]); // inserts tB
- QCOMPARE(myvec, QVector<T>() << tB << tX << tZ << ti << ti
- << tA << tB << tC << tT);
- QCOMPARE(myvec2, myvec);
-
- myvec.insert(0, 1, const_cast<const QVector<T>&>(myvec)[0]); // inserts tB
- myvec2.insert(0, 1, const_cast<const QVector<T>&>(myvec2)[0]); // inserts tB
- QCOMPARE(myvec, QVector<T>() << tB << tB << tX << tZ << ti << ti
- << tA << tB << tC << tT);
- QCOMPARE(myvec2, myvec);
-}
-
-void tst_QVector::insertInt() const
-{
- insert<int>();
-}
-
-void tst_QVector::insertMovable() const
-{
- insert<Movable>();
-}
-
-void tst_QVector::insertCustom() const
-{
- insert<Custom>();
-}
-
-void tst_QVector::isEmpty() const
-{
- QVector<QString> myvec;
-
- // starts ok
- QVERIFY(myvec.isEmpty());
-
- // not empty now
- myvec.append(QLatin1String("hello there"));
- QVERIFY(!myvec.isEmpty());
-
- // empty again
- myvec.remove(0);
- QVERIFY(myvec.isEmpty());
-}
-
-void tst_QVector::last() const
-{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C";
-
- // test starts ok
- QCOMPARE(myvec.last(), QLatin1String("C"));
- QCOMPARE(myvec.constLast(), QLatin1String("C"));
-
- // test it changes ok
- myvec.append(QLatin1String("X"));
- QCOMPARE(myvec.last(), QLatin1String("X"));
- QCOMPARE(myvec.constLast(), QLatin1String("X"));
-
- // and remove again
- myvec.remove(3);
- QCOMPARE(myvec.last(), QLatin1String("C"));
- QCOMPARE(myvec.constLast(), QLatin1String("C"));
-}
-
-void tst_QVector::constLast() const
-{
- QVector<int> myvec;
- myvec << 69 << 42 << 3;
-
- // test it starts ok
- QCOMPARE(myvec.constLast(), 3);
- QVERIFY(myvec.isDetached());
-
- QVector<int> myvecCopy = myvec;
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- QCOMPARE(myvec.constLast(), 3);
- QCOMPARE(myvecCopy.constLast(), 3);
-
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- // test removal changes
- myvec.removeLast();
- QVERIFY(myvec.isDetached());
- QVERIFY(!myvec.isSharedWith(myvecCopy));
- QCOMPARE(myvec.constLast(), 42);
- QCOMPARE(myvecCopy.constLast(), 3);
-
- myvecCopy = myvec;
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- QCOMPARE(myvec.constLast(), 42);
- QCOMPARE(myvecCopy.constLast(), 42);
-
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- // test prepend changes
- myvec.append(23);
- QVERIFY(myvec.isDetached());
- QVERIFY(!myvec.isSharedWith(myvecCopy));
- QCOMPARE(myvec.constLast(), 23);
- QCOMPARE(myvecCopy.constLast(), 42);
-
- myvecCopy = myvec;
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- QCOMPARE(myvec.constLast(), 23);
- QCOMPARE(myvecCopy.constLast(), 23);
-
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-}
-
-void tst_QVector::lastIndexOf() const
-{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C" << "B" << "A";
-
- QVERIFY(myvec.lastIndexOf("B") == 3);
- QVERIFY(myvec.lastIndexOf("B", 2) == 1);
- QVERIFY(myvec.lastIndexOf("X") == -1);
- QVERIFY(myvec.lastIndexOf("X", 2) == -1);
-
- // add an X
- myvec << "X";
- QVERIFY(myvec.lastIndexOf("X") == 5);
- QVERIFY(myvec.lastIndexOf("X", 5) == 5);
- QVERIFY(myvec.lastIndexOf("X", 3) == -1);
-
- // remove first A
- myvec.remove(0);
- QVERIFY(myvec.lastIndexOf("A") == 3);
- QVERIFY(myvec.lastIndexOf("A", 3) == 3);
- QVERIFY(myvec.lastIndexOf("A", 2) == -1);
-}
-
-void tst_QVector::mid() const
-{
- QVector<QString> list;
- list << "foo" << "bar" << "baz" << "bak" << "buck" << "hello" << "kitty";
-
- QCOMPARE(list.mid(3, 3), QVector<QString>() << "bak" << "buck" << "hello");
- QCOMPARE(list.mid(6, 10), QVector<QString>() << "kitty");
- QCOMPARE(list.mid(-1, 20), list);
- QCOMPARE(list.mid(4), QVector<QString>() << "buck" << "hello" << "kitty");
-}
-
-template <typename T>
-void tst_QVector::qhash() const
-{
- QVector<T> l1, l2;
- QCOMPARE(qHash(l1), qHash(l2));
- l1 << SimpleValue<T>::at(0);
- l2 << SimpleValue<T>::at(0);
- QCOMPARE(qHash(l1), qHash(l2));
-}
-
-template <typename T>
-void tst_QVector::move() const
-{
- QVector<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- // move an item
- list.move(0, list.count() - 1);
- QCOMPARE(list, QVector<T>() << T_BAR << T_BAZ << T_FOO);
-
- // move it back
- list.move(list.count() - 1, 0);
- QCOMPARE(list, QVector<T>() << T_FOO << T_BAR << T_BAZ);
-
- // move an item in the middle
- list.move(1, 0);
- QCOMPARE(list, QVector<T>() << T_BAR << T_FOO << T_BAZ);
-}
-
-void tst_QVector::moveInt() const
-{
- move<int>();
-}
-
-void tst_QVector::moveMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- move<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::moveCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- move<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template<typename T>
-void tst_QVector::prepend() const
-{
- 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), val1);
-
- // add something
- myvec.prepend(val4);
- QCOMPARE(myvec.at(0), val4);
- QCOMPARE(myvec.at(1), val1);
- QVERIFY(myvec.size() == 4);
-
- // something else
- myvec.prepend(val5);
- QCOMPARE(myvec.at(0), val5);
- QCOMPARE(myvec.at(1), val4);
- QCOMPARE(myvec.at(2), val1);
- QVERIFY(myvec.size() == 5);
-
- // clear and prepend to an empty vector
- myvec.clear();
- QVERIFY(myvec.size() == 0);
- myvec.prepend(val5);
- QVERIFY(myvec.size() == 1);
- QCOMPARE(myvec.at(0), val5);
-}
-
-void tst_QVector::prependInt() const
-{
- prepend<int>();
-}
-
-void tst_QVector::prependMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- prepend<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::prependCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- prepend<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::removeAllWithAlias() const
-{
- QVector<QString> strings;
- strings << "One" << "Two" << "Three" << "One" /* must be distinct, but equal */;
- QCOMPARE(strings.removeAll(strings.front()), 2); // will trigger asan/ubsan
-}
-
-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);
- T val4 = SimpleValue<T>::at(4);
- myvec << val1 << val2 << val3;
- myvec << val1 << val2 << val3;
- myvec << val1 << val2 << val3;
- // remove middle
- myvec.remove(1);
- QCOMPARE(myvec, QVector<T>() << val1 << val3 << val1 << val2 << val3 << val1 << val2 << val3);
-
- // removeOne()
- QVERIFY(!myvec.removeOne(val4));
- QVERIFY(myvec.removeOne(val2));
- QCOMPARE(myvec, QVector<T>() << val1 << val3 << val1 << val3 << val1 << val2 << val3);
-
- QVector<T> myvecCopy = myvec;
- QVERIFY(myvecCopy.isSharedWith(myvec));
- // removeAll()
- QCOMPARE(myvec.removeAll(val4), 0);
- QVERIFY(myvecCopy.isSharedWith(myvec));
- QCOMPARE(myvec.removeAll(val1), 3);
- QVERIFY(!myvecCopy.isSharedWith(myvec));
- QCOMPARE(myvec, QVector<T>() << val3 << val3 << val2 << val3);
- myvecCopy = myvec;
- QVERIFY(myvecCopy.isSharedWith(myvec));
- QCOMPARE(myvec.removeAll(val2), 1);
- QVERIFY(!myvecCopy.isSharedWith(myvec));
- QCOMPARE(myvec, QVector<T>() << val3 << val3 << val3);
-
- // remove rest
- myvec.remove(0, 3);
- QCOMPARE(myvec, QVector<T>());
-}
-
-void tst_QVector::removeInt() const
-{
- remove<int>();
-}
-
-void tst_QVector::removeMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- remove<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::removeCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- remove<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-struct RemoveLastTestClass
-{
- RemoveLastTestClass() { other = 0; deleted = false; }
- RemoveLastTestClass *other;
- bool deleted;
- ~RemoveLastTestClass()
- {
- deleted = true;
- if (other)
- other->other = 0;
- }
-};
-
-void tst_QVector::removeFirstLast() const
-{
- // pop_pack - pop_front
- QVector<int> t, t2;
- t.append(1);
- t.append(2);
- t.append(3);
- t.append(4);
- t2 = t;
- t.pop_front();
- QCOMPARE(t.size(), 3);
- QCOMPARE(t.at(0), 2);
- t.pop_back();
- QCOMPARE(t.size(), 2);
- QCOMPARE(t.at(0), 2);
- QCOMPARE(t.at(1), 3);
-
- // takefirst - takeLast
- int n1 = t2.takeLast();
- QCOMPARE(t2.size(), 3);
- QCOMPARE(n1, 4);
- QCOMPARE(t2.at(0), 1);
- QCOMPARE(t2.at(2), 3);
- n1 = t2.takeFirst();
- QCOMPARE(t2.size(), 2);
- QCOMPARE(n1, 1);
- QCOMPARE(t2.at(0), 2);
- QCOMPARE(t2.at(1), 3);
-
- // remove first
- QVector<int> x, y;
- x.append(1);
- x.append(2);
- y = x;
- x.removeFirst();
- QCOMPARE(x.size(), 1);
- QCOMPARE(y.size(), 2);
- QCOMPARE(x.at(0), 2);
-
- // remove Last
- QVector<RemoveLastTestClass> v;
- v.resize(2);
- v[0].other = &(v[1]);
- v[1].other = &(v[0]);
- // Check dtor - complex type
- QVERIFY(v.at(0).other != 0);
- v.removeLast();
- QVERIFY(v.at(0).other == 0);
- QCOMPARE(v.at(0).deleted, false);
- // check iterator
- int count = 0;
- for (QVector<RemoveLastTestClass>::const_iterator i = v.constBegin(); i != v.constEnd(); ++i) {
- ++count;
- QVERIFY(i->other == 0);
- QCOMPARE(i->deleted, false);
- }
- // Check size
- QCOMPARE(count, 1);
- QCOMPARE(v.size(), 1);
- v.removeLast();
- QCOMPARE(v.size(), 0);
- // Check if we do correct realloc
- QVector<int> v2, v3;
- v2.append(1);
- v2.append(2);
- v3 = v2; // shared
- v2.removeLast();
- QCOMPARE(v2.size(), 1);
- QCOMPARE(v3.size(), 2);
- QCOMPARE(v2.at(0), 1);
- QCOMPARE(v3.at(0), 1);
- QCOMPARE(v3.at(1), 2);
-
- // Remove last with shared
- QVector<int> z1, z2;
- z1.append(9);
- z2 = z1;
- z1.removeLast();
- QCOMPARE(z1.size(), 0);
- QCOMPARE(z2.size(), 1);
- QCOMPARE(z2.at(0), 9);
-}
-
-
-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);
-
- 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;
-}
-
-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.clear();
- 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);
-
- 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;
-}
-
-void tst_QVector::resizeComplexMovable() const
-{
- const int items = Movable::counter.loadAcquire();
- {
- QFETCH(QVector<Movable>, 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] == 'j'); // check initialization
-
- const int capacity = vector.capacity();
-
- vector.resize(0);
- QCOMPARE(vector.size(), 0);
- QVERIFY(vector.capacity() <= capacity);
- }
- QCOMPARE(items, Movable::counter.loadAcquire());
-}
-
-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);
-
- 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;
-}
-
-void tst_QVector::resizeComplex() const
-{
- const int items = Custom::counter.loadAcquire();
- {
- 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.loadAcquire(), items);
-}
-
-void tst_QVector::resizeCtorAndDtor() const
-{
- const int items = Custom::counter.loadAcquire();
- {
- 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.loadAcquire(), items);
-}
-
-void tst_QVector::reverseIterators() const
-{
- QVector<int> v;
- v << 1 << 2 << 3 << 4;
- QVector<int> vr = v;
- std::reverse(vr.begin(), vr.end());
- const QVector<int> &cvr = vr;
- QVERIFY(std::equal(v.begin(), v.end(), vr.rbegin()));
- QVERIFY(std::equal(v.begin(), v.end(), vr.crbegin()));
- QVERIFY(std::equal(v.begin(), v.end(), cvr.rbegin()));
- QVERIFY(std::equal(vr.rbegin(), vr.rend(), v.begin()));
- QVERIFY(std::equal(vr.crbegin(), vr.crend(), v.begin()));
- QVERIFY(std::equal(cvr.rbegin(), cvr.rend(), v.begin()));
-}
-
-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.loadAcquire();
- size<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::sizeCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- size<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-// ::squeeze() is tested in ::capacity().
-
-void tst_QVector::startsWith() const
-{
- QVector<int> myvec;
-
- // empty vector
- QVERIFY(!myvec.startsWith(1));
-
- // add the one, should work
- myvec.prepend(1);
- QVERIFY(myvec.startsWith(1));
-
- // add something else, fails now
- myvec.prepend(3);
- QVERIFY(!myvec.startsWith(1));
-
- // remove it again :)
- myvec.remove(0);
- QVERIFY(myvec.startsWith(1));
-}
-
-template<typename T>
-void tst_QVector::swap() const
-{
- 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<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.loadAcquire();
- swap<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::swapCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- swap<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::toList() const
-{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C";
-
- // make sure it converts and doesn't modify the original vector
- QCOMPARE(myvec.toList(), QList<QString>() << "A" << "B" << "C");
- QCOMPARE(myvec, QVector<QString>() << "A" << "B" << "C");
-}
-
-#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
-void tst_QVector::toStdVector() const
-{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C";
-
- std::vector<QString> svec = myvec.toStdVector();
- QCOMPARE(svec.at(0), QLatin1String("A"));
- QCOMPARE(svec.at(1), QLatin1String("B"));
- QCOMPARE(svec.at(2), QLatin1String("C"));
-
- QCOMPARE(myvec, QVector<QString>() << "A" << "B" << "C");
-}
-#endif
-
-void tst_QVector::value() const
-{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C";
-
- // valid calls
- QCOMPARE(myvec.value(0), QLatin1String("A"));
- QCOMPARE(myvec.value(1), QLatin1String("B"));
- QCOMPARE(myvec.value(2), QLatin1String("C"));
-
- // default calls
- QCOMPARE(myvec.value(-1), QString());
- QCOMPARE(myvec.value(3), QString());
-
- // test calls with a provided default, valid calls
- QCOMPARE(myvec.value(0, QLatin1String("default")), QLatin1String("A"));
- QCOMPARE(myvec.value(1, QLatin1String("default")), QLatin1String("B"));
- QCOMPARE(myvec.value(2, QLatin1String("default")), QLatin1String("C"));
-
- // test calls with a provided default that will return the default
- QCOMPARE(myvec.value(-1, QLatin1String("default")), QLatin1String("default"));
- QCOMPARE(myvec.value(3, QLatin1String("default")), QLatin1String("default"));
-}
-
-void tst_QVector::testOperators() const
-{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C";
- QVector<QString> myvectwo;
- myvectwo << "D" << "E" << "F";
- QVector<QString> combined;
- combined << "A" << "B" << "C" << "D" << "E" << "F";
-
- // !=
- QVERIFY(myvec != myvectwo);
-
- // +
- QCOMPARE(myvec + myvectwo, combined);
- QCOMPARE(myvec, QVector<QString>() << "A" << "B" << "C");
- QCOMPARE(myvectwo, QVector<QString>() << "D" << "E" << "F");
-
- // +=
- myvec += myvectwo;
- QCOMPARE(myvec, combined);
-
- // ==
- QVERIFY(myvec == combined);
-
- // <, >, <=, >=
- QVERIFY(!(myvec < combined));
- QVERIFY(!(myvec > combined));
- QVERIFY( myvec <= combined);
- QVERIFY( myvec >= combined);
- combined.push_back("G");
- QVERIFY( myvec < combined);
- QVERIFY(!(myvec > combined));
- QVERIFY( myvec <= combined);
- QVERIFY(!(myvec >= combined));
- QVERIFY(combined > myvec);
- QVERIFY(combined >= myvec);
-
- // []
- QCOMPARE(myvec[0], QLatin1String("A"));
- QCOMPARE(myvec[1], QLatin1String("B"));
- QCOMPARE(myvec[2], QLatin1String("C"));
- QCOMPARE(myvec[3], QLatin1String("D"));
- QCOMPARE(myvec[4], QLatin1String("E"));
- QCOMPARE(myvec[5], QLatin1String("F"));
-}
-
-
-int fooCtor;
-int fooDtor;
-
-struct Foo
-{
- int *p;
-
- Foo() { p = new int; ++fooCtor; }
- Foo(const Foo &other) { Q_UNUSED(other); p = new int; ++fooCtor; }
-
- void operator=(const Foo & /* other */) { }
-
- ~Foo() { delete p; ++fooDtor; }
-};
-
-void tst_QVector::reserve()
-{
- fooCtor = 0;
- fooDtor = 0;
- {
- QVector<Foo> a;
- a.resize(2);
- QCOMPARE(fooCtor, 2);
- QVector<Foo> b(a);
- b.reserve(1);
- QCOMPARE(b.size(), a.size());
- QCOMPARE(fooDtor, 0);
- }
- QCOMPARE(fooCtor, fooDtor);
-}
-
-// This is a regression test for QTBUG-51758
-void tst_QVector::reserveZero()
-{
- QVector<int> vec;
- vec.detach();
- vec.reserve(0); // should not crash
- QCOMPARE(vec.size(), 0);
- QCOMPARE(vec.capacity(), 0);
- vec.squeeze();
- QCOMPARE(vec.size(), 0);
- QCOMPARE(vec.capacity(), 0);
- vec.reserve(-1);
- QCOMPARE(vec.size(), 0);
- QCOMPARE(vec.capacity(), 0);
- vec.append(42);
- QCOMPARE(vec.size(), 1);
- QVERIFY(vec.capacity() >= 1);
-}
-
-template<typename T>
-void tst_QVector::initializeList()
-{
- 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);
-
- QVector<T> v4({});
- QCOMPARE(v4.size(), 0);
-}
-
-void tst_QVector::initializeListInt()
-{
- initializeList<int>();
-}
-
-void tst_QVector::initializeListMovable()
-{
- const int instancesCount = Movable::counter.loadAcquire();
- initializeList<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::initializeListCustom()
-{
- const int instancesCount = Custom::counter.loadAcquire();
- initializeList<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::const_shared_null()
-{
- QVector<int> v2;
- QVERIFY(!v2.isDetached());
-}
-
-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.loadAcquire();
- detach<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::detachCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- detach<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-static QAtomicPointer<QVector<int> > detachThreadSafetyDataInt;
-static QAtomicPointer<QVector<Movable> > detachThreadSafetyDataMovable;
-static QAtomicPointer<QVector<Custom> > detachThreadSafetyDataCustom;
-
-template<typename T> QAtomicPointer<QVector<T> > *detachThreadSafetyData();
-template<> QAtomicPointer<QVector<int> > *detachThreadSafetyData() { return &detachThreadSafetyDataInt; }
-template<> QAtomicPointer<QVector<Movable> > *detachThreadSafetyData() { return &detachThreadSafetyDataMovable; }
-template<> QAtomicPointer<QVector<Custom> > *detachThreadSafetyData() { return &detachThreadSafetyDataCustom; }
-
-static QSemaphore detachThreadSafetyLock;
-
-template<typename T>
-void tst_QVector::detachThreadSafety() const
-{
- delete detachThreadSafetyData<T>()->fetchAndStoreOrdered(new QVector<T>(SimpleValue<T>::vector(400)));
-
- static const uint threadsCount = 5;
-
- struct : QThread {
- void run() override
- {
- QVector<T> copy(*detachThreadSafetyData<T>()->loadRelaxed());
- QVERIFY(!copy.isDetached());
- detachThreadSafetyLock.release();
- detachThreadSafetyLock.acquire(100);
- copy.detach();
- }
- } threads[threadsCount];
-
- for (uint i = 0; i < threadsCount; ++i)
- threads[i].start();
- QThread::yieldCurrentThread();
- detachThreadSafetyLock.acquire(threadsCount);
-
- // destroy static original data
- delete detachThreadSafetyData<T>()->fetchAndStoreOrdered(0);
-
- QVERIFY(threadsCount < 100);
- detachThreadSafetyLock.release(threadsCount * 100);
- QThread::yieldCurrentThread();
-
- for (uint i = 0; i < threadsCount; ++i)
- threads[i].wait();
-}
-
-void tst_QVector::detachThreadSafetyInt() const
-{
- for (uint i = 0; i < 128; ++i)
- detachThreadSafety<int>();
-}
-
-void tst_QVector::detachThreadSafetyMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- for (uint i = 0; i < 128; ++i) {
- detachThreadSafety<Movable>();
- QCOMPARE(Movable::counter.loadAcquire(), instancesCount);
- }
-}
-
-void tst_QVector::detachThreadSafetyCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- for (uint i = 0; i < 128; ++i) {
- detachThreadSafety<Custom>();
- QCOMPARE(Custom::counter.loadAcquire(), instancesCount);
- }
-}
-
-void tst_QVector::insertMove() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- {
- QVector<Movable> vec;
- vec.reserve(7);
- Movable m0;
- Movable m1;
- Movable m2;
- Movable m3;
- Movable m4;
- Movable m5;
- Movable m6;
-
- vec.append(std::move(m3));
- QVERIFY(m3.wasConstructedAt(nullptr));
- QVERIFY(vec.at(0).wasConstructedAt(&m3));
- vec.push_back(std::move(m4));
- QVERIFY(m4.wasConstructedAt(nullptr));
- QVERIFY(vec.at(0).wasConstructedAt(&m3));
- QVERIFY(vec.at(1).wasConstructedAt(&m4));
- vec.prepend(std::move(m1));
- QVERIFY(m1.wasConstructedAt(nullptr));
- QVERIFY(vec.at(0).wasConstructedAt(&m1));
- QVERIFY(vec.at(1).wasConstructedAt(&m3));
- QVERIFY(vec.at(2).wasConstructedAt(&m4));
- vec.insert(1, std::move(m2));
- QVERIFY(m2.wasConstructedAt(nullptr));
- QVERIFY(vec.at(0).wasConstructedAt(&m1));
- QVERIFY(vec.at(1).wasConstructedAt(&m2));
- QVERIFY(vec.at(2).wasConstructedAt(&m3));
- QVERIFY(vec.at(3).wasConstructedAt(&m4));
- vec += std::move(m5);
- QVERIFY(m5.wasConstructedAt(nullptr));
- QVERIFY(vec.at(0).wasConstructedAt(&m1));
- QVERIFY(vec.at(1).wasConstructedAt(&m2));
- QVERIFY(vec.at(2).wasConstructedAt(&m3));
- QVERIFY(vec.at(3).wasConstructedAt(&m4));
- QVERIFY(vec.at(4).wasConstructedAt(&m5));
- vec << std::move(m6);
- QVERIFY(m6.wasConstructedAt(nullptr));
- QVERIFY(vec.at(0).wasConstructedAt(&m1));
- QVERIFY(vec.at(1).wasConstructedAt(&m2));
- QVERIFY(vec.at(2).wasConstructedAt(&m3));
- QVERIFY(vec.at(3).wasConstructedAt(&m4));
- QVERIFY(vec.at(4).wasConstructedAt(&m5));
- QVERIFY(vec.at(5).wasConstructedAt(&m6));
- vec.push_front(std::move(m0));
- QVERIFY(m0.wasConstructedAt(nullptr));
- QVERIFY(vec.at(0).wasConstructedAt(&m0));
- QVERIFY(vec.at(1).wasConstructedAt(&m1));
- QVERIFY(vec.at(2).wasConstructedAt(&m2));
- QVERIFY(vec.at(3).wasConstructedAt(&m3));
- QVERIFY(vec.at(4).wasConstructedAt(&m4));
- QVERIFY(vec.at(5).wasConstructedAt(&m5));
- QVERIFY(vec.at(6).wasConstructedAt(&m6));
-
- QCOMPARE(Movable::counter.loadAcquire(), instancesCount + 14);
- }
- QCOMPARE(Movable::counter.loadAcquire(), instancesCount);
-}
-
-void tst_QVector::swapItemsAt() const
-{
- QVector<int> v;
- v << 0 << 1 << 2 << 3;
-
- v.swapItemsAt(0, 2);
- QCOMPARE(v.at(0), 2);
- QCOMPARE(v.at(2), 0);
-
- auto copy = v;
- copy.swapItemsAt(0, 2);
- QCOMPARE(v.at(0), 2);
- QCOMPARE(v.at(2), 0);
- QCOMPARE(copy.at(0), 0);
- QCOMPARE(copy.at(2), 2);
-}
-
-void tst_QVector::emplaceInt()
-{
- emplaceImpl<int>();
-}
-
-void tst_QVector::emplaceCustom()
-{
- emplaceImpl<Custom>();
-}
-
-void tst_QVector::emplaceMovable()
-{
- emplaceImpl<Movable>();
-}
-
-void tst_QVector::emplaceConsistentWithStdVectorInt()
-{
- emplaceConsistentWithStdVectorImpl<int>();
-}
-
-void tst_QVector::emplaceConsistentWithStdVectorCustom()
-{
- emplaceConsistentWithStdVectorImpl<Custom>();
-}
-
-void tst_QVector::emplaceConsistentWithStdVectorMovable()
-{
- emplaceConsistentWithStdVectorImpl<Movable>();
-}
-
-void tst_QVector::emplaceReturnsIterator()
-{
- QVector<Movable> vec;
-
- vec.emplace(0, 'k')->i = 'p';
-
- QCOMPARE(vec[0].i, 'p');
-}
-
-void tst_QVector::emplaceBack()
-{
- QScopedValueRollback<QAtomicInt> rollback(Movable::counter, 0);
-
- QVector<Movable> vec;
-
- vec.emplaceBack('k');
-
- QCOMPARE(Movable::counter, 1);
-}
-
-void tst_QVector::emplaceBackReturnsRef()
-{
- QVector<Movable> vec;
-
- vec.emplaceBack('k').i = 'p';
-
- QCOMPARE(vec.at(0).i, 'p');
-}
-
-void tst_QVector::emplaceWithElementFromTheSameContainer()
-{
- QFETCH(int, elementPos);
- QFETCH(int, insertPos);
- QFETCH(bool, doCopy);
-
- QVector<QString> vec {"a", "b", "c", "d", "e"};
- const QString e = vec[elementPos];
-
- if (doCopy)
- vec.emplace(insertPos, vec[elementPos]);
- else
- vec.emplace(insertPos, std::move(vec[elementPos]));
-
- QCOMPARE(vec[insertPos], e);
-}
-
-void tst_QVector::emplaceWithElementFromTheSameContainer_data()
-{
- QTest::addColumn<int>("elementPos");
- QTest::addColumn<int>("insertPos");
- QTest::addColumn<bool>("doCopy");
-
- for (int i = 0; i < 2; ++i) {
- const bool doCopy = i == 0;
- const char *opName = doCopy ? "copy" : "move";
-
- QTest::addRow("%s: begin -> end" , opName) << 0 << 5 << doCopy;
- QTest::addRow("%s: begin -> middle", opName) << 0 << 2 << doCopy;
- QTest::addRow("%s: middle -> begin" , opName) << 2 << 0 << doCopy;
- QTest::addRow("%s: middle -> end" , opName) << 2 << 5 << doCopy;
- QTest::addRow("%s: end -> middle", opName) << 4 << 2 << doCopy;
- QTest::addRow("%s: end -> begin" , opName) << 4 << 0 << doCopy;
- }
-}
-
-template<typename T>
-void tst_QVector::emplaceImpl() const
-{
- QVector<T> vec {'a', 'b', 'c', 'd'};
-
- vec.emplace(2, 'k');
-
- QCOMPARE(vec[2], T('k'));
-}
-
-template <class T>
-static void vecEq(const QVector<T> &qVec, const std::vector<T> &stdVec)
-{
- QCOMPARE(std::size_t(qVec.size()), stdVec.size());
- QVERIFY(std::equal(qVec.begin(), qVec.end(), stdVec.begin(), stdVec.end()));
-}
-
-template <class T>
-static void squeezeVec(QVector<T> &qVec, std::vector<T> &stdVec)
-{
- qVec.squeeze();
- stdVec.shrink_to_fit();
-}
-
-template<typename T>
-void tst_QVector::emplaceConsistentWithStdVectorImpl() const
-{
- QVector<T> qVec {'a', 'b', 'c', 'd', 'e'};
- std::vector<T> stdVec {'a', 'b', 'c', 'd', 'e'};
- vecEq(qVec, stdVec);
-
- qVec.emplaceBack('f');
- stdVec.emplace_back('f');
- vecEq(qVec, stdVec);
-
- qVec.emplace(3, 'g');
- stdVec.emplace(stdVec.begin() + 3, 'g');
- vecEq(qVec, stdVec);
-
- T t;
- // while QVector is safe with regards to emplacing elements moved form itself, it's UB
- // for std::vector, so do the moving in two steps there.
- qVec.emplaceBack(std::move(qVec[0]));
- stdVec.emplace_back(std::move(t = std::move(stdVec[0])));
- vecEq(qVec, stdVec);
-
- squeezeVec(qVec, stdVec);
-
- qVec.emplaceBack(std::move(qVec[1]));
- stdVec.emplace_back(std::move(t = std::move(stdVec[1])));
- vecEq(qVec, stdVec);
-
- squeezeVec(qVec, stdVec);
-
- qVec.emplace(3, std::move(qVec[5]));
- stdVec.emplace(stdVec.begin() + 3, std::move(t = std::move(stdVec[5])));
-
- vecEq(qVec, stdVec);
-
- qVec.emplaceBack(qVec[3]);
- stdVec.emplace_back((t = stdVec[3]));
- vecEq(qVec, stdVec);
-
- squeezeVec(qVec, stdVec);
-
- qVec.emplaceBack(qVec[4]);
- stdVec.emplace_back((t = stdVec[4]));
- vecEq(qVec, stdVec);
-
- squeezeVec(qVec, stdVec);
-
- qVec.emplace(5, qVec[7]);
- stdVec.emplace(stdVec.begin() + 5, (t = stdVec[7]));
- vecEq(qVec, stdVec);
-}
-
-QTEST_MAIN(tst_QVector)
-#include "tst_qvector.moc"