| /**************************************************************************** |
| ** |
| ** 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 <QLinkedList> |
| |
| #if QT_DEPRECATED_SINCE(5, 15) |
| QT_WARNING_PUSH |
| QT_WARNING_DISABLE_DEPRECATED |
| |
| struct Movable |
| { |
| Movable(char input = 'j') : i(input), state(Constructed) |
| { |
| ++liveCount; |
| } |
| Movable(const Movable &other) |
| : i(other.i) |
| , state(Constructed) |
| { |
| check(other.state, Constructed); |
| ++liveCount; |
| } |
| |
| ~Movable() |
| { |
| check(state, Constructed); |
| i = 0; |
| --liveCount; |
| 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 getLiveCount() { return liveCount; } |
| private: |
| static int liveCount; |
| |
| enum State { Constructed = 106, Destructed = 110 }; |
| State state; |
| |
| static void check(const State state1, const State state2) |
| { |
| QCOMPARE(int(state1), int(state2)); |
| } |
| }; |
| |
| int Movable::liveCount = 0; |
| |
| QT_BEGIN_NAMESPACE |
| Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE); |
| QT_END_NAMESPACE |
| |
| Q_DECLARE_METATYPE(Movable); |
| |
| Q_DECLARE_METATYPE(QLinkedList<int>); |
| |
| |
| int qHash(const Movable& movable) |
| { |
| return qHash(movable.i); |
| } |
| |
| struct Complex |
| { |
| Complex(int val = 0) |
| : value(val) |
| , checkSum(this) |
| { |
| ++liveCount; |
| } |
| |
| Complex(Complex const &other) |
| : value(other.value) |
| , checkSum(this) |
| { |
| ++liveCount; |
| } |
| |
| Complex &operator=(Complex const &other) |
| { |
| check(); other.check(); |
| |
| value = other.value; |
| return *this; |
| } |
| |
| ~Complex() |
| { |
| --liveCount; |
| check(); |
| } |
| |
| operator int() const { return value; } |
| |
| bool operator==(Complex const &other) const |
| { |
| check(); other.check(); |
| return value == other.value; |
| } |
| |
| void check() const |
| { |
| QVERIFY(this == checkSum); |
| } |
| |
| static int getLiveCount() { return liveCount; } |
| private: |
| static int liveCount; |
| |
| int value; |
| void *checkSum; |
| }; |
| |
| int Complex::liveCount = 0; |
| |
| Q_DECLARE_METATYPE(Complex); |
| |
| // Tests depend 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<Complex>::isStatic); |
| Q_STATIC_ASSERT(QTypeInfo<Complex>::isComplex); |
| |
| class tst_QLinkedList : public QObject |
| { |
| Q_OBJECT |
| private slots: |
| void eraseValidIteratorsOnSharedList() const; |
| void insertWithIteratorsOnSharedList() const; |
| void lengthInt() const; |
| void lengthMovable() const; |
| void lengthComplex() const; |
| void lengthSignature() const; |
| void firstInt() const; |
| void firstMovable() const; |
| void firstComplex() const; |
| void lastInt() const; |
| void lastMovable() const; |
| void lastComplex() const; |
| void beginInt() const; |
| void beginMovable() const; |
| void beginComplex() const; |
| void endInt() const; |
| void endMovable() const; |
| void endComplex() const; |
| void containsInt() const; |
| void containsMovable() const; |
| void containsComplex() const; |
| void countInt() const; |
| void countMovable() const; |
| void countComplex() const; |
| void cpp17ctad() const; |
| void emptyInt() const; |
| void emptyMovable() const; |
| void emptyComplex() const; |
| void endsWithInt() const; |
| void endsWithMovable() const; |
| void endsWithComplex() const; |
| void removeAllInt() const; |
| void removeAllMovable() const; |
| void removeAllComplex() const; |
| void removeOneInt() const; |
| void removeOneMovable() const; |
| void removeOneComplex() const; |
| void reverseIterators() const; |
| void startsWithInt() const; |
| void startsWithMovable() const; |
| void startsWithComplex() const; |
| void takeFirstInt() const; |
| void takeFirstMovable() const; |
| void takeFirstComplex() const; |
| void takeLastInt() const; |
| void takeLastMovable() const; |
| void takeLastComplex() const; |
| void toStdListInt() const; |
| void toStdListMovable() const; |
| void toStdListComplex() const; |
| void testOperatorsInt() const; |
| void testOperatorsMovable() const; |
| void testOperatorsComplex() const; |
| void testSTLIteratorsInt() const; |
| void testSTLIteratorsMovable() const; |
| void testSTLIteratorsComplex() const; |
| |
| void initializeList() const; |
| |
| void constSharedNullInt() const; |
| void constSharedNullMovable() const; |
| void constSharedNullComplex() const; |
| |
| void setSharableInt() const; |
| private: |
| template<typename T> void length() const; |
| template<typename T> void first() const; |
| template<typename T> void last() const; |
| template<typename T> void begin() const; |
| template<typename T> void end() const; |
| template<typename T> void contains() const; |
| template<typename T> void count() const; |
| template<typename T> void empty() const; |
| template<typename T> void endsWith() const; |
| template<typename T> void move() const; |
| template<typename T> void removeAll() const; |
| template<typename T> void removeOne() const; |
| template<typename T> void startsWith() const; |
| template<typename T> void swap() const; |
| template<typename T> void takeFirst() const; |
| template<typename T> void takeLast() const; |
| template<typename T> void toStdList() const; |
| template<typename T> void value() const; |
| |
| template<typename T> void testOperators() const; |
| template<typename T> void testSTLIterators() const; |
| |
| template<typename T> void constSharedNull() const; |
| |
| int dummyForGuard; |
| }; |
| |
| template<typename T> struct SimpleValue |
| { |
| static T at(int index) |
| { |
| return values[index % maxSize]; |
| } |
| static const uint maxSize = 7; |
| static const T values[maxSize]; |
| }; |
| |
| template<> |
| const int SimpleValue<int>::values[] = { 10, 20, 30, 40, 100, 101, 102 }; |
| template<> |
| const Movable SimpleValue<Movable>::values[] = { 10, 20, 30, 40, 100, 101, 102 }; |
| template<> |
| const Complex SimpleValue<Complex>::values[] = { 10, 20, 30, 40, 100, 101, 102 }; |
| |
| // 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) |
| #define T_WEEE SimpleValue<T>::at(6) |
| |
| template<typename T> |
| void tst_QLinkedList::length() const |
| { |
| /* Empty list. */ |
| { |
| const QLinkedList<T> list; |
| QCOMPARE(list.size(), 0); |
| } |
| |
| /* One entry. */ |
| { |
| QLinkedList<T> list; |
| list.append(T_FOO); |
| QCOMPARE(list.size(), 1); |
| } |
| |
| /* Two entries. */ |
| { |
| QLinkedList<T> list; |
| list.append(T_FOO); |
| list.append(T_BAR); |
| QCOMPARE(list.size(), 2); |
| } |
| |
| /* Three entries. */ |
| { |
| QLinkedList<T> list; |
| list.append(T_FOO); |
| list.append(T_BAR); |
| list.append(T_BAZ); |
| QCOMPARE(list.size(), 3); |
| } |
| } |
| |
| void tst_QLinkedList::eraseValidIteratorsOnSharedList() const |
| { |
| QLinkedList<int> a, b; |
| a.append(5); |
| a.append(10); |
| a.append(20); |
| a.append(20); |
| a.append(20); |
| a.append(20); |
| a.append(30); |
| |
| QLinkedList<int>::iterator i = a.begin(); |
| ++i; |
| ++i; |
| ++i; |
| b = a; |
| QLinkedList<int>::iterator r = a.erase(i); |
| QCOMPARE(b.size(), 7); |
| QCOMPARE(a.size(), 6); |
| --r; |
| --r; |
| QCOMPARE(*r, 10); // Ensure that number 2 instance was removed; |
| } |
| |
| void tst_QLinkedList::insertWithIteratorsOnSharedList() const |
| { |
| QLinkedList<int> a, b; |
| a.append(5); |
| a.append(10); |
| a.append(20); |
| QLinkedList<int>::iterator i = a.begin(); |
| ++i; |
| ++i; |
| b = a; |
| |
| QLinkedList<int>::iterator i2 = a.insert(i, 15); |
| QCOMPARE(b.size(), 3); |
| QCOMPARE(a.size(), 4); |
| --i2; |
| QCOMPARE(*i2, 10); |
| } |
| |
| void tst_QLinkedList::lengthInt() const |
| { |
| length<int>(); |
| } |
| |
| void tst_QLinkedList::lengthMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| length<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::lengthComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| length<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::lengthSignature() const |
| { |
| /* Constness. */ |
| { |
| const QLinkedList<int> list; |
| /* The function should be const. */ |
| list.size(); |
| } |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::first() const |
| { |
| QLinkedList<T> list; |
| list << T_FOO << T_BAR; |
| |
| QCOMPARE(list.first(), T_FOO); |
| |
| // remove an item, make sure it still works |
| list.pop_front(); |
| QVERIFY(list.size() == 1); |
| QCOMPARE(list.first(), T_BAR); |
| } |
| |
| void tst_QLinkedList::firstInt() const |
| { |
| first<int>(); |
| } |
| |
| void tst_QLinkedList::firstMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| first<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::firstComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| first<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::last() const |
| { |
| QLinkedList<T> list; |
| list << T_FOO << T_BAR; |
| |
| QCOMPARE(list.last(), T_BAR); |
| |
| // remove an item, make sure it still works |
| list.pop_back(); |
| QVERIFY(list.size() == 1); |
| QCOMPARE(list.last(), T_FOO); |
| } |
| |
| void tst_QLinkedList::lastInt() const |
| { |
| last<int>(); |
| } |
| |
| void tst_QLinkedList::lastMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| last<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::lastComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| last<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::begin() const |
| { |
| QLinkedList<T> list; |
| list << T_FOO << T_BAR; |
| |
| QCOMPARE(*list.begin(), T_FOO); |
| |
| // remove an item, make sure it still works |
| list.pop_front(); |
| QVERIFY(list.size() == 1); |
| QCOMPARE(*list.begin(), T_BAR); |
| } |
| |
| void tst_QLinkedList::beginInt() const |
| { |
| begin<int>(); |
| } |
| |
| void tst_QLinkedList::beginMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| begin<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::beginComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| begin<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::end() const |
| { |
| QLinkedList<T> list; |
| list << T_FOO << T_BAR; |
| |
| QCOMPARE(*--list.end(), T_BAR); |
| |
| // remove an item, make sure it still works |
| list.pop_back(); |
| QVERIFY(list.size() == 1); |
| QCOMPARE(*--list.end(), T_FOO); |
| } |
| |
| void tst_QLinkedList::endInt() const |
| { |
| end<int>(); |
| } |
| |
| void tst_QLinkedList::endMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| end<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::endComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| end<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::contains() const |
| { |
| QLinkedList<T> list; |
| list << T_FOO << T_BAR << T_BAZ; |
| |
| QVERIFY(list.contains(T_FOO)); |
| QVERIFY(list.contains(T_BLAH) != true); |
| |
| // add it and make sure it matches |
| list.append(T_BLAH); |
| QVERIFY(list.contains(T_BLAH)); |
| } |
| |
| void tst_QLinkedList::containsInt() const |
| { |
| contains<int>(); |
| } |
| |
| void tst_QLinkedList::containsMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| contains<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::containsComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| contains<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::count() const |
| { |
| QLinkedList<T> list; |
| |
| // starts empty |
| QVERIFY(list.count() == 0); |
| |
| // goes up |
| list.append(T_FOO); |
| QVERIFY(list.count() == 1); |
| |
| // and up |
| list.append(T_BAR); |
| QVERIFY(list.count() == 2); |
| |
| // and down |
| list.pop_back(); |
| QVERIFY(list.count() == 1); |
| |
| // and empty. :) |
| list.pop_back(); |
| QVERIFY(list.count() == 0); |
| } |
| |
| void tst_QLinkedList::countInt() const |
| { |
| count<int>(); |
| } |
| |
| void tst_QLinkedList::countMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| count<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::countComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| count<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::cpp17ctad() const |
| { |
| #ifdef __cpp_deduction_guides |
| #define QVERIFY_IS_LIST_OF(obj, Type) \ |
| QVERIFY2((std::is_same<decltype(obj), QLinkedList<Type>>::value), \ |
| QMetaType::typeName(qMetaTypeId<decltype(obj)::value_type>())) |
| #define CHECK(Type, One, Two, Three) \ |
| do { \ |
| const Type v[] = {One, Two, Three}; \ |
| QLinkedList v1 = {One, Two, Three}; \ |
| QVERIFY_IS_LIST_OF(v1, Type); \ |
| QLinkedList v2(v1.begin(), v1.end()); \ |
| QVERIFY_IS_LIST_OF(v2, Type); \ |
| QLinkedList v3(std::begin(v), std::end(v)); \ |
| QVERIFY_IS_LIST_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_LIST_OF |
| #undef CHECK |
| #else |
| QSKIP("This test requires C++17 Constructor Template Argument Deduction support enabled in the compiler."); |
| #endif |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::empty() const |
| { |
| QLinkedList<T> list; |
| |
| // make sure it starts empty |
| QVERIFY(list.empty()); |
| |
| // and doesn't stay empty |
| list.append(T_FOO); |
| QVERIFY(!list.empty()); |
| |
| // and goes back to being empty |
| list.pop_back(); |
| QVERIFY(list.empty()); |
| } |
| |
| void tst_QLinkedList::emptyInt() const |
| { |
| empty<int>(); |
| } |
| |
| void tst_QLinkedList::emptyMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| empty<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::emptyComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| empty<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::endsWith() const |
| { |
| QLinkedList<T> list; |
| list << T_FOO << T_BAR << T_BAZ; |
| |
| // test it returns correctly in both cases |
| QVERIFY(list.endsWith(T_BAZ)); |
| QVERIFY(!list.endsWith(T_BAR)); |
| |
| // remove an item and make sure the end item changes |
| list.pop_back(); |
| QVERIFY(list.endsWith(T_BAR)); |
| } |
| |
| void tst_QLinkedList::endsWithInt() const |
| { |
| endsWith<int>(); |
| } |
| |
| void tst_QLinkedList::endsWithMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| endsWith<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::endsWithComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| endsWith<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::removeAll() const |
| { |
| QLinkedList<T> list; |
| list << T_FOO << T_BAR << T_BAZ; |
| |
| // remove one instance |
| list.removeAll(T_BAR); |
| QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ); |
| |
| // many instances |
| list << T_FOO << T_BAR << T_BAZ << T_FOO << T_BAR << T_BAZ << T_FOO << T_BAR << T_BAZ; |
| list.removeAll(T_BAR); |
| QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ); |
| |
| // try remove something that doesn't exist |
| list.removeAll(T_WEEE); |
| QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ); |
| } |
| |
| void tst_QLinkedList::removeAllInt() const |
| { |
| removeAll<int>(); |
| } |
| |
| void tst_QLinkedList::removeAllMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| removeAll<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::removeAllComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| removeAll<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::removeOne() const |
| { |
| QLinkedList<T> list; |
| list << T_FOO << T_BAR << T_BAZ; |
| |
| // middle |
| list.removeOne(T_BAR); |
| QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ); |
| |
| // start |
| list.removeOne(T_FOO); |
| QCOMPARE(list, QLinkedList<T>() << T_BAZ); |
| |
| // last |
| list.removeOne(T_BAZ); |
| QCOMPARE(list, QLinkedList<T>()); |
| |
| // make sure it really only removes one :) |
| list << T_FOO << T_FOO; |
| list.removeOne(T_FOO); |
| QCOMPARE(list, QLinkedList<T>() << T_FOO); |
| |
| // try remove something that doesn't exist |
| list.removeOne(T_WEEE); |
| QCOMPARE(list, QLinkedList<T>() << T_FOO); |
| } |
| |
| void tst_QLinkedList::removeOneInt() const |
| { |
| removeOne<int>(); |
| } |
| |
| void tst_QLinkedList::removeOneMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| removeOne<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::removeOneComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| removeOne<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::reverseIterators() const |
| { |
| QLinkedList<int> l; |
| l << 1 << 2 << 3 << 4; |
| QLinkedList<int> lr = l; |
| std::reverse(lr.begin(), lr.end()); |
| const QLinkedList<int> &clr = lr; |
| QVERIFY(std::equal(l.begin(), l.end(), lr.rbegin())); |
| QVERIFY(std::equal(l.begin(), l.end(), lr.crbegin())); |
| QVERIFY(std::equal(l.begin(), l.end(), clr.rbegin())); |
| QVERIFY(std::equal(lr.rbegin(), lr.rend(), l.begin())); |
| QVERIFY(std::equal(lr.crbegin(), lr.crend(), l.begin())); |
| QVERIFY(std::equal(clr.rbegin(), clr.rend(), l.begin())); |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::startsWith() const |
| { |
| QLinkedList<T> list; |
| list << T_FOO << T_BAR << T_BAZ; |
| |
| // make sure it starts ok |
| QVERIFY(list.startsWith(T_FOO)); |
| |
| // remove an item |
| list.removeFirst(); |
| QVERIFY(list.startsWith(T_BAR)); |
| } |
| |
| void tst_QLinkedList::startsWithInt() const |
| { |
| startsWith<int>(); |
| } |
| |
| void tst_QLinkedList::startsWithMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| startsWith<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::startsWithComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| startsWith<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::takeFirst() const |
| { |
| QLinkedList<T> list; |
| list << T_FOO << T_BAR << T_BAZ; |
| |
| QCOMPARE(list.takeFirst(), T_FOO); |
| QVERIFY(list.size() == 2); |
| QCOMPARE(list.takeFirst(), T_BAR); |
| QVERIFY(list.size() == 1); |
| QCOMPARE(list.takeFirst(), T_BAZ); |
| QVERIFY(list.size() == 0); |
| } |
| |
| void tst_QLinkedList::takeFirstInt() const |
| { |
| takeFirst<int>(); |
| } |
| |
| void tst_QLinkedList::takeFirstMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| takeFirst<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::takeFirstComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| takeFirst<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::takeLast() const |
| { |
| QLinkedList<T> list; |
| list << T_FOO << T_BAR << T_BAZ; |
| |
| QCOMPARE(list.takeLast(), T_BAZ); |
| QCOMPARE(list.takeLast(), T_BAR); |
| QCOMPARE(list.takeLast(), T_FOO); |
| } |
| |
| void tst_QLinkedList::takeLastInt() const |
| { |
| takeLast<int>(); |
| } |
| |
| void tst_QLinkedList::takeLastMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| takeLast<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::takeLastComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| takeLast<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::toStdList() const |
| { |
| QLinkedList<T> list; |
| list << T_FOO << T_BAR << T_BAZ; |
| |
| // yuck. |
| std::list<T> slist; |
| slist.push_back(T_FOO); |
| slist.push_back(T_BAR); |
| slist.push_back(T_BAZ); |
| |
| QCOMPARE(list.toStdList(), slist); |
| QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAR << T_BAZ); |
| } |
| |
| void tst_QLinkedList::toStdListInt() const |
| { |
| toStdList<int>(); |
| } |
| |
| void tst_QLinkedList::toStdListMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| toStdList<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::toStdListComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| toStdList<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::testOperators() const |
| { |
| QLinkedList<T> list; |
| list << T_FOO << T_BAR << T_BAZ; |
| |
| QLinkedList<T> listtwo; |
| listtwo << T_FOO << T_BAR << T_BAZ; |
| |
| // test equal |
| QVERIFY(list == listtwo); |
| |
| // not equal |
| listtwo.append(T_CAT); |
| QVERIFY(list != listtwo); |
| |
| // += |
| list += listtwo; |
| QVERIFY(list.size() == 7); |
| QVERIFY(listtwo.size() == 4); |
| QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAR << T_BAZ |
| << T_FOO << T_BAR << T_BAZ << T_CAT); |
| |
| // = |
| list = listtwo; |
| QCOMPARE(list, listtwo); |
| QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAR << T_BAZ << T_CAT); |
| } |
| |
| void tst_QLinkedList::testOperatorsInt() const |
| { |
| testOperators<int>(); |
| } |
| |
| void tst_QLinkedList::testOperatorsMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| testOperators<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::testOperatorsComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| testOperators<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| template<typename T> |
| void tst_QLinkedList::testSTLIterators() const |
| { |
| QLinkedList<T> list; |
| |
| // create a list |
| list << T_FOO << T_BAR << T_BAZ; |
| typename QLinkedList<T>::iterator it = list.begin(); |
| QCOMPARE(*it, T_FOO); it++; |
| QCOMPARE(*it, T_BAR); it++; |
| QCOMPARE(*it, T_BAZ); it++; |
| QCOMPARE(it, list.end()); it--; |
| |
| // walk backwards |
| QCOMPARE(*it, T_BAZ); it--; |
| QCOMPARE(*it, T_BAR); it--; |
| QCOMPARE(*it, T_FOO); |
| |
| // test erase |
| it = list.erase(it); |
| QVERIFY(list.size() == 2); |
| QCOMPARE(*it, T_BAR); |
| |
| // test multiple erase |
| it = list.erase(it, it + 2); |
| QVERIFY(list.size() == 0); |
| QCOMPARE(it, list.end()); |
| |
| // insert again |
| it = list.insert(it, T_FOO); |
| QVERIFY(list.size() == 1); |
| QCOMPARE(*it, T_FOO); |
| |
| // insert again |
| it = list.insert(it, T_BAR); |
| QVERIFY(list.size() == 2); |
| QCOMPARE(*it++, T_BAR); |
| QCOMPARE(*it, T_FOO); |
| } |
| |
| void tst_QLinkedList::testSTLIteratorsInt() const |
| { |
| testSTLIterators<int>(); |
| } |
| |
| void tst_QLinkedList::testSTLIteratorsMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| testSTLIterators<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::testSTLIteratorsComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| testSTLIterators<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::initializeList() const |
| { |
| QLinkedList<int> v1 { 2, 3, 4 }; |
| QCOMPARE(v1, QLinkedList<int>() << 2 << 3 << 4); |
| QCOMPARE(v1, (QLinkedList<int> { 2, 3, 4})); |
| |
| QLinkedList<QLinkedList<int>> v2{ v1, { 1 }, QLinkedList<int>(), { 2, 3, 4 } }; |
| QLinkedList<QLinkedList<int>> v3; |
| v3 << v1 << (QLinkedList<int>() << 1) << QLinkedList<int>() << v1; |
| QCOMPARE(v3, v2); |
| } |
| |
| |
| template<typename T> |
| void tst_QLinkedList::constSharedNull() const |
| { |
| QLinkedList<T> list2; |
| #if !defined(QT_NO_UNSHARABLE_CONTAINERS) |
| QLinkedList<T> list1; |
| list1.setSharable(false); |
| QVERIFY(list1.isDetached()); |
| |
| list2.setSharable(true); |
| #endif |
| QVERIFY(!list2.isDetached()); |
| } |
| |
| void tst_QLinkedList::constSharedNullInt() const |
| { |
| constSharedNull<int>(); |
| } |
| |
| void tst_QLinkedList::constSharedNullMovable() const |
| { |
| const int liveCount = Movable::getLiveCount(); |
| constSharedNull<Movable>(); |
| QCOMPARE(liveCount, Movable::getLiveCount()); |
| } |
| |
| void tst_QLinkedList::constSharedNullComplex() const |
| { |
| const int liveCount = Complex::getLiveCount(); |
| constSharedNull<Complex>(); |
| QCOMPARE(liveCount, Complex::getLiveCount()); |
| } |
| |
| |
| void tst_QLinkedList::setSharableInt() const |
| { |
| #if !defined(QT_NO_UNSHARABLE_CONTAINERS) |
| QLinkedList<int> orglist; |
| orglist << 0 << 1 << 2 << 3 << 4 << 5; |
| int size = 6; |
| |
| QLinkedList<int> list; |
| list = orglist; |
| |
| QVERIFY(!list.isDetached()); |
| list.setSharable(true); |
| |
| QCOMPARE(list.size(), size); |
| |
| { |
| QLinkedList<int> copy(list); |
| QVERIFY(!copy.isDetached()); |
| QVERIFY(copy.isSharedWith(list)); |
| } |
| |
| list.setSharable(false); |
| QVERIFY(list.isDetached() || list.isSharedWith(QLinkedList<int>())); |
| |
| { |
| QLinkedList<int> copy(list); |
| |
| QVERIFY(copy.isDetached() || copy.isSharedWith(QLinkedList<int>())); |
| QCOMPARE(copy.size(), size); |
| QCOMPARE(copy, list); |
| } |
| |
| list.setSharable(true); |
| |
| { |
| QLinkedList<int> copy(list); |
| |
| QVERIFY(!copy.isDetached()); |
| QVERIFY(copy.isSharedWith(list)); |
| } |
| |
| QLinkedList<int>::const_iterator it = list.constBegin(); |
| for (int i = 0; i < list.size(); ++i) { |
| QCOMPARE(int(*it), i); |
| ++it; |
| } |
| |
| QCOMPARE(list.size(), size); |
| #endif |
| } |
| |
| QT_WARNING_POP |
| #else |
| class tst_QLinkedList : public QObject |
| { |
| Q_OBJECT |
| private slots: |
| void initTestCase() { QSKIP("Deprecated APIs are disabled, skipping this test."); } |
| }; |
| |
| #endif // QT_DEPRECATED_SINCE(5, 15) |
| |
| QTEST_APPLESS_MAIN(tst_QLinkedList) |
| #include "tst_qlinkedlist.moc" |