/**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL21$ ** 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 http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 or version 3 as published by the Free ** Software Foundation and appearing in the file LICENSE.LGPLv21 and ** LICENSE.LGPLv3 included in the packaging of this file. Please review the ** following information to ensure the GNU Lesser General Public License ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** As a special exception, The Qt Company gives you certain additional ** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include 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(state1, state2); } }; int Movable::liveCount = 0; QT_BEGIN_NAMESPACE Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE); QT_END_NAMESPACE Q_DECLARE_METATYPE(Movable); 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::isStatic); Q_STATIC_ASSERT(!QTypeInfo::isComplex); Q_STATIC_ASSERT(!QTypeInfo::isStatic); Q_STATIC_ASSERT(QTypeInfo::isComplex); Q_STATIC_ASSERT(QTypeInfo::isStatic); Q_STATIC_ASSERT(QTypeInfo::isComplex); class tst_QList : public QObject { Q_OBJECT private slots: void lengthInt() const; void lengthMovable() const; void lengthComplex() const; void lengthSignature() const; void appendInt() const; void appendMovable() const; void appendComplex() const; void prepend() const; void midInt() const; void midMovable() const; void midComplex() const; void atInt() const; void atMovable() const; void atComplex() 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 emptyInt() const; void emptyMovable() const; void emptyComplex() const; void endsWithInt() const; void endsWithMovable() const; void endsWithComplex() const; void lastIndexOfInt() const; void lastIndexOfMovable() const; void lastIndexOfComplex() const; void moveInt() const; void moveMovable() const; void moveComplex() const; void removeAllInt() const; void removeAllMovable() const; void removeAllComplex() const; void removeAtInt() const; void removeAtMovable() const; void removeAtComplex() const; void removeOneInt() const; void removeOneMovable() const; void removeOneComplex() const; void replaceInt() const; void replaceMovable() const; void replaceComplex() const; void startsWithInt() const; void startsWithMovable() const; void startsWithComplex() const; void swapInt() const; void swapMovable() const; void swapComplex() const; void takeAtInt() const; void takeAtMovable() const; void takeAtComplex() const; void takeFirstInt() const; void takeFirstMovable() const; void takeFirstComplex() const; void takeLastInt() const; void takeLastMovable() const; void takeLastComplex() const; void toSetInt() const; void toSetMovable() const; void toSetComplex() const; void toStdListInt() const; void toStdListMovable() const; void toStdListComplex() const; void toVectorInt() const; void toVectorMovable() const; void toVectorComplex() const; void valueInt() const; void valueMovable() const; void valueComplex() 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_data() const; void setSharableInt() const; void setSharableComplex_data() const; void setSharableComplex() const; void eraseValidIteratorsOnSharedList() const; void insertWithValidIteratorsOnSharedList() const; void reserve() const; private: template void length() const; template void append() const; template void mid() const; template void at() const; template void first() const; template void last() const; template void begin() const; template void end() const; template void contains() const; template void count() const; template void empty() const; template void endsWith() const; template void lastIndexOf() const; template void move() const; template void removeAll() const; template void removeAt() const; template void removeOne() const; template void replace() const; template void startsWith() const; template void swap() const; template void takeAt() const; template void takeFirst() const; template void takeLast() const; template void toSet() const; template void toStdList() const; template void toVector() const; template void value() const; template void testOperators() const; template void testSTLIterators() const; template void constSharedNull() const; int dummyForGuard; }; template 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::values[] = { 10, 20, 30, 40, 100, 101, 102 }; template<> const Movable SimpleValue::values[] = { 10, 20, 30, 40, 100, 101, 102 }; template<> const Complex SimpleValue::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::at(0) #define T_BAR SimpleValue::at(1) #define T_BAZ SimpleValue::at(2) #define T_CAT SimpleValue::at(3) #define T_DOG SimpleValue::at(4) #define T_BLAH SimpleValue::at(5) #define T_WEEE SimpleValue::at(6) template void tst_QList::length() const { /* Empty list. */ { const QList list; QCOMPARE(list.length(), 0); } /* One entry. */ { QList list; list.append(T_FOO); QCOMPARE(list.length(), 1); } /* Two entries. */ { QList list; list.append(T_FOO); list.append(T_BAR); QCOMPARE(list.length(), 2); } /* Three entries. */ { QList list; list.append(T_FOO); list.append(T_BAR); list.append(T_BAZ); QCOMPARE(list.length(), 3); } } void tst_QList::lengthInt() const { length(); } void tst_QList::lengthMovable() const { const int liveCount = Movable::getLiveCount(); length(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::lengthComplex() const { const int liveCount = Complex::getLiveCount(); length(); QCOMPARE(liveCount, Complex::getLiveCount()); } void tst_QList::lengthSignature() const { /* Constness. */ { const QList list; /* The function should be const. */ list.length(); } } template void tst_QList::append() const { /* test append(const QList &) function */ T one(T_FOO); T two(T_BAR); T three(T_BAZ); T four(T_CAT); QList list1; QList list2; QList listTotal; list1.append(one); list1.append(two); list2.append(three); list2.append(four); list1.append(list2); listTotal.append(one); listTotal.append(two); listTotal.append(three); listTotal.append(four); QCOMPARE(list1, listTotal); } void tst_QList::appendInt() const { append(); } void tst_QList::appendMovable() const { const int liveCount = Movable::getLiveCount(); append(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::appendComplex() const { const int liveCount = Complex::getLiveCount(); append(); QCOMPARE(liveCount, Complex::getLiveCount()); } void tst_QList::prepend() const { QList list; int *t1 = new int(0); list.prepend(t1); QVERIFY(list.size() == 1); QVERIFY(list.at(0) == t1); int *t2 = new int(0); list.prepend(t2); QVERIFY(list.size() == 2); QVERIFY(list.at(0) == t2); QVERIFY(list.at(1) == t1); int *t3 = new int(0); list.prepend(t3); QVERIFY(list.size() == 3); QVERIFY(list.at(0) == t3); QVERIFY(list.at(1) == t2); QVERIFY(list.at(2) == t1); list.removeAll(t2); delete t2; QVERIFY(list.size() == 2); QVERIFY(list.at(0) == t3); QVERIFY(list.at(1) == t1); int *t4 = new int(0); list.prepend(t4); QVERIFY(list.size() == 3); QVERIFY(list.at(0) == t4); QVERIFY(list.at(1) == t3); QVERIFY(list.at(2) == t1); qDeleteAll(list); list.clear(); } template void tst_QList::mid() const { QList list; list << T_FOO << T_BAR << T_BAZ << T_CAT << T_DOG << T_BLAH << T_WEEE; QCOMPARE(list.mid(3, 3), QList() << T_CAT << T_DOG << T_BLAH); QList list1; QCOMPARE(list1.mid(1, 1).length(), 0); } void tst_QList::midInt() const { mid(); } void tst_QList::midMovable() const { const int liveCount = Movable::getLiveCount(); mid(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::midComplex() const { const int liveCount = Complex::getLiveCount(); mid(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::at() const { // test at() and make sure it functions correctly with some simple list manipulation. QList list; // create a list list << T_FOO << T_BAR << T_BAZ; QVERIFY(list.size() == 3); QCOMPARE(list.at(0), T_FOO); QCOMPARE(list.at(1), T_BAR); QCOMPARE(list.at(2), T_BAZ); // append an item list << T_CAT; QVERIFY(list.size() == 4); QCOMPARE(list.at(0), T_FOO); QCOMPARE(list.at(1), T_BAR); QCOMPARE(list.at(2), T_BAZ); QCOMPARE(list.at(3), T_CAT); // remove an item list.removeAt(1); QVERIFY(list.size() == 3); QCOMPARE(list.at(0), T_FOO); QCOMPARE(list.at(1), T_BAZ); QCOMPARE(list.at(2), T_CAT); } void tst_QList::atInt() const { at(); } void tst_QList::atMovable() const { const int liveCount = Movable::getLiveCount(); at(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::atComplex() const { const int liveCount = Complex::getLiveCount(); at(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::first() const { QList 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_QList::firstInt() const { first(); } void tst_QList::firstMovable() const { const int liveCount = Movable::getLiveCount(); first(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::firstComplex() const { const int liveCount = Complex::getLiveCount(); first(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::last() const { QList 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_QList::lastInt() const { last(); } void tst_QList::lastMovable() const { const int liveCount = Movable::getLiveCount(); last(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::lastComplex() const { const int liveCount = Complex::getLiveCount(); last(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::begin() const { QList 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_QList::beginInt() const { begin(); } void tst_QList::beginMovable() const { const int liveCount = Movable::getLiveCount(); begin(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::beginComplex() const { const int liveCount = Complex::getLiveCount(); begin(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::end() const { QList 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_QList::endInt() const { end(); } void tst_QList::endMovable() const { const int liveCount = Movable::getLiveCount(); end(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::endComplex() const { const int liveCount = Complex::getLiveCount(); end(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::contains() const { QList list; list << T_FOO << T_BAR << T_BAZ; QVERIFY(list.contains(T_FOO) == true); QVERIFY(list.contains(T_BLAH) != true); // add it and make sure it matches list.append(T_BLAH); QVERIFY(list.contains(T_BLAH) == true); } void tst_QList::containsInt() const { contains(); } void tst_QList::containsMovable() const { const int liveCount = Movable::getLiveCount(); contains(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::containsComplex() const { const int liveCount = Complex::getLiveCount(); contains(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::count() const { QList 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_QList::countInt() const { count(); } void tst_QList::countMovable() const { const int liveCount = Movable::getLiveCount(); count(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::countComplex() const { const int liveCount = Complex::getLiveCount(); count(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::empty() const { QList 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_QList::emptyInt() const { empty(); } void tst_QList::emptyMovable() const { const int liveCount = Movable::getLiveCount(); empty(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::emptyComplex() const { const int liveCount = Complex::getLiveCount(); empty(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::endsWith() const { QList 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_QList::endsWithInt() const { endsWith(); } void tst_QList::endsWithMovable() const { const int liveCount = Movable::getLiveCount(); endsWith(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::endsWithComplex() const { const int liveCount = Complex::getLiveCount(); endsWith(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::lastIndexOf() const { QList list; list << T_FOO << T_BAR << T_BAZ; // one instance of the target item QVERIFY(list.lastIndexOf(T_BAZ) == 2); // shouldn't find this QVERIFY(list.lastIndexOf(T_WEEE) == -1); // multiple instances list.append(T_BAZ); list.append(T_BAZ); QVERIFY(list.lastIndexOf(T_BAZ) == 4); // search from the middle to find the last one QVERIFY(list.lastIndexOf(T_BAZ, 3) == 3); // try to find none QVERIFY(list.lastIndexOf(T_BAZ, 1) == -1); } void tst_QList::lastIndexOfInt() const { lastIndexOf(); } void tst_QList::lastIndexOfMovable() const { const int liveCount = Movable::getLiveCount(); lastIndexOf(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::lastIndexOfComplex() const { const int liveCount = Complex::getLiveCount(); lastIndexOf(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::move() const { QList list; list << T_FOO << T_BAR << T_BAZ; // move an item list.move(0, list.count() - 1); QCOMPARE(list, QList() << T_BAR << T_BAZ << T_FOO); // move it back list.move(list.count() - 1, 0); QCOMPARE(list, QList() << T_FOO << T_BAR << T_BAZ); // move an item in the middle list.move(1, 0); QCOMPARE(list, QList() << T_BAR << T_FOO << T_BAZ); } void tst_QList::moveInt() const { move(); } void tst_QList::moveMovable() const { const int liveCount = Movable::getLiveCount(); move(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::moveComplex() const { const int liveCount = Complex::getLiveCount(); move(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::removeAll() const { QList list; list << T_FOO << T_BAR << T_BAZ; // remove one instance list.removeAll(T_BAR); QCOMPARE(list, QList() << 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, QList() << 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, QList() << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ); } void tst_QList::removeAllInt() const { removeAll(); } void tst_QList::removeAllMovable() const { const int liveCount = Movable::getLiveCount(); removeAll(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::removeAllComplex() const { const int liveCount = Complex::getLiveCount(); removeAll(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::removeAt() const { QList list; list << T_FOO << T_BAR << T_BAZ; // middle list.removeAt(1); QCOMPARE(list, QList() << T_FOO << T_BAZ); // start list.removeAt(0); QCOMPARE(list, QList() << T_BAZ); // final list.removeAt(0); QCOMPARE(list, QList()); } void tst_QList::removeAtInt() const { removeAt(); } void tst_QList::removeAtMovable() const { const int liveCount = Movable::getLiveCount(); removeAt(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::removeAtComplex() const { const int liveCount = Complex::getLiveCount(); removeAt(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::removeOne() const { QList list; list << T_FOO << T_BAR << T_BAZ; // middle list.removeOne(T_BAR); QCOMPARE(list, QList() << T_FOO << T_BAZ); // start list.removeOne(T_FOO); QCOMPARE(list, QList() << T_BAZ); // last list.removeOne(T_BAZ); QCOMPARE(list, QList()); // make sure it really only removes one :) list << T_FOO << T_FOO; list.removeOne(T_FOO); QCOMPARE(list, QList() << T_FOO); // try remove something that doesn't exist list.removeOne(T_WEEE); QCOMPARE(list, QList() << T_FOO); } void tst_QList::removeOneInt() const { removeOne(); } void tst_QList::removeOneMovable() const { const int liveCount = Movable::getLiveCount(); removeOne(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::removeOneComplex() const { const int liveCount = Complex::getLiveCount(); removeOne(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::replace() const { QList list; list << T_FOO << T_BAR << T_BAZ; // start list.replace(0, T_CAT); QCOMPARE(list, QList() << T_CAT << T_BAR << T_BAZ); // middle list.replace(1, T_DOG); QCOMPARE(list, QList() << T_CAT << T_DOG << T_BAZ); // end list.replace(2, T_BLAH); QCOMPARE(list, QList() << T_CAT << T_DOG << T_BLAH); } void tst_QList::replaceInt() const { replace(); } void tst_QList::replaceMovable() const { const int liveCount = Movable::getLiveCount(); replace(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::replaceComplex() const { const int liveCount = Complex::getLiveCount(); replace(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::startsWith() const { QList 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_QList::startsWithInt() const { startsWith(); } void tst_QList::startsWithMovable() const { const int liveCount = Movable::getLiveCount(); startsWith(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::startsWithComplex() const { const int liveCount = Complex::getLiveCount(); startsWith(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::swap() const { QList list; list << T_FOO << T_BAR << T_BAZ; // swap list.swap(0, 2); QCOMPARE(list, QList() << T_BAZ << T_BAR << T_FOO); // swap again list.swap(1, 2); QCOMPARE(list, QList() << T_BAZ << T_FOO << T_BAR); QList list2; list2 << T_DOG << T_BLAH; list.swap(list2); QCOMPARE(list, QList() << T_DOG << T_BLAH); QCOMPARE(list2, QList() << T_BAZ << T_FOO << T_BAR); } void tst_QList::swapInt() const { swap(); } void tst_QList::swapMovable() const { const int liveCount = Movable::getLiveCount(); swap(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::swapComplex() const { const int liveCount = Complex::getLiveCount(); swap(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::takeAt() const { QList list; list << T_FOO << T_BAR << T_BAZ; QCOMPARE(list.takeAt(0), T_FOO); QVERIFY(list.size() == 2); QCOMPARE(list.takeAt(1), T_BAZ); QVERIFY(list.size() == 1); QCOMPARE(list.takeAt(0), T_BAR); QVERIFY(list.size() == 0); } void tst_QList::takeAtInt() const { takeAt(); } void tst_QList::takeAtMovable() const { const int liveCount = Movable::getLiveCount(); takeAt(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::takeAtComplex() const { const int liveCount = Complex::getLiveCount(); takeAt(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::takeFirst() const { QList 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_QList::takeFirstInt() const { takeFirst(); } void tst_QList::takeFirstMovable() const { const int liveCount = Movable::getLiveCount(); takeFirst(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::takeFirstComplex() const { const int liveCount = Complex::getLiveCount(); takeFirst(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::takeLast() const { QList 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_QList::takeLastInt() const { takeLast(); } void tst_QList::takeLastMovable() const { const int liveCount = Movable::getLiveCount(); takeLast(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::takeLastComplex() const { const int liveCount = Complex::getLiveCount(); takeLast(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::toSet() const { QList list; list << T_FOO << T_BAR << T_BAZ; // no duplicates QCOMPARE(list.toSet(), QSet() << T_FOO << T_BAR << T_BAZ); QCOMPARE(list, QList() << T_FOO << T_BAR << T_BAZ); // duplicates (is this more of a QSet test?) list << T_FOO << T_BAR << T_BAZ; QCOMPARE(list.toSet(), QSet() << T_FOO << T_BAR << T_BAZ); QCOMPARE(list, QList() << T_FOO << T_BAR << T_BAZ << T_FOO << T_BAR << T_BAZ); } void tst_QList::toSetInt() const { toSet(); } void tst_QList::toSetMovable() const { const int liveCount = Movable::getLiveCount(); toSet(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::toSetComplex() const { const int liveCount = Complex::getLiveCount(); toSet(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::toStdList() const { QList list; list << T_FOO << T_BAR << T_BAZ; // yuck. std::list slist; slist.push_back(T_FOO); slist.push_back(T_BAR); slist.push_back(T_BAZ); QCOMPARE(list.toStdList(), slist); QCOMPARE(list, QList() << T_FOO << T_BAR << T_BAZ); } void tst_QList::toStdListInt() const { toStdList(); } void tst_QList::toStdListMovable() const { const int liveCount = Movable::getLiveCount(); toStdList(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::toStdListComplex() const { const int liveCount = Complex::getLiveCount(); toStdList(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::toVector() const { QList list; list << T_FOO << T_BAR << T_BAZ; QCOMPARE(list.toVector(), QVector() << T_FOO << T_BAR << T_BAZ); } void tst_QList::toVectorInt() const { toVector(); } void tst_QList::toVectorMovable() const { const int liveCount = Movable::getLiveCount(); toVector(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::toVectorComplex() const { const int liveCount = Complex::getLiveCount(); toVector(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::value() const { QList list; list << T_FOO << T_BAR << T_BAZ; // test real values QCOMPARE(list.value(0), T_FOO); QCOMPARE(list.value(2), T_BAZ); // test empty default QCOMPARE(list.value(3), T()); QCOMPARE(list.value(-1), T()); // test defaults T defaultT(T_WEEE); QCOMPARE(list.value(-1, defaultT), defaultT); QCOMPARE(list.value(3, defaultT), defaultT); } void tst_QList::valueInt() const { value(); } void tst_QList::valueMovable() const { const int liveCount = Movable::getLiveCount(); value(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::valueComplex() const { const int liveCount = Complex::getLiveCount(); value(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::testOperators() const { QList list; list << T_FOO << T_BAR << T_BAZ; QList 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, QList() << T_FOO << T_BAR << T_BAZ << T_FOO << T_BAR << T_BAZ << T_CAT); // = list = listtwo; QCOMPARE(list, listtwo); QCOMPARE(list, QList() << T_FOO << T_BAR << T_BAZ << T_CAT); // [] QCOMPARE(list[0], T_FOO); QCOMPARE(list[list.size() - 1], T_CAT); } void tst_QList::testOperatorsInt() const { testOperators(); } void tst_QList::testOperatorsMovable() const { const int liveCount = Movable::getLiveCount(); testOperators(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::testOperatorsComplex() const { const int liveCount = Complex::getLiveCount(); testOperators(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void tst_QList::testSTLIterators() const { QList list; // create a list list << T_FOO << T_BAR << T_BAZ; typename QList::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_QList::testSTLIteratorsInt() const { testSTLIterators(); } void tst_QList::testSTLIteratorsMovable() const { const int liveCount = Movable::getLiveCount(); testSTLIterators(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::testSTLIteratorsComplex() const { const int liveCount = Complex::getLiveCount(); testSTLIterators(); QCOMPARE(liveCount, Complex::getLiveCount()); } void tst_QList::initializeList() const { #ifdef Q_COMPILER_INITIALIZER_LISTS QList v1{2,3,4}; QCOMPARE(v1, QList() << 2 << 3 << 4); QCOMPARE(v1, (QList{2,3,4})); QList> v2{ v1, {1}, QList(), {2,3,4} }; QList> v3; v3 << v1 << (QList() << 1) << QList() << v1; QCOMPARE(v3, v2); #endif } template void tst_QList::constSharedNull() const { QList list2; #if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QList list1; list1.setSharable(false); QVERIFY(list1.isDetached()); list2.setSharable(true); #endif QVERIFY(!list2.isDetached()); } void tst_QList::constSharedNullInt() const { constSharedNull(); } void tst_QList::constSharedNullMovable() const { const int liveCount = Movable::getLiveCount(); constSharedNull(); QCOMPARE(liveCount, Movable::getLiveCount()); } void tst_QList::constSharedNullComplex() const { const int liveCount = Complex::getLiveCount(); constSharedNull(); QCOMPARE(liveCount, Complex::getLiveCount()); } template void generateSetSharableData() { #if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QTest::addColumn >("list"); QTest::addColumn("size"); QTest::newRow("null") << QList() << 0; QTest::newRow("non-empty") << (QList() << T(0) << T(1) << T(2) << T(3) << T(4)) << 5; #endif } template void runSetSharableTest() { #if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QFETCH(QList, list); QFETCH(int, size); QVERIFY(!list.isDetached()); // Shared with QTest list.setSharable(true); QCOMPARE(list.size(), size); { QList copy(list); QVERIFY(!copy.isDetached()); QVERIFY(copy.isSharedWith(list)); } list.setSharable(false); QVERIFY(list.isDetached() || list.isSharedWith(QList())); { QList copy(list); QVERIFY(copy.isDetached() || copy.isSharedWith(QList())); QCOMPARE(copy.size(), size); QCOMPARE(copy, list); } list.setSharable(true); { QList copy(list); QVERIFY(!copy.isDetached()); QVERIFY(copy.isSharedWith(list)); } for (int i = 0; i < list.size(); ++i) QCOMPARE(int(list[i]), i); QCOMPARE(list.size(), size); #endif } void tst_QList::setSharableInt_data() const { generateSetSharableData(); } void tst_QList::setSharableComplex_data() const { generateSetSharableData(); } void tst_QList::setSharableInt() const { runSetSharableTest(); } void tst_QList::setSharableComplex() const { runSetSharableTest(); } void tst_QList::eraseValidIteratorsOnSharedList() const { QList a, b; a.push_back(10); a.push_back(20); a.push_back(30); QList::iterator i = a.begin(); ++i; b = a; a.erase(i); QCOMPARE(b.size(), 3); QCOMPARE(a.size(), 2); QCOMPARE(a.at(0), 10); QCOMPARE(a.at(1), 30); a.push_back(40); a.push_back(50); a.push_back(60); QCOMPARE(a.size(), 5); i = a.begin(); b = a; ++i; QList::iterator j = i; ++j; ++j; a.erase(i, j); // remove 3 elements QCOMPARE(b.size(), 5); QCOMPARE(a.size(), 3); QCOMPARE(a.at(0), 10); QCOMPARE(a.at(1), 50); } void tst_QList::insertWithValidIteratorsOnSharedList() const { QList a, b; a.push_back(10); a.push_back(20); a.push_back(30); QList::iterator i = a.begin(); ++i; b = a; a.insert(i, 15); QCOMPARE(a.size(), b.size() + 1); QCOMPARE(b.at(1), 20); QCOMPARE(a.at(1), 15); } void tst_QList::reserve() const { // Note: // This test depends on QList's current behavior that ints are stored in the array itself. // This test would not work for QList. int capacity = 100; QList list; list.reserve(capacity); list << 0; int *data = &list[0]; for (int i = 1; i < capacity; i++) { list << i; QCOMPARE(&list.at(0), data); } QList copy = list; list.reserve(capacity / 2); QCOMPARE(list.size(), capacity); // we didn't shrink the size! copy = list; list.reserve(capacity * 2); QCOMPARE(list.size(), capacity); QVERIFY(&list.at(0) != data); } QTEST_APPLESS_MAIN(tst_QList) #include "tst_qlist.moc"