f9f395c28b
Updated version of LGPL and FDL licenseheaders. Apply release phase licenseheaders for all source files. Reviewed-by: Trust Me
3855 lines
101 KiB
C++
3855 lines
101 KiB
C++
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
|
** All rights reserved.
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
**
|
|
** This file is part of the test suite of the Qt Toolkit.
|
|
**
|
|
** $QT_BEGIN_LICENSE:LGPL$
|
|
** GNU Lesser General Public License Usage
|
|
** This file may be used under the terms of the GNU Lesser General Public
|
|
** License version 2.1 as published by the Free Software Foundation and
|
|
** appearing in the file LICENSE.LGPL included in the packaging of this
|
|
** file. Please review the following information to ensure the GNU Lesser
|
|
** General Public License version 2.1 requirements will be met:
|
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
**
|
|
** In addition, as a special exception, Nokia gives you certain additional
|
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
**
|
|
** GNU General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU General
|
|
** Public License version 3.0 as published by the Free Software Foundation
|
|
** and appearing in the file LICENSE.GPL included in the packaging of this
|
|
** file. Please review the following information to ensure the GNU General
|
|
** Public License version 3.0 requirements will be met:
|
|
** http://www.gnu.org/copyleft/gpl.html.
|
|
**
|
|
** Other Usage
|
|
** Alternatively, this file may be used in accordance with the terms and
|
|
** conditions contained in a signed written agreement between you and Nokia.
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
|
|
|
|
// test the container forwards
|
|
#include <QtContainerFwd>
|
|
|
|
static QCache<int, int> *cacheX;
|
|
static QHash<int, int> *hashX;
|
|
static QLinkedList<int> *linkedListX;
|
|
static QList<int> *listX;
|
|
static QMap<int, int> *mapX;
|
|
static QMultiHash<int, int> *multiHashX;
|
|
static QMultiMap<int, int> *multiMapX;
|
|
static QPair<int, int> *pairX;
|
|
static QQueue<int> *queueX;
|
|
static QSet<int> *setX;
|
|
static QStack<int> *stackX;
|
|
static QVarLengthArray<int> *varLengthArrayX;
|
|
static QVarLengthArray<int, 512> *varLengthArrayY;
|
|
static QVector<int> *vectorX;
|
|
|
|
void foo()
|
|
{
|
|
cacheX = 0;
|
|
hashX = 0;
|
|
linkedListX = 0;
|
|
listX = 0;
|
|
mapX = 0;
|
|
multiHashX = 0;
|
|
multiMapX = 0;
|
|
pairX = 0;
|
|
queueX = 0;
|
|
setX = 0;
|
|
stackX = 0;
|
|
varLengthArrayX = 0;
|
|
varLengthArrayY = 0;
|
|
vectorX = 0;
|
|
}
|
|
|
|
#include <QtTest/QtTest>
|
|
|
|
#ifndef QT_NO_STL
|
|
# include <algorithm>
|
|
#endif
|
|
|
|
#include "qalgorithms.h"
|
|
#include "qbitarray.h"
|
|
#include "qbytearray.h"
|
|
#include "qcache.h"
|
|
#include "qhash.h"
|
|
#include "qlinkedlist.h"
|
|
#include "qlist.h"
|
|
#include "qmap.h"
|
|
#include "qpair.h"
|
|
#include "qregexp.h"
|
|
#include "qset.h"
|
|
#include "qstack.h"
|
|
#include "qstring.h"
|
|
#include "qstringlist.h"
|
|
#include "qvarlengtharray.h"
|
|
#include "qvector.h"
|
|
#include "qqueue.h"
|
|
|
|
template class QList<int>;
|
|
|
|
//TESTED_FILES=
|
|
|
|
class tst_Collections : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
tst_Collections();
|
|
~tst_Collections();
|
|
|
|
public slots:
|
|
void init();
|
|
void cleanup();
|
|
private slots:
|
|
void typeinfo();
|
|
void qstring();
|
|
void list();
|
|
void linkedList();
|
|
void vector();
|
|
void byteArray();
|
|
void stack();
|
|
void hash();
|
|
void map();
|
|
void bitArray();
|
|
void cache();
|
|
void regexp();
|
|
void pair();
|
|
void sharableQList();
|
|
void sharableQLinkedList();
|
|
void sharableQVector();
|
|
void sharableQMap();
|
|
void sharableQHash();
|
|
void q_foreach();
|
|
void conversions();
|
|
void javaStyleIterators();
|
|
void constAndNonConstStlIterators();
|
|
#ifndef QT_NO_STL
|
|
void vector_stl_data();
|
|
void vector_stl();
|
|
void list_stl_data();
|
|
void list_stl();
|
|
void linkedlist_stl_data();
|
|
void linkedlist_stl();
|
|
#endif
|
|
void q_init();
|
|
void pointersize();
|
|
void containerInstantiation();
|
|
void qtimerList();
|
|
void containerTypedefs();
|
|
void forwardDeclared();
|
|
void alignment();
|
|
void QTBUG13079_collectionInsideCollection();
|
|
|
|
void foreach_2();
|
|
void insert_remove_loop();
|
|
};
|
|
|
|
struct LargeStatic {
|
|
static int count;
|
|
LargeStatic():c(count) { ++count; }
|
|
LargeStatic(const LargeStatic& o):c(o.c) { ++count; }
|
|
~LargeStatic() { --count; }
|
|
int c;
|
|
int data[8];
|
|
};
|
|
|
|
int LargeStatic::count = 0;
|
|
|
|
struct Movable {
|
|
static int count;
|
|
Movable():c(count) { ++count; }
|
|
Movable(const Movable& o):c(o.c) { ++count; }
|
|
~Movable() { --count; }
|
|
int c;
|
|
};
|
|
|
|
int Movable::count = 0;
|
|
QT_BEGIN_NAMESPACE
|
|
Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE);
|
|
QT_END_NAMESPACE
|
|
|
|
|
|
struct Pod {
|
|
int i1, i2;
|
|
};
|
|
|
|
tst_Collections::tst_Collections()
|
|
{
|
|
}
|
|
|
|
tst_Collections::~tst_Collections()
|
|
{
|
|
|
|
}
|
|
|
|
void tst_Collections::init()
|
|
{
|
|
}
|
|
|
|
void tst_Collections::cleanup()
|
|
{
|
|
}
|
|
|
|
void tst_Collections::typeinfo()
|
|
{
|
|
QVERIFY(QTypeInfo<int*>::isPointer);
|
|
QVERIFY(!QTypeInfo<int>::isPointer);
|
|
QVERIFY(QTypeInfo<QString>::isComplex);
|
|
QVERIFY(!QTypeInfo<int>::isComplex);
|
|
}
|
|
|
|
void tst_Collections::list()
|
|
{
|
|
{
|
|
QList<int> list;
|
|
QVERIFY(list.isEmpty());
|
|
list.append(1);
|
|
QVERIFY(list.size() == 1);
|
|
|
|
QVERIFY(*list.begin() == 1);
|
|
|
|
list.push_back(2);
|
|
list += (3);
|
|
list << 4 << 5 << 6;
|
|
QVERIFY(!list.isEmpty());
|
|
QVERIFY(list.size() == 6);
|
|
QVERIFY(list.end() - list.begin() == list.size());
|
|
|
|
#if !defined(QT_NO_STL) && !defined(Q_CC_MSVC) && !defined(Q_CC_SUN)
|
|
QVERIFY(std::binary_search(list.begin(), list.end(), 2) == true);
|
|
QVERIFY(std::binary_search(list.begin(), list.end(), 9) == false);
|
|
#endif
|
|
QVERIFY(qBinaryFind(list.begin(), list.end(), 2) == list.begin() + 1);
|
|
QVERIFY(qLowerBound(list.begin(), list.end(), 2) == list.begin() + 1);
|
|
QVERIFY(qUpperBound(list.begin(), list.end(), 2) == list.begin() + 2);
|
|
QVERIFY(qBinaryFind(list.begin(), list.end(), 9) == list.end());
|
|
QVERIFY(qLowerBound(list.begin(), list.end(), 9) == list.end());
|
|
QVERIFY(qUpperBound(list.begin(), list.end(), 9) == list.end());
|
|
{
|
|
int sum = 0;
|
|
QListIterator<int> i(list);
|
|
while (i.hasNext())
|
|
sum += i.next();
|
|
QVERIFY(sum == 21);
|
|
}
|
|
|
|
{
|
|
QList<int> list1;
|
|
list1 << 1 << 2 << 3 << 5 << 7 << 8 << 9;
|
|
QList<int> list2 = list1;
|
|
|
|
QMutableListIterator<int> i1(list1);
|
|
while (i1.hasNext()) {
|
|
if (i1.next() % 2 != 0)
|
|
i1.remove();
|
|
}
|
|
|
|
QMutableListIterator<int> i2(list2);
|
|
i2.toBack();
|
|
while (i2.hasPrevious()) {
|
|
if (i2.previous() % 2 != 0)
|
|
i2.remove();
|
|
}
|
|
QVERIFY(list1.size() == 2);
|
|
QVERIFY(list2.size() == 2);
|
|
QVERIFY(list1 == list2);
|
|
}
|
|
|
|
{
|
|
int sum = 0;
|
|
for (int i = 0; i < list.size(); ++i)
|
|
sum += list[i];
|
|
QVERIFY(sum == 21);
|
|
}
|
|
{
|
|
int sum = 0;
|
|
QList<int>::const_iterator i = list.begin();
|
|
while (i != list.end())
|
|
sum += *i++;
|
|
QVERIFY(sum == 21);
|
|
}
|
|
{
|
|
int sum = 0;
|
|
QList<int>::ConstIterator i = list.begin();
|
|
while (i != list.end())
|
|
sum += *i++;
|
|
QVERIFY(sum == 21);
|
|
}
|
|
{
|
|
QList<int>::Iterator i = list.begin();
|
|
i += 2;
|
|
QCOMPARE(*i, 3);
|
|
i -= 1;
|
|
QCOMPARE(*i, 2);
|
|
}
|
|
{
|
|
QList<int>::ConstIterator i = list.begin();
|
|
i += 2;
|
|
QCOMPARE(*i, 3);
|
|
i -= 1;
|
|
QCOMPARE(*i, 2);
|
|
}
|
|
{
|
|
int sum = 0;
|
|
int i;
|
|
for (i = 0; i < list.size(); ++i)
|
|
list[i] = list[i] +1;
|
|
for (i = 0; i < list.size(); ++i)
|
|
sum += list[i];
|
|
QVERIFY(sum == 21 + list.size());
|
|
}
|
|
{
|
|
int sum = 0;
|
|
int i;
|
|
for (i = 0; i < list.size(); ++i)
|
|
--list[i];
|
|
for (i = 0; i < list.size(); ++i)
|
|
sum += list[i];
|
|
QVERIFY(sum == 21);
|
|
}
|
|
{
|
|
QMutableListIterator<int> i(list);
|
|
while (i.hasNext())
|
|
i.setValue(2*i.next());
|
|
}
|
|
{
|
|
int sum = 0;
|
|
QListIterator<int> i(list);
|
|
i.toBack();
|
|
while (i.hasPrevious())
|
|
sum += i.previous();
|
|
QVERIFY(sum == 2*21);
|
|
}
|
|
{
|
|
QMutableListIterator<int> i(list);
|
|
i.toBack();
|
|
while (i.hasPrevious())
|
|
i.setValue(2*i.previous());
|
|
}
|
|
{
|
|
int sum = 0;
|
|
QListIterator<int> i(list);
|
|
i.toBack();
|
|
while (i.hasPrevious())
|
|
sum += i.previous();
|
|
QVERIFY(sum == 2*2*21);
|
|
}
|
|
{
|
|
QMutableListIterator<int> i(list);
|
|
while (i.hasNext()) {
|
|
int a = i.next();
|
|
i.insert(a);
|
|
}
|
|
}
|
|
{
|
|
int sum = 0;
|
|
QList<int>::iterator i = list.begin();
|
|
while (i != list.end())
|
|
sum += *i++;
|
|
QVERIFY(sum == 2*2*2*21);
|
|
}
|
|
{
|
|
int duplicates = 0;
|
|
QListIterator<int> i(list);
|
|
while (i.hasNext()) {
|
|
int a = i.next();
|
|
if (i.hasNext() && a == i.peekNext())
|
|
duplicates++;
|
|
}
|
|
QVERIFY(duplicates == 6);
|
|
}
|
|
{
|
|
int duplicates = 0;
|
|
QListIterator<int> i(list);
|
|
i.toBack();
|
|
while (i.hasPrevious()) {
|
|
int a = i.previous();
|
|
if (i.hasPrevious() && a == i.peekPrevious())
|
|
duplicates++;
|
|
}
|
|
QVERIFY(duplicates == 6);
|
|
}
|
|
{
|
|
QMutableListIterator<int> i(list);
|
|
while (i.hasNext()) {
|
|
int a = i.next();
|
|
if (i.hasNext() &&
|
|
i.peekNext() == a)
|
|
i.remove();
|
|
}
|
|
}
|
|
{
|
|
int duplicates = 0;
|
|
QMutableListIterator<int> i = list;
|
|
i.toBack();
|
|
while (i.hasPrevious()) {
|
|
int a = i.previous();
|
|
if (i.hasPrevious() && a == i.peekPrevious())
|
|
duplicates++;
|
|
}
|
|
QVERIFY(duplicates == 0);
|
|
}
|
|
{
|
|
QVERIFY(list.size() == 6);
|
|
QMutableListIterator<int> i = list;
|
|
while (i.hasNext()) {
|
|
int a = i.peekNext();
|
|
i.insert(42);
|
|
QVERIFY(i.peekPrevious() == 42 && i.peekNext() == a);
|
|
i.next();
|
|
}
|
|
QVERIFY(list.size() == 12);
|
|
i.toFront();
|
|
while (i.findNext(42))
|
|
i.remove();
|
|
}
|
|
{
|
|
QList<int> l;
|
|
l << 4 << 8 << 12 << 16 << 20 << 24;
|
|
QVERIFY(l == list);
|
|
QList<int> copy = list;
|
|
list += list;
|
|
QVERIFY(l != list && l.size() == list.size()/2 && l == copy);
|
|
l += copy;
|
|
QVERIFY(l == list);
|
|
list = copy;
|
|
}
|
|
{
|
|
QList<int> copy = list;
|
|
list << 8;
|
|
QVERIFY(list.indexOf(8) == 1);
|
|
QVERIFY(list.indexOf(8, list.indexOf(8)+1) == 6);
|
|
int a = list.indexOf(8);
|
|
QVERIFY(list.count(8) == 2);
|
|
int r = list.removeAll(8);
|
|
QVERIFY(r == 2);
|
|
list.insert(a, 8);
|
|
QVERIFY(list == copy);
|
|
}
|
|
{
|
|
QList<QString> list;
|
|
list << "one" << "two" << "three" << "four" << "five" << "six";
|
|
while (!list.isEmpty())
|
|
list.removeAll(list.first());
|
|
}
|
|
{
|
|
QList<QString> list;
|
|
list << "one" << "two" << "one" << "two";
|
|
QVERIFY(!list.removeOne("three"));
|
|
QVERIFY(list.removeOne("two"));
|
|
QCOMPARE(list, QList<QString>() << "one" << "one" << "two");;
|
|
QVERIFY(list.removeOne("two"));
|
|
QCOMPARE(list, QList<QString>() << "one" << "one");
|
|
QVERIFY(!list.removeOne("two"));
|
|
QCOMPARE(list, QList<QString>() << "one" << "one");
|
|
QVERIFY(list.removeOne("one"));
|
|
QCOMPARE(list, QList<QString>() << "one");
|
|
QVERIFY(list.removeOne("one"));
|
|
QVERIFY(list.isEmpty());
|
|
QVERIFY(!list.removeOne("one"));
|
|
QVERIFY(list.isEmpty());
|
|
}
|
|
{
|
|
QList<int> copy = list;
|
|
list << 8;
|
|
QVERIFY(list.lastIndexOf(8) == 6);
|
|
QVERIFY(list.lastIndexOf(8, list.lastIndexOf(8)-1) == 1);
|
|
list = copy;
|
|
}
|
|
{
|
|
QList<int> copy = list;
|
|
list.insert(3, 999);
|
|
QVERIFY(list[3] == 999);
|
|
list.replace(3, 222);
|
|
QVERIFY(list[3] == 222);
|
|
QVERIFY(list.contains(222) && ! list.contains(999));
|
|
list.removeAt(3);
|
|
list = copy;
|
|
QVERIFY(list == copy);
|
|
}
|
|
{
|
|
list.clear();
|
|
QVERIFY(list.isEmpty());
|
|
QVERIFY(list.begin() == list.end());
|
|
QListIterator<int> i(list);
|
|
QVERIFY(!i.hasNext() && !i.hasPrevious());
|
|
}
|
|
{
|
|
QList<int> l1;
|
|
QList<int> l2;
|
|
l1 << 1 << 2 << 3;
|
|
l2 << 4 << 5 << 6;
|
|
QList<int> l3 = l1 + l2;
|
|
l1 += l2;
|
|
QVERIFY(l3 == l1);
|
|
}
|
|
{
|
|
QList<int> list;
|
|
QVERIFY(list.isEmpty());
|
|
list.append(1);
|
|
QList<int> list2;
|
|
list2 = list;
|
|
list2.clear();
|
|
QVERIFY(list2.size() == 0);
|
|
QVERIFY(list.size() == 1);
|
|
}
|
|
{
|
|
QList<int> list;
|
|
list.append(1);
|
|
list = list;
|
|
QVERIFY(list.size() == 1);
|
|
}
|
|
}
|
|
{
|
|
QList<void*> list;
|
|
list.append(0);
|
|
list.append((void*)42);
|
|
QCOMPARE(list.size(), 2);
|
|
QCOMPARE(list.at(0), (void*)0);
|
|
QCOMPARE(list.at(1), (void*)42);
|
|
}
|
|
|
|
{
|
|
QVector<QString> vector(5);
|
|
vector[0] = "99";
|
|
vector[4] ="100";
|
|
QList<QString> list = vector.toList();
|
|
|
|
QVERIFY(list.size() == 5);
|
|
QVERIFY(list.at(0) == "99");
|
|
QVERIFY(list.at(4) == "100");
|
|
list[0] = "10";
|
|
QVERIFY(list.at(0) == "10");
|
|
QVERIFY(vector.at(0) == "99");
|
|
|
|
}
|
|
|
|
{
|
|
QList<QString> list;
|
|
list.append("Hello");
|
|
|
|
QList<QString>::iterator it = list.begin();
|
|
QVERIFY((*it)[0] == QChar('H'));
|
|
QVERIFY(it->constData()[0] == QChar('H'));
|
|
it->replace(QChar('H'), QChar('X'));
|
|
QVERIFY(list.first() == "Xello");
|
|
|
|
QList<QString>::const_iterator cit = list.constBegin();
|
|
QVERIFY((*cit).toLower() == "xello");
|
|
QVERIFY(cit->toUpper() == "XELLO");
|
|
}
|
|
|
|
{
|
|
QList<int *> list;
|
|
QVERIFY(list.value(0) == 0);
|
|
int i;
|
|
list.append(&i);
|
|
QVERIFY(list.value(0) == &i);
|
|
}
|
|
{
|
|
QList<const int *> list;
|
|
QVERIFY(list.value(0) == 0);
|
|
int i;
|
|
list.append(&i);
|
|
QVERIFY(list.value(0) == &i);
|
|
}
|
|
{
|
|
QList<int> list;
|
|
QVERIFY(list.value(0) == 0);
|
|
list.append(10);
|
|
QVERIFY(list.value(0) == 10);
|
|
}
|
|
{
|
|
QList<Pod> list;
|
|
QCOMPARE(list.value(0).i1, 0);
|
|
QCOMPARE(list.value(0).i2, 0);
|
|
}
|
|
|
|
{
|
|
QList<QString> list;
|
|
list << "alpha" << "beta";
|
|
list += list;
|
|
QVERIFY(list.size() == 4);
|
|
QVERIFY(list.at(0) == "alpha");
|
|
QVERIFY(list.at(1) == "beta");
|
|
QVERIFY(list.at(2) == "alpha");
|
|
QVERIFY(list.at(3) == "beta");
|
|
}
|
|
|
|
// test endcases for inserting into a qlist
|
|
{
|
|
QList<QString> list;
|
|
list << "foo" << "bar";
|
|
QVERIFY(!list.isEmpty());
|
|
|
|
list.insert(-1, "lessthanzero");
|
|
QCOMPARE(list.at(0), QString("lessthanzero"));
|
|
|
|
list.insert(0, "atzero");
|
|
QCOMPARE(list.at(0), QString("atzero"));
|
|
|
|
int listCount = list.count();
|
|
list.insert(listCount, "atcount");
|
|
QCOMPARE(list.at(listCount), QString("atcount"));
|
|
|
|
listCount = list.count();
|
|
list.insert(listCount + 1, "beyondcount");
|
|
QCOMPARE(list.at(listCount), QString("beyondcount"));
|
|
}
|
|
|
|
{
|
|
QList<int> list1;
|
|
list1 << 0 << 1 << 2 << 3;
|
|
list1.removeFirst();
|
|
|
|
list1.swap(0, 0);
|
|
QVERIFY(list1 == QList<int>() << 1 << 2 << 3);
|
|
|
|
list1.swap(1, 1);
|
|
QVERIFY(list1 == QList<int>() << 1 << 2 << 3);
|
|
|
|
list1.swap(2, 2);
|
|
QVERIFY(list1 == QList<int>() << 1 << 2 << 3);
|
|
|
|
list1.swap(0, 1);
|
|
QVERIFY(list1 == QList<int>() << 2 << 1 << 3);
|
|
|
|
list1.swap(0, 2);
|
|
QVERIFY(list1 == QList<int>() << 3 << 1 << 2);
|
|
|
|
list1.swap(1, 2);
|
|
QVERIFY(list1 == QList<int>() << 3 << 2 << 1);
|
|
|
|
list1.swap(1, 2);
|
|
QVERIFY(list1 == QList<int>() << 3 << 1 << 2);
|
|
|
|
QList<QString> list2;
|
|
list2 << "1" << "2" << "3";
|
|
|
|
list2.swap(0, 0);
|
|
QVERIFY(list2 == QList<QString>() << "1" << "2" << "3");
|
|
|
|
list2.swap(1, 1);
|
|
QVERIFY(list2 == QList<QString>() << "1" << "2" << "3");
|
|
|
|
list2.swap(2, 2);
|
|
QVERIFY(list2 == QList<QString>() << "1" << "2" << "3");
|
|
|
|
list2.swap(0, 1);
|
|
QVERIFY(list2 == QList<QString>() << "2" << "1" << "3");
|
|
|
|
list2.swap(0, 2);
|
|
QVERIFY(list2 == QList<QString>() << "3" << "1" << "2");
|
|
|
|
list2.swap(1, 2);
|
|
QVERIFY(list2 == QList<QString>() << "3" << "2" << "1");
|
|
|
|
list2.swap(1, 2);
|
|
QVERIFY(list2 == QList<QString>() << "3" << "1" << "2");
|
|
|
|
QList<double> list3;
|
|
list3 << 1.0 << 2.0 << 3.0;
|
|
|
|
list3.swap(0, 0);
|
|
QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0);
|
|
|
|
list3.swap(1, 1);
|
|
QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0);
|
|
|
|
list3.swap(2, 2);
|
|
QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0);
|
|
|
|
list3.swap(0, 1);
|
|
QVERIFY(list3 == QList<double>() << 2.0 << 1.0 << 3.0);
|
|
|
|
list3.swap(0, 2);
|
|
QVERIFY(list3 == QList<double>() << 3.0 << 1.0 << 2.0);
|
|
|
|
list3.swap(1, 2);
|
|
QVERIFY(list3 == QList<double>() << 3.0 << 2.0 << 1.0);
|
|
|
|
list3.swap(1, 2);
|
|
QVERIFY(list3 == QList<double>() << 3.0 << 1.0 << 2.0);
|
|
}
|
|
|
|
// Check what happens when using references to own items.
|
|
// Ideally we should run valgrind on this.
|
|
{
|
|
int i;
|
|
|
|
QList<void *> list1;
|
|
list1.append(reinterpret_cast<void *>(50));
|
|
|
|
for (i = 1; i < 100; ++i) {
|
|
list1.append(list1.at(i - 1));
|
|
list1.prepend(list1.at(i));
|
|
list1.insert(i, list1.at(i - 1));
|
|
list1.insert(i, list1.at(i));
|
|
list1.insert(i, list1.at(i + 1));
|
|
list1.replace(i, list1.at(i - 1));
|
|
list1.replace(i, list1.at(i));
|
|
list1.replace(i, list1.at(i + 1));
|
|
}
|
|
QCOMPARE(list1.size(), 496);
|
|
for (i = 0; i < list1.size(); ++i) {
|
|
QCOMPARE(list1.at(i), reinterpret_cast<void *>(50));
|
|
}
|
|
|
|
QList<QString> list2;
|
|
list2.append("50");
|
|
|
|
for (i = 1; i < 100; ++i) {
|
|
list2.append(list2.at(i - 1));
|
|
list2.prepend(list2.at(i));
|
|
list2.insert(i, list2.at(i - 1));
|
|
list2.insert(i, list2.at(i));
|
|
list2.insert(i, list2.at(i + 1));
|
|
list2.replace(i, list2.at(i - 1));
|
|
list2.replace(i, list2.at(i));
|
|
list2.replace(i, list2.at(i + 1));
|
|
}
|
|
QCOMPARE(list2.size(), 496);
|
|
for (i = 0; i < list2.size(); ++i) {
|
|
QCOMPARE(list2.at(i), QString::fromLatin1("50"));
|
|
}
|
|
|
|
QList<double> list3;
|
|
list3.append(50.0);
|
|
|
|
for (i = 1; i < 100; ++i) {
|
|
list3.append(list3.at(i - 1));
|
|
list3.prepend(list3.at(i));
|
|
list3.insert(i, list3.at(i - 1));
|
|
list3.insert(i, list3.at(i));
|
|
list3.insert(i, list3.at(i + 1));
|
|
list3.replace(i, list3.at(i - 1));
|
|
list3.replace(i, list3.at(i));
|
|
list3.replace(i, list3.at(i + 1));
|
|
}
|
|
QCOMPARE(list3.size(), 496);
|
|
for (i = 0; i < list3.size(); ++i) {
|
|
QCOMPARE(list3.at(i), 50.0);
|
|
}
|
|
|
|
QList<QTime> list4;
|
|
list4.append(QTime(12, 34, 56));
|
|
|
|
for (i = 1; i < 100; ++i) {
|
|
list4.append(list4.at(i - 1));
|
|
list4.prepend(list4.at(i));
|
|
list4.insert(i, list4.at(i - 1));
|
|
list4.insert(i, list4.at(i));
|
|
list4.insert(i, list4.at(i + 1));
|
|
list4.replace(i, list4.at(i - 1));
|
|
list4.replace(i, list4.at(i));
|
|
list4.replace(i, list4.at(i + 1));
|
|
}
|
|
QCOMPARE(list4.size(), 496);
|
|
for (i = 0; i < list4.size(); ++i) {
|
|
QVERIFY(list4.at(i) == QTime(12, 34, 56));
|
|
}
|
|
|
|
}
|
|
{
|
|
QList<int> a;
|
|
QCOMPARE(a.startsWith(1), false);
|
|
QCOMPARE(a.endsWith(1), false);
|
|
a.append(1);
|
|
QCOMPARE(a.startsWith(1), true);
|
|
QCOMPARE(a.startsWith(2), false);
|
|
QCOMPARE(a.endsWith(1), true);
|
|
QCOMPARE(a.endsWith(2), false);
|
|
a.append(2);
|
|
QCOMPARE(a.startsWith(1), true);
|
|
QCOMPARE(a.startsWith(2), false);
|
|
QCOMPARE(a.endsWith(1), false);
|
|
QCOMPARE(a.endsWith(2), true);
|
|
}
|
|
}
|
|
|
|
void tst_Collections::linkedList()
|
|
{
|
|
{
|
|
QLinkedList<int> list;
|
|
QVERIFY(list.isEmpty());
|
|
list.append(1);
|
|
list.push_back(2);
|
|
list += (3);
|
|
list << 4 << 5 << 6;
|
|
QVERIFY(!list.isEmpty());
|
|
QVERIFY(list.size() == 6);
|
|
{
|
|
int sum = 0;
|
|
QLinkedListIterator<int> i = list;
|
|
while (i.hasNext()) {
|
|
sum += i.next();
|
|
}
|
|
QVERIFY(sum == 21);
|
|
}
|
|
{
|
|
int sum = 0;
|
|
QLinkedList<int>::const_iterator i = list.begin();
|
|
while (i != list.end())
|
|
sum += *i++;
|
|
QVERIFY(sum == 21);
|
|
}
|
|
{
|
|
QMutableLinkedListIterator<int> i = list;
|
|
while (i.hasNext())
|
|
i.setValue(2*i.next());
|
|
}
|
|
{
|
|
int sum = 0;
|
|
QLinkedListIterator<int> i = list;
|
|
i.toBack();
|
|
while (i.hasPrevious())
|
|
sum += i.previous();
|
|
QVERIFY(sum == 2*21);
|
|
}
|
|
{
|
|
QMutableLinkedListIterator<int> i = list;
|
|
i.toBack();
|
|
while (i.hasPrevious())
|
|
i.setValue(2*i.previous());
|
|
}
|
|
{
|
|
int sum = 0;
|
|
QLinkedListIterator<int> i = list;
|
|
i.toBack();
|
|
while (i.hasPrevious())
|
|
sum += i.previous();
|
|
QVERIFY(sum == 2*2*21);
|
|
}
|
|
{
|
|
QMutableLinkedListIterator<int> i = list;
|
|
while (i.hasNext()) {
|
|
int a = i.next();
|
|
i.insert(a);
|
|
}
|
|
}
|
|
{
|
|
int sum = 0;
|
|
QLinkedList<int>::iterator i = list.begin();
|
|
while (i != list.end())
|
|
sum += *i++;
|
|
QVERIFY(sum == 2*2*2*21);
|
|
}
|
|
{
|
|
int duplicates = 0;
|
|
QLinkedListIterator<int> i = list;
|
|
while (i.hasNext()) {
|
|
int a = i.next();
|
|
if (i.hasNext() && a == i.peekNext())
|
|
duplicates++;
|
|
}
|
|
QVERIFY(duplicates == 6);
|
|
}
|
|
{
|
|
int duplicates = 0;
|
|
QLinkedListIterator<int> i = list;
|
|
i.toBack();
|
|
while (i.hasPrevious()) {
|
|
int a = i.previous();
|
|
if (i.hasPrevious() && a == i.peekPrevious())
|
|
duplicates++;
|
|
}
|
|
QVERIFY(duplicates == 6);
|
|
}
|
|
{
|
|
QMutableLinkedListIterator<int> i = list;
|
|
while (i.hasNext()) {
|
|
int a = i.next();
|
|
if (i.hasNext() &&
|
|
i.peekNext() == a)
|
|
i.remove();
|
|
}
|
|
}
|
|
{
|
|
int duplicates = 0;
|
|
QMutableLinkedListIterator<int> i = list;
|
|
i.toBack();
|
|
while (i.hasPrevious()) {
|
|
int a = i.previous();
|
|
if (i.hasPrevious() && a == i.peekPrevious())
|
|
duplicates++;
|
|
}
|
|
QVERIFY(duplicates == 0);
|
|
}
|
|
{
|
|
QVERIFY(list.size() == 6);
|
|
QMutableLinkedListIterator<int> i = list;
|
|
while (i.hasNext()) {
|
|
int a = i.peekNext();
|
|
i.insert(42);
|
|
QVERIFY(i.peekPrevious() == 42 && i.peekNext() == a);
|
|
i.next();
|
|
}
|
|
QVERIFY(list.size() == 12);
|
|
i.toFront();
|
|
while (i.findNext(42))
|
|
i.remove();
|
|
}
|
|
{
|
|
QLinkedList<int> l;
|
|
l << 4 << 8 << 12 << 16 << 20 << 24;
|
|
QVERIFY(l == list);
|
|
QLinkedList<int> copy = list;
|
|
list += list;
|
|
QVERIFY(l != list && l.size() == list.size()/2 && l == copy);
|
|
l += copy;
|
|
QVERIFY(l == list);
|
|
list = copy;
|
|
}
|
|
{
|
|
QLinkedList<int> copy = list;
|
|
list.prepend(999);
|
|
list.append(999);
|
|
QVERIFY(list.contains(999));
|
|
QVERIFY(list.count(999) == 2);
|
|
list.removeAll(999);
|
|
QVERIFY(list == copy);
|
|
}
|
|
{
|
|
QLinkedList<QString> list;
|
|
list << "one" << "two" << "three" << "four" << "five" << "six";
|
|
while (!list.isEmpty())
|
|
list.removeAll(list.first());
|
|
}
|
|
{
|
|
QLinkedList<QString> list;
|
|
list << "one" << "two" << "one" << "two";
|
|
QVERIFY(!list.removeOne("three"));
|
|
QVERIFY(list.removeOne("two"));
|
|
QCOMPARE(list, QLinkedList<QString>() << "one" << "one" << "two");;
|
|
QVERIFY(list.removeOne("two"));
|
|
QCOMPARE(list, QLinkedList<QString>() << "one" << "one");
|
|
QVERIFY(!list.removeOne("two"));
|
|
QCOMPARE(list, QLinkedList<QString>() << "one" << "one");
|
|
QVERIFY(list.removeOne("one"));
|
|
QCOMPARE(list, QLinkedList<QString>() << "one");
|
|
QVERIFY(list.removeOne("one"));
|
|
QVERIFY(list.isEmpty());
|
|
QVERIFY(!list.removeOne("one"));
|
|
QVERIFY(list.isEmpty());
|
|
}
|
|
{
|
|
list.clear();
|
|
QVERIFY(list.isEmpty());
|
|
QVERIFY(list.begin() == list.end());
|
|
QLinkedListIterator<int> i(list);
|
|
QVERIFY(!i.hasNext() && !i.hasPrevious());
|
|
}
|
|
}
|
|
|
|
{
|
|
QLinkedList<QString> list;
|
|
list.append("Hello");
|
|
|
|
QLinkedList<QString>::iterator it = list.begin();
|
|
QVERIFY((*it)[0] == QChar('H'));
|
|
QVERIFY(it->constData()[0] == QChar('H'));
|
|
it->replace(QChar('H'), QChar('X'));
|
|
QVERIFY(list.first() == "Xello");
|
|
|
|
QLinkedList<QString>::const_iterator cit = list.constBegin();
|
|
QVERIFY((*cit).toLower() == "xello");
|
|
QVERIFY(cit->toUpper() == "XELLO");
|
|
}
|
|
|
|
{
|
|
QLinkedList<QString> list;
|
|
list << "alpha" << "beta";
|
|
list += list;
|
|
QVERIFY(list.size() == 4);
|
|
QVERIFY(*list.begin() == "alpha");
|
|
QVERIFY(*(list.begin() + 1) == "beta");
|
|
QVERIFY(*(list.begin() + 2) == "alpha");
|
|
QVERIFY(*(list.begin() + 3) == "beta");
|
|
}
|
|
|
|
{
|
|
QLinkedList<int> a;
|
|
QCOMPARE(a.startsWith(1), false);
|
|
QCOMPARE(a.endsWith(1), false);
|
|
a.append(1);
|
|
QCOMPARE(a.startsWith(1), true);
|
|
QCOMPARE(a.startsWith(2), false);
|
|
QCOMPARE(a.endsWith(1), true);
|
|
QCOMPARE(a.endsWith(2), false);
|
|
a.append(2);
|
|
QCOMPARE(a.startsWith(1), true);
|
|
QCOMPARE(a.startsWith(2), false);
|
|
QCOMPARE(a.endsWith(1), false);
|
|
QCOMPARE(a.endsWith(2), true);
|
|
}
|
|
};
|
|
|
|
|
|
void tst_Collections::vector()
|
|
{
|
|
QVector<int> v1;
|
|
v1 << 1 << 2 << 3;
|
|
QVector<int> v2;
|
|
v2 << 4 << 5;
|
|
QVector<int> v3;
|
|
v3 << 1 << 2 << 3 << 4 << 5;
|
|
QVERIFY(v1 + v2 == v3);
|
|
|
|
QVector<int> emptyVector;
|
|
QCOMPARE(emptyVector.size(), 0);
|
|
#if 0
|
|
// this should trigger an assert
|
|
emptyVector.remove(3, -3);
|
|
QCOMPARE(emptyVector.size(), 0);
|
|
#endif
|
|
emptyVector.remove(0, 0);
|
|
QCOMPARE(emptyVector.size(), 0);
|
|
|
|
QVector<int> v4;
|
|
v4 << 1 << 2 << 3;
|
|
QCOMPARE(v4.size(), 3);
|
|
v4.remove(1, 0);
|
|
QCOMPARE(v4.size(), 3);
|
|
|
|
QVector<int> v;
|
|
v.append(2);
|
|
QVERIFY(*v.begin() == 2);
|
|
v.prepend(1);
|
|
|
|
v << 3 << 4 << 5 << 6;
|
|
#if !defined(QT_NO_STL)
|
|
QVERIFY(std::binary_search(v.begin(), v.end(), 2) == true);
|
|
QVERIFY(std::binary_search(v.begin(), v.end(), 9) == false);
|
|
#endif
|
|
QVERIFY(qBinaryFind(v.begin(), v.end(), 2) == v.begin() + 1);
|
|
QVERIFY(qLowerBound(v.begin(), v.end(), 2) == v.begin() + 1);
|
|
QVERIFY(qUpperBound(v.begin(), v.end(), 2) == v.begin() + 2);
|
|
QVERIFY(qBinaryFind(v.begin(), v.end(), 9) == v.end());
|
|
QVERIFY(qLowerBound(v.begin(), v.end(), 9) == v.end());
|
|
QVERIFY(qUpperBound(v.begin(), v.end(), 9) == v.end());
|
|
|
|
v.clear();
|
|
v << 1 << 2 << 3;
|
|
v.insert(v.begin(), 0);
|
|
v.insert(v.end(), 4);
|
|
v.insert(v.begin()+2, 9);
|
|
|
|
QVector<int> result;
|
|
result << 0 << 1 << 9 << 2 << 3 << 4;
|
|
|
|
QVERIFY( v == result );
|
|
|
|
v.clear();
|
|
v << 1 << 2 << 3;
|
|
v.insert(0, 0);
|
|
v.insert(4, 4);
|
|
v.insert(2, 9);
|
|
|
|
QVERIFY( v == result );
|
|
|
|
QVector<QString> vec;
|
|
vec << "foo" << "bar";
|
|
vec.reserve( 512 );
|
|
QVERIFY(vec[0] == "foo");
|
|
QVERIFY(vec[1] == "bar");
|
|
|
|
int initialLargeStaticCount = LargeStatic::count;
|
|
{
|
|
QVector<LargeStatic> vector;
|
|
vector.append(LargeStatic());
|
|
vector.resize(0);
|
|
}
|
|
QCOMPARE(LargeStatic::count, initialLargeStaticCount);
|
|
|
|
{
|
|
QVector<QString> vector;
|
|
vector << "alpha" << "beta";
|
|
vector += vector;
|
|
QVERIFY(vector.size() == 4);
|
|
QVERIFY(vector.at(0) == "alpha");
|
|
QVERIFY(vector.at(1) == "beta");
|
|
QVERIFY(vector.at(2) == "alpha");
|
|
QVERIFY(vector.at(3) == "beta");
|
|
}
|
|
|
|
int originalLargeStaticCount = LargeStatic::count;
|
|
{
|
|
QVector<LargeStatic> vector(5);
|
|
}
|
|
QVERIFY(LargeStatic::count == originalLargeStaticCount);
|
|
{
|
|
QVector<LargeStatic> vector(5);
|
|
QList<LargeStatic> list = vector.toList();
|
|
}
|
|
QVERIFY(LargeStatic::count == originalLargeStaticCount);
|
|
{
|
|
QVector<LargeStatic> vector;
|
|
LargeStatic *dummy = 0;
|
|
for (int i = 0; i < 10000; ++i) {
|
|
delete dummy;
|
|
dummy = new LargeStatic;
|
|
vector.append(LargeStatic());
|
|
}
|
|
delete dummy;
|
|
}
|
|
QVERIFY(LargeStatic::count == originalLargeStaticCount);
|
|
|
|
int originalMovableCount = Movable::count;
|
|
{
|
|
QVector<Movable> vector(5);
|
|
}
|
|
QVERIFY(Movable::count == originalMovableCount);
|
|
{
|
|
QVector<Movable> vector(5);
|
|
QList<Movable> list = vector.toList();
|
|
}
|
|
QVERIFY(Movable::count == originalMovableCount);
|
|
{
|
|
QVector<Movable> vector;
|
|
Movable *dummy = 0;
|
|
for (int i = 0; i < 10000; ++i) {
|
|
delete dummy;
|
|
dummy = new Movable;
|
|
vector.append(Movable());
|
|
}
|
|
delete dummy;
|
|
}
|
|
QVERIFY(Movable::count == originalMovableCount);
|
|
|
|
// Check what happens when using references to own items.
|
|
// Ideally we should run valgrind on this.
|
|
{
|
|
int i;
|
|
|
|
QVector<void *> vect1;
|
|
vect1.append(reinterpret_cast<void *>(50));
|
|
|
|
for (i = 1; i < 100; ++i) {
|
|
vect1.append(vect1.at(i - 1));
|
|
vect1.prepend(vect1.at(i));
|
|
vect1.insert(i, vect1.at(i - 1));
|
|
vect1.insert(i, vect1.at(i));
|
|
vect1.insert(i, vect1.at(i + 1));
|
|
vect1.replace(i, vect1.at(i - 1));
|
|
vect1.replace(i, vect1.at(i));
|
|
vect1.replace(i, vect1.at(i + 1));
|
|
}
|
|
QCOMPARE(vect1.size(), 496);
|
|
for (i = 0; i < vect1.size(); ++i) {
|
|
QCOMPARE(vect1.at(i), reinterpret_cast<void *>(50));
|
|
}
|
|
|
|
QVector<QString> vect2;
|
|
vect2.append("50");
|
|
|
|
for (i = 1; i < 100; ++i) {
|
|
vect2.append(vect2.at(i - 1));
|
|
vect2.prepend(vect2.at(i));
|
|
vect2.insert(i, vect2.at(i - 1));
|
|
vect2.insert(i, vect2.at(i));
|
|
vect2.insert(i, vect2.at(i + 1));
|
|
vect2.replace(i, vect2.at(i - 1));
|
|
vect2.replace(i, vect2.at(i));
|
|
vect2.replace(i, vect2.at(i + 1));
|
|
}
|
|
QCOMPARE(vect2.size(), 496);
|
|
for (i = 0; i < vect2.size(); ++i) {
|
|
QCOMPARE(vect2.at(i), QString::fromLatin1("50"));
|
|
}
|
|
|
|
QVector<double> vect3;
|
|
vect3.append(50.0);
|
|
|
|
for (i = 1; i < 100; ++i) {
|
|
vect3.append(vect3.at(i - 1));
|
|
vect3.prepend(vect3.at(i));
|
|
vect3.insert(i, vect3.at(i - 1));
|
|
vect3.insert(i, vect3.at(i));
|
|
vect3.insert(i, vect3.at(i + 1));
|
|
vect3.replace(i, vect3.at(i - 1));
|
|
vect3.replace(i, vect3.at(i));
|
|
vect3.replace(i, vect3.at(i + 1));
|
|
}
|
|
QCOMPARE(vect3.size(), 496);
|
|
for (i = 0; i < vect3.size(); ++i) {
|
|
QCOMPARE(vect3.at(i), 50.0);
|
|
}
|
|
|
|
QVector<QTime> vect4;
|
|
vect4.append(QTime(12, 34, 56));
|
|
|
|
for (i = 1; i < 100; ++i) {
|
|
vect4.append(vect4.at(i - 1));
|
|
vect4.prepend(vect4.at(i));
|
|
vect4.insert(i, vect4.at(i - 1));
|
|
vect4.insert(i, vect4.at(i));
|
|
vect4.insert(i, vect4.at(i + 1));
|
|
vect4.replace(i, vect4.at(i - 1));
|
|
vect4.replace(i, vect4.at(i));
|
|
vect4.replace(i, vect4.at(i + 1));
|
|
}
|
|
QCOMPARE(vect4.size(), 496);
|
|
for (i = 0; i < vect4.size(); ++i) {
|
|
QVERIFY(vect4.at(i) == QTime(12, 34, 56));
|
|
}
|
|
}
|
|
|
|
// this used to trigger an uninitialized read in valgrind
|
|
QVector<char> foo;
|
|
foo.resize(144);
|
|
|
|
{
|
|
QVector<int> a;
|
|
QCOMPARE(a.startsWith(1), false);
|
|
QCOMPARE(a.endsWith(1), false);
|
|
a.append(1);
|
|
QCOMPARE(a.startsWith(1), true);
|
|
QCOMPARE(a.startsWith(2), false);
|
|
QCOMPARE(a.endsWith(1), true);
|
|
QCOMPARE(a.endsWith(2), false);
|
|
a.append(2);
|
|
QCOMPARE(a.startsWith(1), true);
|
|
QCOMPARE(a.startsWith(2), false);
|
|
QCOMPARE(a.endsWith(1), false);
|
|
QCOMPARE(a.endsWith(2), true);
|
|
}
|
|
}
|
|
|
|
void tst_Collections::byteArray()
|
|
{
|
|
QByteArray hello = "hello";
|
|
QByteArray ello = "ello";
|
|
QByteArray World = "World";
|
|
QByteArray Wor = "Wor";
|
|
QByteArray helloWorld = "helloWorld";
|
|
QVERIFY(hello + World == helloWorld);
|
|
QVERIFY(hello + "World" == helloWorld);
|
|
QVERIFY("hello" + World == helloWorld);
|
|
|
|
|
|
QByteArray l;
|
|
QVERIFY('h' + ello == hello);
|
|
QVERIFY(Wor + 'l' + 'd' == "World");
|
|
QVERIFY(hello + World == "helloWorld");
|
|
QVERIFY(hello + "World" == "helloWorld");
|
|
QVERIFY("hello" + World == "helloWorld");
|
|
QVERIFY('h' + ello == "hello");
|
|
QVERIFY(Wor + 'l' + 'd' == "World");
|
|
QVERIFY("helloWorld" == hello + World);
|
|
QVERIFY("helloWorld" == hello + "World");
|
|
QVERIFY("helloWorld" == "hello" + World);
|
|
QVERIFY("hello" == 'h' + ello);
|
|
QVERIFY("World" == Wor + 'l' + 'd');
|
|
|
|
QVERIFY(hello.contains('e'));
|
|
QVERIFY (true == hello.contains('e'));
|
|
QVERIFY (hello.contains('e') != false);
|
|
|
|
QVERIFY(hello.indexOf('e') == 1);
|
|
QVERIFY(hello.indexOf('e', -10) == 1);
|
|
QVERIFY(hello.indexOf('l') == 2);
|
|
QVERIFY(hello.indexOf('l',2) == 2);
|
|
QVERIFY(hello.indexOf('l',3) == 3);
|
|
|
|
QByteArray large = "000 100 200 300 400 500 600 700 800 900";
|
|
|
|
QVERIFY(large.indexOf("700") == 28);
|
|
QVERIFY(large.indexOf("700", 28) == 28);
|
|
QVERIFY(large.indexOf("700", 29) == -1);
|
|
QVERIFY(large.lastIndexOf("700") == 28);
|
|
QVERIFY(large.lastIndexOf("700", 28) == 28);
|
|
QVERIFY(large.lastIndexOf("700", 27) == -1);
|
|
|
|
QVERIFY(large.contains("200"));
|
|
QVERIFY(!large.contains("201"));
|
|
QVERIFY(large.contains('3'));
|
|
QVERIFY(!large.contains('a'));
|
|
|
|
QVERIFY(large.count("00") == 11);
|
|
QVERIFY(large.count('3') == 1);
|
|
QVERIFY(large.count('0') == 21);
|
|
QVERIFY(large.count("0") == 21);
|
|
QVERIFY(large.count("200") == 1);
|
|
QVERIFY(large.count("201") == 0);
|
|
|
|
QVERIFY(hello.left(0) == "");
|
|
QVERIFY(!hello.left(0).isNull());
|
|
QVERIFY(hello.left(1) == "h");
|
|
QVERIFY(hello.left(2) == "he");
|
|
QVERIFY(hello.left(200) == "hello");
|
|
QVERIFY(hello.left(hello.size()) == hello);
|
|
QVERIFY(hello.left(hello.size()+1) == hello);
|
|
|
|
QVERIFY(hello.right(0) == "");
|
|
QVERIFY(!hello.right(0).isNull());
|
|
QVERIFY(hello.right(1) == "o");
|
|
QVERIFY(hello.right(2) == "lo");
|
|
QVERIFY(hello.right(200) == "hello");
|
|
QVERIFY(hello.right(hello.size()) == hello);
|
|
QVERIFY(hello.right(hello.size()+1) == hello);
|
|
|
|
QVERIFY(!hello.mid(0, 0).isNull());
|
|
QVERIFY(hello.mid(0, 1) == "h");
|
|
QVERIFY(hello.mid(0, 2) == "he");
|
|
QVERIFY(hello.mid(0, 200) == "hello");
|
|
QVERIFY(hello.mid(0) == "hello");
|
|
QVERIFY(hello.mid(0, hello.size()) == hello);
|
|
QVERIFY(hello.mid(0, hello.size()+1) == hello);
|
|
|
|
QVERIFY(hello.mid(hello.size()-0) == "");
|
|
|
|
QVERIFY(hello.mid(hello.size()-0).isNull()); // weird but valid 3.x semantics
|
|
QVERIFY(hello.mid(hello.size()-1) == "o");
|
|
QVERIFY(hello.mid(hello.size()-2) == "lo");
|
|
QVERIFY(hello.mid(hello.size()-200) == "hello");
|
|
|
|
QByteArray null;
|
|
QByteArray nonNull = "";
|
|
QVERIFY(null.left(10).isNull());
|
|
QVERIFY(null.mid(0).isNull());
|
|
|
|
#if 0
|
|
QVERIFY(null == QByteArray::null);
|
|
QVERIFY(QByteArray::null == null);
|
|
QVERIFY(nonNull != QByteArray::null);
|
|
QVERIFY(QByteArray::null != nonNull);
|
|
QVERIFY(null == nonNull);
|
|
QVERIFY(QByteArray::null == QByteArray::null);
|
|
#endif
|
|
|
|
QByteArray str = "Hello";
|
|
QByteArray cstr(str.data(), str.size());
|
|
QVERIFY(str == "Hello");
|
|
QVERIFY(cstr == "Hello");
|
|
cstr.clear();
|
|
QVERIFY(str == "Hello");
|
|
QVERIFY(cstr.isEmpty());
|
|
|
|
{
|
|
QByteArray ba1("Foo");
|
|
ba1.prepend(ba1);
|
|
QCOMPARE(ba1, QByteArray("FooFoo"));
|
|
ba1.append(ba1);
|
|
QCOMPARE(ba1, QByteArray("FooFooFooFoo"));
|
|
ba1.insert(2, ba1);
|
|
QCOMPARE(ba1, QByteArray("FoFooFooFooFoooFooFooFoo"));
|
|
ba1.replace(3, 3, ba1);
|
|
QCOMPARE(ba1, QByteArray("FoFFoFooFooFooFoooFooFooFooooFooFoooFooFooFoo"));
|
|
ba1 = "FooFoo";
|
|
ba1.replace(char('F'), ba1);
|
|
QCOMPARE(ba1, QByteArray("FooFooooFooFoooo"));
|
|
ba1 = "FooFoo";
|
|
ba1.replace(char('o'), ba1);
|
|
QCOMPARE(ba1, QByteArray("FFooFooFooFooFFooFooFooFoo"));
|
|
|
|
ba1.replace(ba1, "xxx");
|
|
QCOMPARE(ba1, QByteArray("xxx"));
|
|
ba1.replace(ba1, QByteArray("yyy"));
|
|
QCOMPARE(ba1, QByteArray("yyy"));
|
|
ba1 += ba1;
|
|
QCOMPARE(ba1, QByteArray("yyyyyy"));
|
|
|
|
ba1.remove(1, -1); // do nothing
|
|
QCOMPARE(ba1, QByteArray("yyyyyy"));
|
|
|
|
ba1.replace(0, -1, "ZZZ");
|
|
QCOMPARE(ba1, QByteArray("ZZZyyyyyy"));
|
|
}
|
|
};
|
|
|
|
void tst_Collections::stack()
|
|
{
|
|
QStack<int> stack;
|
|
stack.push(1);
|
|
stack.push(2);
|
|
stack.push(3);
|
|
QVectorIterator<int> i = stack;
|
|
i.toBack();
|
|
int sum = 0;
|
|
while (i.hasPrevious())
|
|
sum += i.previous();
|
|
QVERIFY(sum == 6);
|
|
|
|
sum = 0;
|
|
for (QStack<int>::iterator i = stack.begin(); i != stack.end(); ++i)
|
|
sum += *i;
|
|
QVERIFY(sum == 6);
|
|
|
|
while (!stack.isEmpty())
|
|
sum -= stack.pop();
|
|
QVERIFY(sum == 0);
|
|
}
|
|
|
|
void tst_Collections::hash()
|
|
{
|
|
const char *hello = "hello";
|
|
const char *world = "world";
|
|
const char *allo = "allo";
|
|
const char *monde = "monde";
|
|
|
|
{
|
|
typedef QHash<QString, QString> Hash;
|
|
Hash hash;
|
|
QString key;
|
|
for (int i = 0; i < 10; ++i) {
|
|
key[0] = i + '0';
|
|
for (int j = 0; j < 10; ++j) {
|
|
key[1] = j + '0';
|
|
hash.insert(key, "V" + key);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < 10; ++i) {
|
|
key[0] = i + '0';
|
|
for (int j = 0; j < 10; ++j) {
|
|
key[1] = j + '0';
|
|
hash.remove(key);
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
typedef QHash<int, const char *> Hash;
|
|
Hash hash;
|
|
hash.insert(1, hello);
|
|
hash.insert(2, world);
|
|
|
|
QVERIFY(hash.size() == 2);
|
|
QVERIFY(!hash.isEmpty());
|
|
|
|
{
|
|
Hash hash2 = hash;
|
|
hash2 = hash;
|
|
hash = hash2;
|
|
hash2 = hash2;
|
|
hash = hash;
|
|
hash2.clear();
|
|
hash2 = hash2;
|
|
QVERIFY(hash2.size() == 0);
|
|
QVERIFY(hash2.isEmpty());
|
|
}
|
|
QVERIFY(hash.size() == 2);
|
|
|
|
{
|
|
Hash hash2 = hash;
|
|
hash2[1] = allo;
|
|
hash2[2] = monde;
|
|
|
|
QVERIFY(hash2[1] == allo);
|
|
QVERIFY(hash2[2] == monde);
|
|
QVERIFY(hash[1] == hello);
|
|
QVERIFY(hash[2] == world);
|
|
|
|
hash2[1] = hash[1];
|
|
hash2[2] = hash[2];
|
|
|
|
QVERIFY(hash2[1] == hello);
|
|
QVERIFY(hash2[2] == world);
|
|
|
|
hash[1] = hash[1];
|
|
QVERIFY(hash[1] == hello);
|
|
}
|
|
|
|
{
|
|
Hash hash2 = hash;
|
|
hash2.detach();
|
|
hash2.remove(1);
|
|
QVERIFY(hash2.size() == 1);
|
|
hash2.remove(1);
|
|
QVERIFY(hash2.size() == 1);
|
|
hash2.remove(0);
|
|
QVERIFY(hash2.size() == 1);
|
|
hash2.remove(2);
|
|
QVERIFY(hash2.size() == 0);
|
|
QVERIFY(hash.size() == 2);
|
|
}
|
|
|
|
hash.detach();
|
|
|
|
{
|
|
Hash::iterator it1 = hash.find(1);
|
|
QVERIFY(it1 != hash.end());
|
|
|
|
Hash::iterator it2 = hash.find(0);
|
|
QVERIFY(it2 != hash.begin());
|
|
QVERIFY(it2 == hash.end());
|
|
|
|
*it1 = monde;
|
|
QVERIFY(*it1 == monde);
|
|
QVERIFY(hash[1] == monde);
|
|
|
|
*it1 = hello;
|
|
QVERIFY(*it1 == hello);
|
|
QVERIFY(hash[1] == hello);
|
|
|
|
hash[1] = monde;
|
|
QVERIFY(it1.key() == 1);
|
|
QVERIFY(it1.value() == monde);
|
|
QVERIFY(*it1 == monde);
|
|
QVERIFY(hash[1] == monde);
|
|
|
|
hash[1] = hello;
|
|
QVERIFY(*it1 == hello);
|
|
QVERIFY(hash[1] == hello);
|
|
}
|
|
|
|
{
|
|
const Hash hash2 = hash;
|
|
|
|
Hash::const_iterator it1 = hash2.find(1);
|
|
QVERIFY(it1 != hash2.end());
|
|
QVERIFY(it1.key() == 1);
|
|
QVERIFY(it1.value() == hello);
|
|
QVERIFY(*it1 == hello);
|
|
|
|
Hash::const_iterator it2 = hash2.find(2);
|
|
QVERIFY(it1 != it2);
|
|
QVERIFY(it1 != hash2.end());
|
|
QVERIFY(it2 != hash2.end());
|
|
|
|
int count = 0;
|
|
it1 = hash2.begin();
|
|
while (it1 != hash2.end()) {
|
|
count++;
|
|
++it1;
|
|
}
|
|
QVERIFY(count == 2);
|
|
|
|
count = 0;
|
|
it1 = hash.begin();
|
|
while (it1 != hash.end()) {
|
|
count++;
|
|
++it1;
|
|
}
|
|
QVERIFY(count == 2);
|
|
}
|
|
|
|
{
|
|
QVERIFY(hash.contains(1));
|
|
QVERIFY(hash.contains(2));
|
|
QVERIFY(!hash.contains(0));
|
|
QVERIFY(!hash.contains(3));
|
|
}
|
|
|
|
{
|
|
QVERIFY(hash.value(1) == hello);
|
|
QVERIFY(hash.value(2) == world);
|
|
QVERIFY(hash.value(3) == 0);
|
|
QVERIFY(hash.value(1, allo) == hello);
|
|
QVERIFY(hash.value(2, allo) == world);
|
|
QVERIFY(hash.value(3, allo) == allo);
|
|
QVERIFY(hash.value(0, monde) == monde);
|
|
}
|
|
|
|
{
|
|
QHash<int,LargeStatic> hash;
|
|
for (int i = 0; i < 10; i++)
|
|
hash.insert(i, LargeStatic());
|
|
QVERIFY(LargeStatic::count == 10);
|
|
hash.remove(7);
|
|
QVERIFY(LargeStatic::count == 9);
|
|
|
|
}
|
|
QVERIFY(LargeStatic::count == 0);
|
|
{
|
|
QHash<int, int*> hash;
|
|
QVERIFY(((const QHash<int,int*>*) &hash)->operator[](7) == 0);
|
|
}
|
|
|
|
{
|
|
/*
|
|
This test relies on a certain implementation of
|
|
QHash. If you change the way QHash works internally,
|
|
change this test as well.
|
|
*/
|
|
QHash<int, int> hash;
|
|
for (int i = 0; i < 1000; ++i)
|
|
hash.insert(i, i);
|
|
QVERIFY(hash.capacity() == 1031);
|
|
hash.squeeze();
|
|
QVERIFY(hash.capacity() == 521);
|
|
|
|
hash.insert(12345, 12345);
|
|
QVERIFY(hash.capacity() == 1031);
|
|
|
|
for (int j = 0; j < 900; ++j)
|
|
hash.remove(j);
|
|
QVERIFY(hash.capacity() == 257);
|
|
hash.squeeze();
|
|
QVERIFY(hash.capacity() == 67);
|
|
hash.reserve(0);
|
|
}
|
|
}
|
|
|
|
{
|
|
QHash<int, QString> hash;
|
|
hash.insert(0, "Hello");
|
|
|
|
QHash<int, QString>::iterator it = hash.begin();
|
|
QVERIFY((*it)[0] == QChar('H'));
|
|
QVERIFY(it->constData()[0] == QChar('H'));
|
|
it->replace(QChar('H'), QChar('X'));
|
|
QVERIFY(*hash.begin() == "Xello");
|
|
|
|
QHash<int, QString>::const_iterator cit = hash.constBegin();
|
|
QVERIFY((*cit).toLower() == "xello");
|
|
QVERIFY(cit->toUpper() == "XELLO");
|
|
}
|
|
|
|
{
|
|
QHash<int, QString> hash1, hash2;
|
|
hash1.insertMulti(1, "Alpha");
|
|
hash1.insertMulti(1, "Gamma");
|
|
hash2.insertMulti(1, "Beta");
|
|
hash2.insertMulti(1, "Gamma");
|
|
hash2.insertMulti(1, "Gamma");
|
|
|
|
hash1.unite(hash2);
|
|
QCOMPARE(hash1.size(), 5);
|
|
QCOMPARE(hash1.values(),
|
|
(QList<QString>() << "Gamma" << "Gamma" << "Beta" << "Gamma" << "Alpha"));
|
|
|
|
hash2 = hash1;
|
|
hash2.unite(hash2);
|
|
QCOMPARE(hash2.size(), 10);
|
|
QCOMPARE(hash2.values(), hash1.values() + hash1.values());
|
|
}
|
|
|
|
#if 0
|
|
{
|
|
QMultiHash<QString, int> hash1;
|
|
hash1.insert("1", 2);
|
|
hash1.insert("1", 1);
|
|
hash1.insert("a", 3);
|
|
hash1.insert("a", 2);
|
|
hash1.insert("a", 1);
|
|
hash1.insert("b", 2);
|
|
hash1.insert("b", 1);
|
|
|
|
// hash1: [ "1" -> 1, "1" -> 2, "a" -> 1, "a" -> 2, "a" -> 3, "b" -> 1, "b" -> 2 ]
|
|
|
|
QHashIterator<QString, int> i1(hash1);
|
|
i1.toBack();
|
|
|
|
bool found;
|
|
|
|
found = i1.findPreviousKey("1");
|
|
QVERIFY(found && i1.value() == 2);
|
|
|
|
found = i1.findPreviousKey("1");
|
|
QVERIFY(found && i1.value() == 1);
|
|
|
|
found = i1.findPreviousKey("1");
|
|
QVERIFY(!found);
|
|
|
|
i1.toFront();
|
|
found = i1.findNextKey("1");
|
|
QVERIFY(found && i1.value() == 1);
|
|
|
|
found = i1.findNextKey("1");
|
|
QVERIFY(found && i1.value() == 2);
|
|
|
|
found = i1.findNextKey("1");
|
|
QVERIFY(!found);
|
|
|
|
i1.toBack();
|
|
found = i1.findPreviousKey("b");
|
|
QVERIFY(found && i1.value() == 2);
|
|
|
|
found = i1.findPreviousKey("b");
|
|
QVERIFY(found && i1.value() == 1);
|
|
|
|
found = i1.findPreviousKey("b");
|
|
QVERIFY(!found);
|
|
|
|
i1.toFront();
|
|
found = i1.findNextKey("b");
|
|
QVERIFY(found && i1.value() == 1);
|
|
|
|
found = i1.findNextKey("b");
|
|
QVERIFY(found && i1.value() == 2);
|
|
|
|
found = i1.findNextKey("b");
|
|
QVERIFY(!found);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void tst_Collections::map()
|
|
{
|
|
const char *hello = "hello";
|
|
const char *world = "world";
|
|
const char *allo = "allo";
|
|
const char *monde = "monde";
|
|
|
|
{
|
|
typedef QMap<int, const char *> Map;
|
|
Map map;
|
|
map.insert(1, hello);
|
|
map.insert(2, world);
|
|
|
|
QVERIFY(*map.begin() == hello);
|
|
|
|
QVERIFY(map.size() == 2);
|
|
QVERIFY(!map.isEmpty());
|
|
|
|
{
|
|
Map map2 = map;
|
|
map2 = map;
|
|
map = map2;
|
|
map2 = map2;
|
|
map = map;
|
|
map2.clear();
|
|
map2 = map2;
|
|
QVERIFY(map2.size() == 0);
|
|
QVERIFY(map2.isEmpty());
|
|
}
|
|
QVERIFY(map.size() == 2);
|
|
|
|
{
|
|
Map map2 = map;
|
|
map2[1] = allo;
|
|
map2[2] = monde;
|
|
|
|
QVERIFY(map2[1] == allo);
|
|
QVERIFY(map2[2] == monde);
|
|
QVERIFY(map[1] == hello);
|
|
QVERIFY(map[2] == world);
|
|
|
|
map2[1] = map[1];
|
|
map2[2] = map[2];
|
|
|
|
QVERIFY(map2[1] == hello);
|
|
QVERIFY(map2[2] == world);
|
|
|
|
map[1] = map[1];
|
|
QVERIFY(map[1] == hello);
|
|
}
|
|
|
|
{
|
|
Map map2 = map;
|
|
map2.detach();
|
|
map2.remove(1);
|
|
QVERIFY(map2.size() == 1);
|
|
map2.remove(1);
|
|
QVERIFY(map2.size() == 1);
|
|
map2.remove(0);
|
|
QVERIFY(map2.size() == 1);
|
|
map2.remove(2);
|
|
QVERIFY(map2.size() == 0);
|
|
QVERIFY(map.size() == 2);
|
|
}
|
|
|
|
map.detach();
|
|
|
|
{
|
|
Map::iterator it1 = map.find(1);
|
|
QVERIFY(it1 == map.begin());
|
|
QVERIFY(it1 != map.end());
|
|
|
|
Map::iterator it2 = map.find(0);
|
|
QVERIFY(it2 != map.begin());
|
|
QVERIFY(it2 == map.end());
|
|
|
|
*it1 = monde;
|
|
QVERIFY(*it1 == monde);
|
|
QVERIFY(map[1] == monde);
|
|
|
|
*it1 = hello;
|
|
QVERIFY(*it1 == hello);
|
|
QVERIFY(map[1] == hello);
|
|
|
|
map[1] = monde;
|
|
QVERIFY(it1.key() == 1);
|
|
QVERIFY(it1.value() == monde);
|
|
QVERIFY(*it1 == monde);
|
|
QVERIFY(map[1] == monde);
|
|
|
|
map[1] = hello;
|
|
QVERIFY(*it1 == hello);
|
|
QVERIFY(map[1] == hello);
|
|
|
|
*++it1 = allo;
|
|
QVERIFY(*it1 == allo);
|
|
QVERIFY(map[2] == allo);
|
|
*it1 = world;
|
|
|
|
++it1;
|
|
QVERIFY(it1 == map.end());
|
|
|
|
int count = 0;
|
|
it1 = map.begin();
|
|
while (it1 != map.end()) {
|
|
count++;
|
|
++it1;
|
|
}
|
|
QVERIFY(count == 2);
|
|
}
|
|
|
|
{
|
|
const Map map2 = map;
|
|
|
|
Map::const_iterator it1 = map2.find(1);
|
|
QVERIFY(it1 != map2.end());
|
|
QVERIFY(it1.key() == 1);
|
|
QVERIFY(it1.value() == hello);
|
|
QVERIFY(*it1 == hello);
|
|
++it1;
|
|
|
|
Map::const_iterator it2 = map2.find(2);
|
|
QVERIFY(it1 == it2);
|
|
++it1;
|
|
QVERIFY(it1 == map2.end());
|
|
QVERIFY(it2 != map2.end());
|
|
QVERIFY(it1 != it2);
|
|
|
|
int count = 0;
|
|
it1 = map2.begin();
|
|
while (it1 != map2.end()) {
|
|
count++;
|
|
++it1;
|
|
}
|
|
QVERIFY(count == 2);
|
|
|
|
count = 0;
|
|
it1 = map.begin();
|
|
while (it1 != map.end()) {
|
|
count++;
|
|
++it1;
|
|
}
|
|
QVERIFY(count == 2);
|
|
}
|
|
|
|
{
|
|
QVERIFY(map.contains(1));
|
|
QVERIFY(map.contains(2));
|
|
QVERIFY(!map.contains(0));
|
|
QVERIFY(!map.contains(3));
|
|
}
|
|
|
|
{
|
|
QVERIFY(map.value(1) == hello);
|
|
QVERIFY(map.value(2) == world);
|
|
QVERIFY(map.value(3) == 0);
|
|
QVERIFY(map.value(1, allo) == hello);
|
|
QVERIFY(map.value(2, allo) == world);
|
|
QVERIFY(map.value(3, allo) == allo);
|
|
QVERIFY(map.value(0, monde) == monde);
|
|
}
|
|
int originalLargeStaticCount = LargeStatic::count;
|
|
{
|
|
QMap<int,LargeStatic> map;
|
|
for (int i = 0; i < 10; i++)
|
|
map.insert(i, LargeStatic());
|
|
QVERIFY(LargeStatic::count == (originalLargeStaticCount + 10));
|
|
map.remove(7);
|
|
QVERIFY(LargeStatic::count == (originalLargeStaticCount + 9));
|
|
|
|
}
|
|
QVERIFY(LargeStatic::count == originalLargeStaticCount);
|
|
{
|
|
QMap<int, int*> map;
|
|
QVERIFY(((const QMap<int,int*>*) &map)->operator[](7) == 0);
|
|
}
|
|
|
|
{
|
|
QMap<int, int> map;
|
|
map[0] = 1;
|
|
map[1] = 2;
|
|
map[2] = 4;
|
|
map[3] = 8;
|
|
int sum = 0;
|
|
int sumkey = 0;
|
|
QMapIterator<int,int> i = map;
|
|
while (i.hasNext()) {
|
|
sum += i.next().value();
|
|
sumkey += i.key();
|
|
}
|
|
QVERIFY(sum == 15);
|
|
QVERIFY(sumkey == 6);
|
|
}
|
|
{
|
|
QMap<int, int> map;
|
|
map[0] = 1;
|
|
map[1] = 2;
|
|
map[2] = 4;
|
|
map[3] = 8;
|
|
int sum = 0;
|
|
QMutableMapIterator<int,int> i = map;
|
|
while(i.hasNext())
|
|
if (i.next().key() == 2)
|
|
i.remove();
|
|
i.toFront();
|
|
while(i.hasNext()) {
|
|
sum += i.next().value();
|
|
i.setValue(10);
|
|
i.value() += 22;
|
|
QVERIFY(i.value() == 32);
|
|
}
|
|
QVERIFY(sum == 11);
|
|
}
|
|
{
|
|
QMap<int, int> map;
|
|
map[0] = 1;
|
|
QMutableMapIterator<int,int> i(map);
|
|
i.toBack();
|
|
while (i.hasPrevious()) {
|
|
i.previous();
|
|
QCOMPARE(i.key(), 0);
|
|
QCOMPARE(i.value(), 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
QMultiMap<QString, int> map1;
|
|
map1.insert("1", 2);
|
|
map1.insert("1", 1);
|
|
map1.insert("a", 3);
|
|
map1.insert("a", 2);
|
|
map1.insert("a", 1);
|
|
map1.insert("b", 2);
|
|
map1.insert("b", 1);
|
|
|
|
// map1: [ "1" -> 1, "1" -> 2, "a" -> 1, "a" -> 2, "a" -> 3, "b" -> 1, "b" -> 2 ]
|
|
|
|
#if 0
|
|
QMapIterator<QString, int> i1(map1);
|
|
i1.toBack();
|
|
|
|
bool found;
|
|
found = i1.findPreviousKey("1");
|
|
QVERIFY(found && i1.value() == 2);
|
|
|
|
found = i1.findPreviousKey("1");
|
|
QVERIFY(found && i1.value() == 1);
|
|
|
|
found = i1.findPreviousKey("1");
|
|
QVERIFY(!found);
|
|
|
|
i1.toFront();
|
|
found = i1.findNextKey("1");
|
|
QVERIFY(found && i1.value() == 1);
|
|
|
|
found = i1.findNextKey("1");
|
|
QVERIFY(found && i1.value() == 2);
|
|
|
|
found = i1.findNextKey("1");
|
|
QVERIFY(!found);
|
|
|
|
i1.toBack();
|
|
found = i1.findPreviousKey("b");
|
|
QVERIFY(found && i1.value() == 2);
|
|
|
|
found = i1.findPreviousKey("b");
|
|
QVERIFY(found && i1.value() == 1);
|
|
|
|
found = i1.findPreviousKey("b");
|
|
QVERIFY(!found);
|
|
|
|
i1.toFront();
|
|
found = i1.findNextKey("b");
|
|
QVERIFY(found && i1.value() == 1);
|
|
|
|
found = i1.findNextKey("b");
|
|
QVERIFY(found && i1.value() == 2);
|
|
|
|
found = i1.findNextKey("b");
|
|
QVERIFY(!found);
|
|
#endif
|
|
|
|
QMultiMap<QString, int>::iterator j1, k1;
|
|
|
|
j1 = map1.lowerBound("0"); k1 = map1.upperBound("0");
|
|
QVERIFY(j1 == map1.begin() && k1 == j1);
|
|
j1 = map1.lowerBound("00"); k1 = map1.upperBound("00");
|
|
QVERIFY(j1 == map1.find("1") && k1 == j1);
|
|
j1 = map1.lowerBound("1"); k1 = map1.upperBound("1");
|
|
QVERIFY(j1 == map1.find("1") && --(--k1) == j1);
|
|
j1 = map1.lowerBound("11"); k1 = map1.upperBound("11");
|
|
QVERIFY(j1 == map1.find("a") && k1 == j1);
|
|
j1 = map1.lowerBound("a"); k1 = map1.upperBound("a");
|
|
QVERIFY(j1 == map1.find("a") && k1 == map1.find("b"));
|
|
QVERIFY(j1.value() == 1 && j1.value() == 1);
|
|
j1 = map1.lowerBound("aa"); k1 = map1.upperBound("aa");
|
|
QVERIFY(j1 == map1.find("b") && k1 == j1);
|
|
QVERIFY(j1.value() == 1);
|
|
j1 = map1.lowerBound("b"); k1 = map1.upperBound("b");
|
|
QVERIFY(j1 == map1.find("b") && k1 == map1.end());
|
|
QVERIFY(j1.value() == 1);
|
|
j1 = map1.lowerBound("bb"); k1 = map1.upperBound("bb");
|
|
QVERIFY(j1 == map1.end() && k1 == j1);
|
|
|
|
const QMultiMap<QString, int> map2 = map1;
|
|
QMultiMap<QString, int>::const_iterator j2, k2;
|
|
|
|
j2 = map2.lowerBound("0"); k2 = map2.upperBound("0");
|
|
QVERIFY(j2 == map2.begin() && k2 == j2);
|
|
j2 = map2.lowerBound("00"); k2 = map2.upperBound("00");
|
|
QVERIFY(j2 == map2.find("1") && k2 == j2);
|
|
j2 = map2.lowerBound("1"); k2 = map2.upperBound("1");
|
|
QVERIFY(j2 == map2.find("1") && --(--k2) == j2);
|
|
j2 = map2.lowerBound("11"); k2 = map2.upperBound("11");
|
|
QVERIFY(j2 == map2.find("a") && k2 == j2);
|
|
j2 = map2.lowerBound("a"); k2 = map2.upperBound("a");
|
|
QVERIFY(j2 == map2.find("a") && k2 == map2.find("b"));
|
|
QVERIFY(j2.value() == 1 && j2.value() == 1);
|
|
j2 = map2.lowerBound("aa"); k2 = map2.upperBound("aa");
|
|
QVERIFY(j2 == map2.find("b") && k2 == j2);
|
|
QVERIFY(j2.value() == 1);
|
|
j2 = map2.lowerBound("b"); k2 = map2.upperBound("b");
|
|
QVERIFY(j2 == map2.find("b") && k2 == map2.end());
|
|
QVERIFY(j2.value() == 1);
|
|
j2 = map2.lowerBound("bb"); k2 = map2.upperBound("bb");
|
|
QVERIFY(j2 == map2.end() && k2 == j2);
|
|
}
|
|
|
|
{
|
|
QMap<int, QString> map;
|
|
map.insert(0, "Hello");
|
|
|
|
QMap<int, QString>::iterator it = map.begin();
|
|
QVERIFY((*it)[0] == QChar('H'));
|
|
QVERIFY(it->constData()[0] == QChar('H'));
|
|
it->replace(QChar('H'), QChar('X'));
|
|
QVERIFY(*map.begin() == "Xello");
|
|
|
|
QMap<int, QString>::const_iterator cit = map.constBegin();
|
|
QVERIFY((*cit).toLower() == "xello");
|
|
QVERIFY(cit->toUpper() == "XELLO");
|
|
}
|
|
|
|
{
|
|
QMap<int, QString> map1, map2;
|
|
map1.insertMulti(1, "Alpha");
|
|
map1.insertMulti(1, "Gamma");
|
|
map2.insertMulti(1, "Beta");
|
|
map2.insertMulti(1, "Gamma");
|
|
map2.insertMulti(1, "Gamma");
|
|
|
|
map1.unite(map2);
|
|
QCOMPARE(map1.size(), 5);
|
|
QCOMPARE(static_cast<QStringList>(map1.values()),
|
|
(QStringList() << "Gamma" << "Gamma" << "Beta" << "Gamma" << "Alpha"));
|
|
|
|
map2 = map1;
|
|
map2.unite(map2);
|
|
QCOMPARE(map2.size(), 10);
|
|
QCOMPARE(map2.values(), map1.values() + map1.values());
|
|
}
|
|
}
|
|
|
|
void tst_Collections::qstring()
|
|
{
|
|
QString hello = "hello";
|
|
QString ello = "ello";
|
|
QString World = "World";
|
|
QString Wor = "Wor";
|
|
QString helloWorld = "helloWorld";
|
|
|
|
QString s = hello + "World";
|
|
QVERIFY(hello + World == helloWorld);
|
|
QVERIFY(hello + "World" == helloWorld);
|
|
QVERIFY("hello" + World == helloWorld);
|
|
|
|
|
|
QString l;
|
|
QVERIFY('h' + ello == hello);
|
|
QVERIFY(Wor + 'l' + 'd' == "World");
|
|
QVERIFY(hello + World == "helloWorld");
|
|
QVERIFY(hello + "World" == "helloWorld");
|
|
QVERIFY("hello" + World == "helloWorld");
|
|
QVERIFY('h' + ello == "hello");
|
|
QVERIFY(Wor + 'l' + 'd' == "World");
|
|
QVERIFY("helloWorld" == hello + World);
|
|
QVERIFY("helloWorld" == hello + "World");
|
|
QVERIFY("helloWorld" == "hello" + World);
|
|
QVERIFY("hello" == 'h' + ello);
|
|
QVERIFY("World" == Wor + 'l' + 'd');
|
|
|
|
QVERIFY(hello.contains('e'));
|
|
QVERIFY (true == hello.contains('e'));
|
|
QVERIFY (hello.contains('e') != false);
|
|
|
|
QVERIFY(hello.indexOf('e') == 1);
|
|
QVERIFY(hello.indexOf('e', -10) == 1);
|
|
QVERIFY(hello.indexOf('l') == 2);
|
|
QVERIFY(hello.indexOf('l',2) == 2);
|
|
QVERIFY(hello.indexOf('l',3) == 3);
|
|
|
|
QString large = "000 100 200 300 400 500 600 700 800 900";
|
|
|
|
QVERIFY(large.indexOf("700") == 28);
|
|
QVERIFY(large.indexOf("700", 28) == 28);
|
|
QVERIFY(large.indexOf("700", 29) == -1);
|
|
QVERIFY(large.lastIndexOf("700") == 28);
|
|
QVERIFY(large.lastIndexOf("700", 28) == 28);
|
|
QVERIFY(large.lastIndexOf("700", 27) == -1);
|
|
|
|
QVERIFY(large.contains("200"));
|
|
QVERIFY(!large.contains("201"));
|
|
QVERIFY(large.contains('3'));
|
|
QVERIFY(!large.contains('a'));
|
|
|
|
QVERIFY(large.count("00") == 11);
|
|
QVERIFY(large.count('3') == 1);
|
|
QVERIFY(large.count('0') == 21);
|
|
QVERIFY(large.count("0") == 21);
|
|
QVERIFY(large.count("200") == 1);
|
|
QVERIFY(large.count("201") == 0);
|
|
|
|
QVERIFY(hello.left(0) == "");
|
|
QVERIFY(!hello.left(0).isNull());
|
|
QVERIFY(hello.left(1) == "h");
|
|
QVERIFY(hello.left(2) == "he");
|
|
QVERIFY(hello.left(200) == "hello");
|
|
QVERIFY(hello.left(hello.size()) == hello);
|
|
QVERIFY(hello.left(hello.size()+1) == hello);
|
|
|
|
QVERIFY(hello.right(0) == "");
|
|
QVERIFY(!hello.right(0).isNull());
|
|
QVERIFY(hello.right(1) == "o");
|
|
QVERIFY(hello.right(2) == "lo");
|
|
QVERIFY(hello.right(200) == "hello");
|
|
QVERIFY(hello.right(hello.size()) == hello);
|
|
QVERIFY(hello.right(hello.size()+1) == hello);
|
|
|
|
QVERIFY(!hello.mid(0, 0).isNull());
|
|
QVERIFY(hello.mid(0, 1) == "h");
|
|
QVERIFY(hello.mid(0, 2) == "he");
|
|
QVERIFY(hello.mid(0, 200) == "hello");
|
|
QVERIFY(hello.mid(0) == "hello");
|
|
QVERIFY(hello.mid(0, hello.size()) == hello);
|
|
QVERIFY(hello.mid(0, hello.size()+1) == hello);
|
|
|
|
QVERIFY(hello.mid(hello.size()-0) == "");
|
|
|
|
QVERIFY(hello.mid(hello.size()-0).isNull());
|
|
QVERIFY(hello.mid(hello.size()-1) == "o");
|
|
QVERIFY(hello.mid(hello.size()-2) == "lo");
|
|
QVERIFY(hello.mid(hello.size()-200) == "hello");
|
|
|
|
QString null;
|
|
QString nonNull = "";
|
|
QVERIFY(null.left(10).isNull());
|
|
QVERIFY(null.mid(0).isNull());
|
|
|
|
QVERIFY(null == QString::null);
|
|
QVERIFY(QString::null == null);
|
|
QVERIFY(nonNull != QString::null);
|
|
QVERIFY(QString::null != nonNull);
|
|
QVERIFY(null == nonNull);
|
|
QVERIFY(QString::null == QString::null);
|
|
|
|
QString fill = "123";
|
|
fill.fill('a');
|
|
QVERIFY(fill == "aaa");
|
|
|
|
s.clear();
|
|
s = hello;
|
|
s.append(World);
|
|
QVERIFY(s == helloWorld);
|
|
s.clear();
|
|
s = World;
|
|
s.insert(0,hello);
|
|
QVERIFY(s == helloWorld);
|
|
s = "012345";
|
|
s.insert(3, 'E');
|
|
QVERIFY(s == "012E345");
|
|
s.insert(3, "INSID");
|
|
QVERIFY(s == "012INSIDE345");
|
|
s = "short";
|
|
s.insert(7, 'E');
|
|
QVERIFY(s == "short E");
|
|
s = "short";
|
|
s.insert(7, "END");
|
|
QVERIFY(s == "short END");
|
|
|
|
QVERIFY(QString::fromLatin1("hello") == "hello");
|
|
|
|
s = "first";
|
|
QVERIFY(s.toLatin1() == "first");
|
|
s = "second";
|
|
QVERIFY(s.toLatin1() == "second");
|
|
s.clear();
|
|
QVERIFY(s.isNull());
|
|
QVERIFY(s.toLatin1().size() == 0);
|
|
QVERIFY(s.toLatin1().isEmpty());
|
|
QVERIFY(s.toLatin1().isNull());
|
|
|
|
s = "first-utf8";
|
|
QVERIFY(s.toUtf8() == "first-utf8");
|
|
s = "second-utf8";
|
|
QVERIFY(s.toUtf8() == "second-utf8");
|
|
s.clear();
|
|
QVERIFY(s.isNull());
|
|
QVERIFY(s.toUtf8().size() == 0);
|
|
QVERIFY(s.toUtf8().isEmpty());
|
|
QVERIFY(s.toUtf8().isNull());
|
|
|
|
s = "first-utf8";
|
|
QVERIFY(s.toUtf8() == "first-utf8");
|
|
s = "second-utf8";
|
|
QVERIFY(s.toUtf8() == "second-utf8");
|
|
s.clear();
|
|
QVERIFY(s.isNull());
|
|
QVERIFY(s.toUtf8().size() == 0);
|
|
QVERIFY(s.toUtf8().isEmpty());
|
|
QVERIFY(s.toUtf8().isNull());
|
|
|
|
s = "first-local8Bit";
|
|
QVERIFY(s.toLocal8Bit() == "first-local8Bit");
|
|
s = "second-local8Bit";
|
|
QVERIFY(s.toLocal8Bit() == "second-local8Bit");
|
|
s.clear();
|
|
QVERIFY(s.isNull());
|
|
QVERIFY(s.toLocal8Bit().size() == 0);
|
|
QVERIFY(s.toLocal8Bit().isEmpty());
|
|
|
|
s = "first-ascii";
|
|
QVERIFY(s.toAscii() == "first-ascii");
|
|
s = "second-ascii";
|
|
QVERIFY(s.toAscii() == "second-ascii");
|
|
s.clear();
|
|
QVERIFY(s.isNull());
|
|
QVERIFY(s.toAscii().size() == 0);
|
|
QVERIFY(s.toAscii().isEmpty());
|
|
QVERIFY(s.toAscii().isNull());
|
|
|
|
s = "ascii";
|
|
s += (uchar) 0xb0;
|
|
QVERIFY(s.toUtf8() != s.toLatin1());
|
|
QString sa = s.toLatin1().constData();
|
|
QVERIFY(sa[sa.length()-1] == (ushort) 0xb0);
|
|
QVERIFY(sa.left(sa.length()-1) == "ascii");
|
|
|
|
QVERIFY(s == QString::fromUtf8(s.toUtf8().constData()));
|
|
|
|
s = "12";
|
|
s.append('3');
|
|
s += '4';
|
|
QVERIFY(s == "1234");
|
|
|
|
s = "repend";
|
|
s.prepend('p');
|
|
QVERIFY(s == "prepend");
|
|
s.prepend("abc ");
|
|
QVERIFY(s == "abc prepend");
|
|
|
|
s = " whitespace ";
|
|
QVERIFY(s.trimmed() == "whitespace");
|
|
s = " lots of stuff ";
|
|
QVERIFY(s.simplified() == "lots of stuff");
|
|
|
|
s = "a hat, a stick, a ski";
|
|
QVERIFY(s[2] == 'h');
|
|
QVERIFY(s[1] < 'b');
|
|
|
|
|
|
s = "12223";
|
|
s.remove(1, 2);
|
|
QVERIFY(s == "123");
|
|
|
|
s = "(%1)(%2)";
|
|
s = s.arg("foo").arg(7);
|
|
QVERIFY(s == "(foo)(7)");
|
|
|
|
|
|
#if 0
|
|
s = "stl rocks";
|
|
std::string stl_string = s;
|
|
s = stl_string;
|
|
QVERIFY(s == "stl rocks");
|
|
#endif
|
|
|
|
{
|
|
QString str("Bananas");
|
|
QVERIFY(str.startsWith("Ban"));
|
|
QVERIFY(false == str.startsWith("Car"));
|
|
}
|
|
{
|
|
QString str("Bananas");
|
|
QVERIFY(str.endsWith("anas"));
|
|
QVERIFY(false == str.endsWith("pple"));
|
|
}
|
|
|
|
|
|
QString str = "Hello";
|
|
QString cstr = QString::fromRawData(str.unicode(), str.length());
|
|
QVERIFY(str == "Hello");
|
|
QVERIFY(cstr == "Hello");
|
|
cstr.clear();
|
|
QVERIFY(str == "Hello");
|
|
QVERIFY(cstr.isEmpty());
|
|
|
|
{
|
|
QString str1("Foo");
|
|
str1.prepend(str1);
|
|
QCOMPARE(str1, QString("FooFoo"));
|
|
str1.append(str1);
|
|
QCOMPARE(str1, QString("FooFooFooFoo"));
|
|
str1.insert(2, str1);
|
|
QCOMPARE(str1, QString("FoFooFooFooFoooFooFooFoo"));
|
|
str1.replace(3, 3, str1);
|
|
QCOMPARE(str1, QString("FoFFoFooFooFooFoooFooFooFooooFooFoooFooFooFoo"));
|
|
str1 = "FooFoo";
|
|
str1.replace(char('F'), str1);
|
|
QCOMPARE(str1, QString("FooFooooFooFoooo"));
|
|
str1 = "FooFoo";
|
|
str1.replace(char('o'), str1);
|
|
QCOMPARE(str1, QString("FFooFooFooFooFFooFooFooFoo"));
|
|
|
|
str1 = "Foo";
|
|
str1.replace("Foo", str1);
|
|
QCOMPARE(str1, QString("Foo"));
|
|
str1.replace(str1, str1);
|
|
QCOMPARE(str1, QString("Foo"));
|
|
|
|
str1 = "Foo";
|
|
str1.replace("Foo", str1, Qt::CaseInsensitive);
|
|
QCOMPARE(str1, QString("Foo"));
|
|
str1.replace(str1, str1);
|
|
QCOMPARE(str1, QString("Foo"));
|
|
|
|
str1 = "FooFoo";
|
|
str1.reserve(100);
|
|
str1.replace("oo", str1);
|
|
QCOMPARE(str1, QString("FFooFooFFooFoo"));
|
|
|
|
str1 = "Bar";
|
|
str1.replace("FooFoo", str1);
|
|
QCOMPARE(str1, QString("Bar"));
|
|
|
|
str1.replace(str1, "xxx");
|
|
QCOMPARE(str1, QString("xxx"));
|
|
str1.replace(str1, QString("yyy"));
|
|
QCOMPARE(str1, QString("yyy"));
|
|
str1 += str1;
|
|
QCOMPARE(str1, QString("yyyyyy"));
|
|
}
|
|
}
|
|
|
|
|
|
void tst_Collections::bitArray()
|
|
{
|
|
QBitArray ba(20);
|
|
QVERIFY(ba.testBit(17) == false);
|
|
ba.setBit(17);
|
|
QVERIFY(ba.size() == 20);
|
|
QVERIFY(ba.testBit(17)==true);
|
|
QVERIFY(!ba.testBit(16));
|
|
ba[4] = true;
|
|
QVERIFY(ba.testBit(4));
|
|
QVERIFY(ba[4]);
|
|
int sum = 0;
|
|
for(int i = 0; i < 20; i++)
|
|
sum += ba.testBit(i) ? 1 : 0;
|
|
QVERIFY(sum == 2);
|
|
|
|
ba = QBitArray(7, true);
|
|
QVERIFY(ba.size() == 7);
|
|
QVERIFY(ba[5]);
|
|
|
|
ba = QBitArray(3);
|
|
ba[0] = ba[2] = true;
|
|
|
|
QBitArray nba(3);
|
|
nba[1] = true;
|
|
|
|
QVERIFY(~ba == nba);
|
|
|
|
};
|
|
|
|
struct CacheFoo
|
|
{
|
|
CacheFoo(int v):val(v) { counter++; }
|
|
~CacheFoo() { counter--; }
|
|
int val;
|
|
static int counter;
|
|
bool isDetached() const { return val != 2; }
|
|
};
|
|
|
|
int CacheFoo::counter = 0;
|
|
|
|
void tst_Collections::cache()
|
|
{
|
|
{
|
|
CacheFoo* cf;
|
|
QCache<int, CacheFoo> cache(120);
|
|
int i;
|
|
for (i = 0; i < 30; i++) {
|
|
cf = cache.object(10);
|
|
cache.insert(i, new CacheFoo(i), i);
|
|
}
|
|
|
|
QVERIFY(cache.contains(10));
|
|
QVERIFY(!cache.contains(1));
|
|
QVERIFY(!cache.contains(2));
|
|
delete cache.take(10);
|
|
}
|
|
{
|
|
QCache<int, QString> cache(120);
|
|
int i;
|
|
QString two;
|
|
for (i = 0; i < 30; i++) {
|
|
QString s = QString::number(i);
|
|
cache.insert(i, new QString(s), i);
|
|
if (i == 2)
|
|
two = s;
|
|
}
|
|
QVERIFY(!cache.contains(3));
|
|
QVERIFY(cache.contains(2));
|
|
}
|
|
{
|
|
QCache<int, int> cache(100);
|
|
cache.insert(2, new int(2));
|
|
*cache[2] = 3;
|
|
QVERIFY(*cache.object(2) == 3);
|
|
}
|
|
|
|
QVERIFY(CacheFoo::counter == 0);
|
|
|
|
}
|
|
|
|
void tst_Collections::regexp()
|
|
{
|
|
QRegExp rx("^\\d\\d?$");
|
|
QVERIFY(rx.indexIn("123") == -1);
|
|
QVERIFY(rx.indexIn("-6") == -1);
|
|
QVERIFY(rx.indexIn("6") == 0) ;
|
|
}
|
|
|
|
void tst_Collections::pair()
|
|
{
|
|
QPair<double, int> p;
|
|
QVERIFY(p.first == 0.0);
|
|
QVERIFY(p.second == 0);
|
|
|
|
QPair<int, QString> a(1, "Zebra"), b(2, "Ying"), c(3, "Yang"), d(3, "Ying"), e(5, "Alabama");
|
|
QVERIFY(a.first == 1);
|
|
QVERIFY(a.second == "Zebra");
|
|
QVERIFY(a == qMakePair(1, QString("Zebra")));
|
|
|
|
QVERIFY(a == a && b == b && c == c && d == d && e == e);
|
|
QVERIFY(a != b && a != c && a != d && a != e && b != c && b != d && b != e && c != d && c != e
|
|
&& d != e);
|
|
|
|
QVERIFY(a < b && b < c && c < d && d < e);
|
|
QVERIFY(a <= b && b <= c && c <= d && d <= e);
|
|
|
|
QVERIFY(e > d && d > c && c > b && b > a);
|
|
QVERIFY(e >= d && d >= c && c >= b && b >= a);
|
|
|
|
QVERIFY(!(a > b || b > c || c > d || d > e));
|
|
QVERIFY(!(a >= b || b >= c || c >= d || d >= e));
|
|
|
|
QVERIFY(!(e < d || d < c || c < b || b < a));
|
|
QVERIFY(!(e <= d || d <= c || c <= b || b <= a));
|
|
|
|
QVERIFY(a <= a && b <= b && c <= c && d <= d && e <= e);
|
|
QVERIFY(!(a < a || b < b || c < c || d < d || e < e));
|
|
|
|
QVERIFY(a >= a && b >= b && c >= c && d >= d && e >= e);
|
|
QVERIFY(!(a > a || b > b || c > c || d > d || e > e));
|
|
}
|
|
|
|
/*
|
|
These test that Java-style mutable iterators don't trash shared
|
|
copy (the setSharable() mechanism).
|
|
*/
|
|
|
|
template <class Container>
|
|
void populate(Container &);
|
|
|
|
template <>
|
|
void populate(QList<int> &container)
|
|
{
|
|
container << 1 << 2 << 4 << 8;
|
|
}
|
|
|
|
template <>
|
|
void populate(QLinkedList<int> &container)
|
|
{
|
|
container << 1 << 2 << 4 << 8;
|
|
}
|
|
|
|
template <>
|
|
void populate(QVector<int> &container)
|
|
{
|
|
container << 1 << 2 << 4 << 8;
|
|
}
|
|
|
|
template <>
|
|
void populate(QMap<int, int> &container)
|
|
{
|
|
container.insert(1, 1);
|
|
container.insert(2, 2);
|
|
container.insert(4, 4);
|
|
container.insert(8, 8);
|
|
}
|
|
|
|
template <>
|
|
void populate(QHash<int, int> &container)
|
|
{
|
|
container.insert(1, 1);
|
|
container.insert(2, 2);
|
|
container.insert(4, 4);
|
|
container.insert(8, 8);
|
|
}
|
|
|
|
template <class Container>
|
|
bool isSharable(const Container &container)
|
|
{
|
|
Container copy = container;
|
|
return !container.isDetached();
|
|
}
|
|
|
|
template <class Container, class ContainerMutableIterator>
|
|
void testContainer()
|
|
{
|
|
/*
|
|
Verify that shared_null's 'sharable' flag is set to true.
|
|
*/
|
|
{
|
|
Container c1;
|
|
QVERIFY(!c1.isDetached());
|
|
|
|
Container c2 = c1;
|
|
QVERIFY(!c1.isDetached());
|
|
QVERIFY(!c2.isDetached());
|
|
}
|
|
|
|
/*
|
|
Verify that the 'sharable' flag is true while no mutable
|
|
iterator is active.
|
|
*/
|
|
{
|
|
Container c1;
|
|
populate(c1);
|
|
QVERIFY(c1.size() == 4);
|
|
QVERIFY(c1.isDetached());
|
|
|
|
Container c2 = c1;
|
|
QVERIFY(c1.size() == 4);
|
|
QVERIFY(c2.size() == 4);
|
|
QVERIFY(!c1.isDetached());
|
|
QVERIFY(!c2.isDetached());
|
|
}
|
|
|
|
/*
|
|
Verify that the 'sharable' flag is set to false by the
|
|
mutable iterator.
|
|
*/
|
|
{
|
|
Container c1;
|
|
populate(c1);
|
|
QVERIFY(c1.size() == 4);
|
|
QVERIFY(c1.isDetached());
|
|
|
|
ContainerMutableIterator i(c1);
|
|
i.next();
|
|
|
|
Container c2 = c1;
|
|
QVERIFY(c1.size() == 4);
|
|
QVERIFY(c2.size() == 4);
|
|
QVERIFY(c1.isDetached());
|
|
QVERIFY(c2.isDetached());
|
|
|
|
i.remove();
|
|
QVERIFY(c1.size() == 3);
|
|
QVERIFY(c2.size() == 4);
|
|
}
|
|
|
|
/*
|
|
Verify that the 'sharable' flag is reset to true by the
|
|
mutable iterator's destructor.
|
|
*/
|
|
{
|
|
Container c1;
|
|
populate(c1);
|
|
QVERIFY(c1.size() == 4);
|
|
QVERIFY(c1.isDetached());
|
|
|
|
{
|
|
ContainerMutableIterator i(c1);
|
|
i.next();
|
|
}
|
|
|
|
Container c2 = c1;
|
|
QVERIFY(c1.size() == 4);
|
|
QVERIFY(c2.size() == 4);
|
|
QVERIFY(!c1.isDetached());
|
|
QVERIFY(!c2.isDetached());
|
|
}
|
|
|
|
/*
|
|
Verify that the 'sharable' flag only affects the original
|
|
object, not the copies.
|
|
*/
|
|
{
|
|
Container c1;
|
|
populate(c1);
|
|
QVERIFY(c1.size() == 4);
|
|
QVERIFY(c1.isDetached());
|
|
|
|
Container c2 = c1;
|
|
QVERIFY(isSharable(c2));
|
|
|
|
ContainerMutableIterator i(c1);
|
|
QVERIFY(!isSharable(c1));
|
|
QVERIFY(isSharable(c2));
|
|
|
|
Container c3 = c1;
|
|
QVERIFY(!isSharable(c1));
|
|
QVERIFY(isSharable(c2));
|
|
QVERIFY(isSharable(c3));
|
|
QVERIFY(c1.isDetached());
|
|
QVERIFY(c2.isDetached());
|
|
QVERIFY(c3.isDetached());
|
|
|
|
Container c4;
|
|
c4 = c1;
|
|
QVERIFY(!isSharable(c1));
|
|
QVERIFY(isSharable(c2));
|
|
QVERIFY(isSharable(c4));
|
|
QVERIFY(c1.isDetached());
|
|
QVERIFY(c2.isDetached());
|
|
QVERIFY(c4.isDetached());
|
|
|
|
c3 = c2;
|
|
QVERIFY(!isSharable(c1));
|
|
QVERIFY(isSharable(c2));
|
|
QVERIFY(isSharable(c3));
|
|
QVERIFY(c1.isDetached());
|
|
QVERIFY(!c2.isDetached());
|
|
QVERIFY(!c3.isDetached());
|
|
}
|
|
}
|
|
|
|
#define TEST_SEQUENTIAL_CONTAINER(Container) \
|
|
testContainer<Q##Container<int>, QMutable##Container##Iterator<int> >()
|
|
|
|
#define TEST_ASSOCIATIVE_CONTAINER(Container) \
|
|
testContainer<Q##Container<int, int>, QMutable##Container##Iterator<int, int> >()
|
|
|
|
void tst_Collections::sharableQList()
|
|
{
|
|
TEST_SEQUENTIAL_CONTAINER(List);
|
|
}
|
|
|
|
void tst_Collections::sharableQLinkedList()
|
|
{
|
|
TEST_SEQUENTIAL_CONTAINER(LinkedList);
|
|
}
|
|
|
|
void tst_Collections::sharableQVector()
|
|
{
|
|
TEST_SEQUENTIAL_CONTAINER(Vector);
|
|
}
|
|
|
|
void tst_Collections::sharableQMap()
|
|
{
|
|
TEST_ASSOCIATIVE_CONTAINER(Map);
|
|
}
|
|
|
|
void tst_Collections::sharableQHash()
|
|
{
|
|
TEST_ASSOCIATIVE_CONTAINER(Hash);
|
|
}
|
|
|
|
static int getList_calls = 0;
|
|
QList<int> getList()
|
|
{
|
|
++getList_calls;
|
|
QList<int> list;
|
|
list << 1 << 2 << 3 << 4 << 5 << 6;
|
|
return list;
|
|
}
|
|
|
|
|
|
void tst_Collections::q_foreach()
|
|
{
|
|
QList<int> list;
|
|
list << -2 << -1 << 0 << 1 << 2;
|
|
|
|
int sum = 0;
|
|
int j = 0;
|
|
foreach(int i, list) {
|
|
QCOMPARE(i, list.at(j));
|
|
sum += i;
|
|
++j;
|
|
}
|
|
QCOMPARE(sum, 0);
|
|
|
|
// again, but without scope
|
|
foreach(int i, list)
|
|
sum += i;
|
|
QCOMPARE(sum, 0);
|
|
|
|
foreach(int i, list) {
|
|
sum += i;
|
|
if (i == 0)
|
|
break;
|
|
}
|
|
QCOMPARE(sum, -3);
|
|
|
|
sum = 0;
|
|
foreach(int i, list) {
|
|
if (i < 0)
|
|
continue;
|
|
sum += i;
|
|
}
|
|
QCOMPARE(sum, 3);
|
|
|
|
sum = 0;
|
|
getList_calls = 0;
|
|
foreach(int i, getList())
|
|
sum += i;
|
|
QCOMPARE(sum, 21);
|
|
QCOMPARE(getList_calls, 1);
|
|
}
|
|
|
|
|
|
void tst_Collections::conversions()
|
|
{
|
|
#define STUFF "A" << "C" << "B" << "A"
|
|
|
|
{
|
|
QList<QString> list1;
|
|
list1 << STUFF;
|
|
|
|
QVector<QString> vect1 = list1.toVector();
|
|
QCOMPARE(list1.size(), 4);
|
|
QVERIFY(vect1 == (QVector<QString>() << STUFF));
|
|
|
|
QList<QString> list2 = vect1.toList();
|
|
QCOMPARE(list2.size(), 4);
|
|
QVERIFY(list2 == (QList<QString>() << STUFF));
|
|
|
|
QSet<QString> set1 = list1.toSet();
|
|
QCOMPARE(set1.size(), 3);
|
|
QVERIFY(set1.contains("A"));
|
|
QVERIFY(set1.contains("B"));
|
|
QVERIFY(set1.contains("C"));
|
|
QVERIFY(!set1.contains("D"));
|
|
|
|
QList<QString> list3 = set1.toList();
|
|
QCOMPARE(list3.size(), 3);
|
|
QVERIFY(list3.contains("A"));
|
|
QVERIFY(list3.contains("B"));
|
|
QVERIFY(list3.contains("C"));
|
|
QVERIFY(!list3.contains("D"));
|
|
|
|
QVERIFY(QList<int>().toVector().isEmpty());
|
|
QVERIFY(QList<int>().toSet().isEmpty());
|
|
QVERIFY(QVector<int>().toList().isEmpty());
|
|
QVERIFY(QSet<int>().toList().isEmpty());
|
|
}
|
|
|
|
{
|
|
QList<QString> list1;
|
|
list1 << STUFF;
|
|
|
|
QVector<QString> vect1 = QVector<QString>::fromList(list1);
|
|
QCOMPARE(list1.size(), 4);
|
|
QVERIFY(vect1 == (QVector<QString>() << STUFF));
|
|
|
|
QList<QString> list2 = QList<QString>::fromVector(vect1);
|
|
QCOMPARE(list2.size(), 4);
|
|
QVERIFY(list2 == (QList<QString>() << STUFF));
|
|
|
|
QSet<QString> set1 = QSet<QString>::fromList(list1);
|
|
QCOMPARE(set1.size(), 3);
|
|
QVERIFY(set1.contains("A"));
|
|
QVERIFY(set1.contains("B"));
|
|
QVERIFY(set1.contains("C"));
|
|
QVERIFY(!set1.contains("D"));
|
|
|
|
QList<QString> list3 = QList<QString>::fromSet(set1);
|
|
QCOMPARE(list3.size(), 3);
|
|
QVERIFY(list3.contains("A"));
|
|
QVERIFY(list3.contains("B"));
|
|
QVERIFY(list3.contains("C"));
|
|
QVERIFY(!list3.contains("D"));
|
|
|
|
QVERIFY(QVector<int>::fromList(QList<int>()).isEmpty());
|
|
QVERIFY(QSet<int>::fromList(QList<int>()).isEmpty());
|
|
QVERIFY(QList<int>::fromVector(QVector<int>()).isEmpty());
|
|
QVERIFY(QList<int>::fromSet(QSet<int>()).isEmpty());
|
|
}
|
|
#undef STUFF
|
|
}
|
|
|
|
void tst_Collections::javaStyleIterators()
|
|
{
|
|
QStringList list;
|
|
list << "a" << "b" << "c";
|
|
QMutableStringListIterator i(list);
|
|
while (i.hasNext()) {
|
|
i.next();
|
|
i.setValue("");
|
|
}
|
|
while (i.hasPrevious()) {
|
|
i.previous();
|
|
QVERIFY(i.value().isEmpty());
|
|
i.value() = "x";
|
|
QCOMPARE(i.value(), QString("x"));
|
|
}
|
|
}
|
|
|
|
template <class Container>
|
|
void testLinkedListLikeStlIterators()
|
|
{
|
|
Container fake;
|
|
typename Container::value_type t;
|
|
fake << t;
|
|
|
|
typename Container::iterator i1 = fake.begin(), i2 = i1 + 1;
|
|
typename Container::const_iterator c1 = i1, c2 = c1 + 1;
|
|
|
|
QVERIFY(i1 == i1);
|
|
QVERIFY(i1 == c1);
|
|
QVERIFY(c1 == i1);
|
|
QVERIFY(c1 == c1);
|
|
QVERIFY(i2 == i2);
|
|
QVERIFY(i2 == c2);
|
|
QVERIFY(c2 == i2);
|
|
QVERIFY(c2 == c2);
|
|
|
|
QVERIFY(i1 != i2);
|
|
QVERIFY(i1 != c2);
|
|
QVERIFY(c1 != i2);
|
|
QVERIFY(c1 != c2);
|
|
QVERIFY(i2 != i1);
|
|
QVERIFY(i2 != c1);
|
|
QVERIFY(c2 != i1);
|
|
QVERIFY(c2 != c1);
|
|
}
|
|
|
|
template <class Container>
|
|
void testListLikeStlIterators()
|
|
{
|
|
testLinkedListLikeStlIterators<Container>();
|
|
|
|
Container fake;
|
|
typename Container::value_type t;
|
|
fake << t;
|
|
|
|
typename Container::iterator i1 = fake.begin(), i2 = i1 + 1;
|
|
typename Container::const_iterator c1 = i1, c2 = c1 + 1;
|
|
|
|
QVERIFY(i1 < i2);
|
|
QVERIFY(i1 < c2);
|
|
QVERIFY(c1 < i2);
|
|
QVERIFY(c1 < c2);
|
|
QVERIFY(!(i2 < i1));
|
|
QVERIFY(!(i2 < c1));
|
|
QVERIFY(!(c2 < i1));
|
|
QVERIFY(!(c2 < c1));
|
|
QVERIFY(!(i1 < i1));
|
|
QVERIFY(!(i1 < c1));
|
|
QVERIFY(!(c1 < i1));
|
|
QVERIFY(!(c1 < c1));
|
|
QVERIFY(!(i2 < i2));
|
|
QVERIFY(!(i2 < c2));
|
|
QVERIFY(!(c2 < i2));
|
|
QVERIFY(!(c2 < c2));
|
|
|
|
QVERIFY(i2 > i1);
|
|
QVERIFY(i2 > c1);
|
|
QVERIFY(c2 > i1);
|
|
QVERIFY(c2 > c1);
|
|
QVERIFY(!(i1 > i2));
|
|
QVERIFY(!(i1 > c2));
|
|
QVERIFY(!(c1 > i2));
|
|
QVERIFY(!(c1 > c2));
|
|
QVERIFY(!(i1 > i1));
|
|
QVERIFY(!(i1 > c1));
|
|
QVERIFY(!(c1 > i1));
|
|
QVERIFY(!(c1 > c1));
|
|
QVERIFY(!(i2 > i2));
|
|
QVERIFY(!(i2 > c2));
|
|
QVERIFY(!(c2 > i2));
|
|
QVERIFY(!(c2 > c2));
|
|
|
|
QVERIFY(!(i1 >= i2));
|
|
QVERIFY(!(i1 >= c2));
|
|
QVERIFY(!(c1 >= i2));
|
|
QVERIFY(!(c1 >= c2));
|
|
QVERIFY(i2 >= i1);
|
|
QVERIFY(i2 >= c1);
|
|
QVERIFY(c2 >= i1);
|
|
QVERIFY(c2 >= c1);
|
|
QVERIFY(i1 >= i1);
|
|
QVERIFY(i1 >= c1);
|
|
QVERIFY(c1 >= i1);
|
|
QVERIFY(c1 >= c1);
|
|
QVERIFY(i2 >= i2);
|
|
QVERIFY(i2 >= c2);
|
|
QVERIFY(c2 >= i2);
|
|
QVERIFY(c2 >= c2);
|
|
|
|
QVERIFY(!(i2 <= i1));
|
|
QVERIFY(!(i2 <= c1));
|
|
QVERIFY(!(c2 <= i1));
|
|
QVERIFY(!(c2 <= c1));
|
|
QVERIFY(i1 <= i2);
|
|
QVERIFY(i1 <= c2);
|
|
QVERIFY(c1 <= i2);
|
|
QVERIFY(c1 <= c2);
|
|
QVERIFY(i1 <= i1);
|
|
QVERIFY(i1 <= c1);
|
|
QVERIFY(c1 <= i1);
|
|
QVERIFY(c1 <= c1);
|
|
QVERIFY(i2 <= i2);
|
|
QVERIFY(i2 <= c2);
|
|
QVERIFY(c2 <= i2);
|
|
QVERIFY(c2 <= c2);
|
|
}
|
|
|
|
template <class Container>
|
|
void testMapLikeStlIterators()
|
|
{
|
|
Container fake;
|
|
QString k;
|
|
QString t;
|
|
fake.insert(k, t);
|
|
|
|
typename Container::iterator i1 = fake.begin(), i2 = i1 + 1;
|
|
typename Container::const_iterator c1 = i1, c2 = c1 + 1;
|
|
|
|
QVERIFY(i1 == i1);
|
|
QVERIFY(i1 == c1);
|
|
QVERIFY(c1 == i1);
|
|
QVERIFY(c1 == c1);
|
|
QVERIFY(i2 == i2);
|
|
QVERIFY(i2 == c2);
|
|
QVERIFY(c2 == i2);
|
|
QVERIFY(c2 == c2);
|
|
|
|
QVERIFY(i1 != i2);
|
|
QVERIFY(i1 != c2);
|
|
QVERIFY(c1 != i2);
|
|
QVERIFY(c1 != c2);
|
|
QVERIFY(i2 != i1);
|
|
QVERIFY(i2 != c1);
|
|
QVERIFY(c2 != i1);
|
|
QVERIFY(c2 != c1);
|
|
}
|
|
|
|
void tst_Collections::constAndNonConstStlIterators()
|
|
{
|
|
testListLikeStlIterators<QList<int> >();
|
|
testListLikeStlIterators<QStringList >();
|
|
testLinkedListLikeStlIterators<QLinkedList<int> >();
|
|
testListLikeStlIterators<QVector<int> >();
|
|
testMapLikeStlIterators<QMap<QString, QString> >();
|
|
testMapLikeStlIterators<QMultiMap<QString, QString> >();
|
|
testMapLikeStlIterators<QHash<QString, QString> >();
|
|
testMapLikeStlIterators<QMultiHash<QString, QString> >();
|
|
}
|
|
|
|
#ifndef QT_NO_STL
|
|
void tst_Collections::vector_stl_data()
|
|
{
|
|
QTest::addColumn<QStringList>("elements");
|
|
|
|
QTest::newRow("empty") << QStringList();
|
|
QTest::newRow("one") << (QStringList() << "Hei");
|
|
QTest::newRow("two") << (QStringList() << "Hei" << "Hopp");
|
|
QTest::newRow("three") << (QStringList() << "Hei" << "Hopp" << "Sann");
|
|
}
|
|
|
|
void tst_Collections::vector_stl()
|
|
{
|
|
QFETCH(QStringList, elements);
|
|
|
|
QVector<QString> vector;
|
|
for (int i = 0; i < elements.count(); ++i)
|
|
vector << elements.at(i);
|
|
|
|
std::vector<QString> stdVector = vector.toStdVector();
|
|
|
|
QCOMPARE(int(stdVector.size()), elements.size());
|
|
|
|
std::vector<QString>::const_iterator it = stdVector.begin();
|
|
for (uint j = 0; j < stdVector.size() && it != stdVector.end(); ++j, ++it)
|
|
QCOMPARE(*it, vector[j]);
|
|
|
|
QCOMPARE(QVector<QString>::fromStdVector(stdVector), vector);
|
|
}
|
|
|
|
void tst_Collections::linkedlist_stl_data()
|
|
{
|
|
list_stl_data();
|
|
}
|
|
|
|
void tst_Collections::linkedlist_stl()
|
|
{
|
|
QFETCH(QStringList, elements);
|
|
|
|
QLinkedList<QString> list;
|
|
for (int i = 0; i < elements.count(); ++i)
|
|
list << elements.at(i);
|
|
|
|
std::list<QString> stdList = list.toStdList();
|
|
|
|
QCOMPARE(int(stdList.size()), elements.size());
|
|
|
|
std::list<QString>::const_iterator it = stdList.begin();
|
|
QLinkedList<QString>::const_iterator it2 = list.constBegin();
|
|
for (uint j = 0; j < stdList.size(); ++j, ++it, ++it2)
|
|
QCOMPARE(*it, *it2);
|
|
|
|
QCOMPARE(QLinkedList<QString>::fromStdList(stdList), list);
|
|
}
|
|
|
|
void tst_Collections::list_stl_data()
|
|
{
|
|
QTest::addColumn<QStringList>("elements");
|
|
|
|
QTest::newRow("empty") << QStringList();
|
|
QTest::newRow("one") << (QStringList() << "Hei");
|
|
QTest::newRow("two") << (QStringList() << "Hei" << "Hopp");
|
|
QTest::newRow("three") << (QStringList() << "Hei" << "Hopp" << "Sann");
|
|
}
|
|
|
|
void tst_Collections::list_stl()
|
|
{
|
|
QFETCH(QStringList, elements);
|
|
|
|
QList<QString> list;
|
|
for (int i = 0; i < elements.count(); ++i)
|
|
list << elements.at(i);
|
|
|
|
std::list<QString> stdList = list.toStdList();
|
|
|
|
QCOMPARE(int(stdList.size()), elements.size());
|
|
|
|
std::list<QString>::const_iterator it = stdList.begin();
|
|
for (uint j = 0; j < stdList.size() && it != stdList.end(); ++j, ++it)
|
|
QCOMPARE(*it, list[j]);
|
|
|
|
QCOMPARE(QList<QString>::fromStdList(stdList), list);
|
|
}
|
|
#endif
|
|
|
|
template <typename T>
|
|
T qtInit(T * = 0)
|
|
{
|
|
return T();
|
|
}
|
|
|
|
void tst_Collections::q_init()
|
|
{
|
|
QCOMPARE(qtInit<int>(), 0);
|
|
QCOMPARE(qtInit<double>(), 0.0);
|
|
QCOMPARE(qtInit<QString>(), QString());
|
|
QCOMPARE(qtInit<int *>(), static_cast<int *>(0));
|
|
QCOMPARE(qtInit<double *>(), static_cast<double *>(0));
|
|
QCOMPARE(qtInit<QString *>(), static_cast<QString *>(0));
|
|
QCOMPARE(qtInit<Pod>().i1, 0);
|
|
QCOMPARE(qtInit<Pod>().i2, 0);
|
|
}
|
|
|
|
void tst_Collections::pointersize()
|
|
{
|
|
QCOMPARE(int(sizeof(void *)), QT_POINTER_SIZE);
|
|
}
|
|
|
|
class LessThanComparable
|
|
{
|
|
public:
|
|
bool operator<(const LessThanComparable &) const { return true; }
|
|
};
|
|
|
|
class EqualsComparable
|
|
{
|
|
public:
|
|
bool operator==(const EqualsComparable &) const { return true; }
|
|
};
|
|
|
|
uint qHash(const EqualsComparable &)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
The following functions instatiates every member functions in the
|
|
Qt containers that requires either operator== or operator<.
|
|
They are ordered in a concept inheritance tree:
|
|
|
|
Container
|
|
MutableIterationContainer
|
|
Sequence (QLinkedList)
|
|
Random Access (QVector, QList, QQueue, QStack)
|
|
Pair Associative (QHash, QMap)
|
|
Associative (QSet)
|
|
*/
|
|
template <typename ContainerType, typename ValueType>
|
|
void instantiateContainer()
|
|
{
|
|
const ValueType value = ValueType();
|
|
ContainerType container;
|
|
const ContainerType constContainer(container);
|
|
|
|
#ifndef QT_NO_STL
|
|
typename ContainerType::const_iterator constIt;
|
|
constIt = constContainer.begin();
|
|
container.constBegin();
|
|
|
|
constIt = constContainer.end();
|
|
container.constEnd();
|
|
#endif
|
|
container.clear();
|
|
container.contains(value);
|
|
container.count();
|
|
container.empty();
|
|
container.isEmpty();
|
|
container.size();
|
|
|
|
container != constContainer;
|
|
container == constContainer;
|
|
container = constContainer;
|
|
}
|
|
|
|
template <typename ContainerType, typename ValueType>
|
|
void instantiateMutableIterationContainer()
|
|
{
|
|
instantiateContainer<ContainerType, ValueType>();
|
|
ContainerType container;
|
|
|
|
#ifndef QT_NO_STL
|
|
typename ContainerType::iterator it;
|
|
it = container.begin();
|
|
it = container.end();
|
|
#endif
|
|
|
|
// QSet lacks count(T).
|
|
const ValueType value = ValueType();
|
|
container.count(value);
|
|
}
|
|
|
|
template <typename ContainerType, typename ValueType>
|
|
void instantiateSequence()
|
|
{
|
|
instantiateMutableIterationContainer<ContainerType, ValueType>();
|
|
|
|
// QVector lacks removeAll(T)
|
|
// ValueType value = ValueType();
|
|
// ContainerType container;
|
|
// container.removeAll(value);
|
|
}
|
|
|
|
template <typename ContainerType, typename ValueType>
|
|
void instantiateRandomAccess()
|
|
{
|
|
instantiateSequence<ContainerType, ValueType>();
|
|
|
|
ValueType value = ValueType();
|
|
ContainerType container;
|
|
container.indexOf(value);
|
|
container.lastIndexOf(value);
|
|
}
|
|
|
|
template <typename ContainerType, typename ValueType>
|
|
void instantiateAssociative()
|
|
{
|
|
instantiateContainer<ContainerType, ValueType>();
|
|
|
|
const ValueType value = ValueType();
|
|
ContainerType container;
|
|
const ContainerType constContainer(container);
|
|
|
|
container.reserve(1);
|
|
container.capacity();
|
|
container.squeeze();
|
|
|
|
container.remove(value);
|
|
container.values();
|
|
|
|
container.unite(constContainer);
|
|
container.intersect(constContainer);
|
|
container.subtract(constContainer);
|
|
|
|
container != constContainer;
|
|
container == constContainer;
|
|
container & constContainer;
|
|
container &= constContainer;
|
|
container &= value;
|
|
container + constContainer;
|
|
container += constContainer;
|
|
container += value;
|
|
container - constContainer;
|
|
container -= constContainer;
|
|
container -= value;
|
|
container | constContainer;
|
|
container |= constContainer;
|
|
container |= value;
|
|
}
|
|
|
|
template <typename ContainerType, typename KeyType, typename ValueType>
|
|
void instantiatePairAssociative()
|
|
{
|
|
instantiateMutableIterationContainer<ContainerType, KeyType>();
|
|
|
|
typename ContainerType::iterator it;
|
|
typename ContainerType::const_iterator constIt;
|
|
const KeyType key = KeyType();
|
|
const ValueType value = ValueType();
|
|
ContainerType container;
|
|
const ContainerType constContainer(container);
|
|
|
|
it = container.insert(key, value);
|
|
container.erase(it);
|
|
container.find(key);
|
|
container.constFind(key);
|
|
constContainer.find(key);
|
|
|
|
container.key(value);
|
|
container.keys();
|
|
constContainer.keys();
|
|
container.remove(key);
|
|
container.take(key);
|
|
container.unite(constContainer);
|
|
container.value(key);
|
|
container.value(key, value);
|
|
container.values();
|
|
container.values(key);
|
|
container[key];
|
|
const int foo = constContainer[key];
|
|
Q_UNUSED(foo);
|
|
}
|
|
|
|
/*
|
|
Instantiate all Qt containers using a datatype that
|
|
defines the minimum amount of operators.
|
|
*/
|
|
void tst_Collections::containerInstantiation()
|
|
{
|
|
// Instantiate QHash member functions.
|
|
typedef QHash<EqualsComparable, int> Hash;
|
|
instantiatePairAssociative<Hash, EqualsComparable, int>();
|
|
|
|
Hash hash;
|
|
hash.reserve(1);
|
|
hash.capacity();
|
|
hash.squeeze();
|
|
|
|
// Instantiate QMap member functions.
|
|
typedef QMap<LessThanComparable, int> Map;
|
|
instantiatePairAssociative<Map, LessThanComparable, int>();
|
|
|
|
// Instantiate QSet member functions.
|
|
typedef QSet<EqualsComparable> Set;
|
|
instantiateAssociative<Set, EqualsComparable>();
|
|
|
|
//Instantiate QLinkedList member functions.
|
|
typedef QLinkedList<EqualsComparable> LinkedList;
|
|
instantiateSequence<LinkedList, EqualsComparable> ();
|
|
{
|
|
EqualsComparable value;
|
|
LinkedList list;
|
|
list.removeAll(value);
|
|
}
|
|
|
|
//Instantiate QList member functions.
|
|
typedef QList<EqualsComparable> List;
|
|
instantiateRandomAccess<List, EqualsComparable>();
|
|
{
|
|
EqualsComparable value;
|
|
List list;
|
|
list.removeAll(value);
|
|
}
|
|
|
|
//Instantiate QVector member functions.
|
|
typedef QVector<EqualsComparable> Vector;
|
|
instantiateRandomAccess<Vector, EqualsComparable>();
|
|
|
|
//Instantiate QQueue member functions.
|
|
typedef QQueue<EqualsComparable> Queue;
|
|
instantiateRandomAccess<Queue, EqualsComparable>();
|
|
|
|
//Instantiate QStack member functions.
|
|
typedef QStack<EqualsComparable> Stack;
|
|
instantiateRandomAccess<Stack, EqualsComparable>();
|
|
}
|
|
|
|
void tst_Collections::qtimerList()
|
|
{
|
|
QList<double> foo;
|
|
const int N = 10000;
|
|
|
|
foo.append(99.9);
|
|
foo.append(99.9);
|
|
foo.append(99.9);
|
|
|
|
for(int i = 0; i < N; i++) {
|
|
foo.removeFirst();
|
|
foo.insert(1, 99.9);
|
|
}
|
|
|
|
QList<double>::Iterator end = foo.end();
|
|
for (int i = 0; i < (N / 2) - 10; ++i) {
|
|
foo.prepend(99.9);
|
|
if (foo.end() != end)
|
|
return;
|
|
}
|
|
QFAIL("QList preallocates too much memory");
|
|
}
|
|
|
|
template <typename Container>
|
|
void testContainerTypedefs(Container container)
|
|
{
|
|
Q_UNUSED(container)
|
|
{ typedef typename Container::value_type Foo; }
|
|
{ typedef typename Container::iterator Foo; }
|
|
{ typedef typename Container::const_iterator Foo; }
|
|
{ typedef typename Container::reference Foo; }
|
|
{ typedef typename Container::const_reference Foo; }
|
|
{ typedef typename Container::pointer Foo; }
|
|
{ typedef typename Container::difference_type Foo; }
|
|
{ typedef typename Container::size_type Foo; }
|
|
}
|
|
|
|
template <typename Container>
|
|
void testPairAssociativeContainerTypedefs(Container container)
|
|
{
|
|
Q_UNUSED(container)
|
|
|
|
// TODO: Not sure how to define value_type for our associative containers
|
|
// { typedef typename Container::value_type Foo; }
|
|
// { typedef typename Container::const_iterator Foo; }
|
|
// { typedef typename Container::reference Foo; }
|
|
// { typedef typename Container::const_reference Foo; }
|
|
// { typedef typename Container::pointer Foo; }
|
|
|
|
{ typedef typename Container::difference_type Foo; }
|
|
{ typedef typename Container::size_type Foo; }
|
|
{ typedef typename Container::iterator Foo; }
|
|
{ typedef typename Container::key_type Foo; }
|
|
{ typedef typename Container::mapped_type Foo; }
|
|
// TODO
|
|
// { typedef typename Container::key_compare Foo; }
|
|
// { typedef typename Container::value_comare Foo; }
|
|
}
|
|
|
|
template <typename Container>
|
|
void testSetContainerTypedefs(Container container)
|
|
{
|
|
Q_UNUSED(container)
|
|
{ typedef typename Container::iterator Foo; }
|
|
{ typedef typename Container::const_iterator Foo; }
|
|
{ typedef typename Container::reference Foo; }
|
|
{ typedef typename Container::const_reference Foo; }
|
|
{ typedef typename Container::pointer Foo; }
|
|
{ typedef typename Container::difference_type Foo; }
|
|
{ typedef typename Container::size_type Foo; }
|
|
{ typedef typename Container::key_type Foo; }
|
|
}
|
|
|
|
/*
|
|
Compile-time test that verifies that the Qt containers
|
|
have STL-compatable typedefs.
|
|
*/
|
|
void tst_Collections::containerTypedefs()
|
|
{
|
|
testContainerTypedefs(QVector<int>());
|
|
testContainerTypedefs(QStack<int>());
|
|
testContainerTypedefs(QList<int>());
|
|
testContainerTypedefs(QLinkedList<int>());
|
|
testContainerTypedefs(QQueue<int>());
|
|
|
|
testPairAssociativeContainerTypedefs(QMap<int, int>());
|
|
testPairAssociativeContainerTypedefs(QMultiMap<int, int>());
|
|
testPairAssociativeContainerTypedefs(QHash<int, int>());
|
|
|
|
testSetContainerTypedefs(QSet<int>());
|
|
}
|
|
|
|
class Key1;
|
|
class T1;
|
|
class T2;
|
|
|
|
void tst_Collections::forwardDeclared()
|
|
{
|
|
{ typedef QHash<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
|
|
{ typedef QMultiHash<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
|
|
{ typedef QMap<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
|
|
{ typedef QMultiMap<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
|
|
#if !defined(Q_CC_RVCT)
|
|
// RVCT can't handle forward declared template parameters if those are used to declare
|
|
// class members inside templated class.
|
|
{ typedef QPair<T1, T2> C; C *x = 0; Q_UNUSED(x) }
|
|
#endif
|
|
{ typedef QList<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
|
|
{ typedef QLinkedList<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
|
|
{ typedef QVector<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) Q_UNUSED(i) Q_UNUSED(j) }
|
|
{ typedef QStack<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) Q_UNUSED(i) Q_UNUSED(j) }
|
|
{ typedef QQueue<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
|
|
{ typedef QSet<T1> C; C *x = 0; /* C::iterator i; */ C::const_iterator j; Q_UNUSED(x) }
|
|
}
|
|
|
|
#if defined(Q_ALIGNOF) && defined(Q_DECL_ALIGN)
|
|
|
|
class Q_DECL_ALIGN(4) Aligned4
|
|
{
|
|
char i;
|
|
public:
|
|
Aligned4(int i = 0) : i(i) {}
|
|
bool checkAligned() const
|
|
{
|
|
return (quintptr(this) & 3) == 0;
|
|
}
|
|
|
|
inline bool operator==(const Aligned4 &other) const { return i == other.i; }
|
|
inline bool operator<(const Aligned4 &other) const { return i < other.i; }
|
|
friend inline int qHash(const Aligned4 &a) { return qHash(a.i); }
|
|
};
|
|
|
|
class Q_DECL_ALIGN(128) Aligned128
|
|
{
|
|
char i;
|
|
public:
|
|
Aligned128(int i = 0) : i(i) {}
|
|
bool checkAligned() const
|
|
{
|
|
return (quintptr(this) & 127) == 0;
|
|
}
|
|
|
|
inline bool operator==(const Aligned128 &other) const { return i == other.i; }
|
|
inline bool operator<(const Aligned128 &other) const { return i < other.i; }
|
|
friend inline int qHash(const Aligned128 &a) { return qHash(a.i); }
|
|
};
|
|
|
|
template<typename C>
|
|
void testVectorAlignment()
|
|
{
|
|
typedef typename C::value_type Aligned;
|
|
C container;
|
|
container.append(Aligned());
|
|
QVERIFY(container[0].checkAligned());
|
|
|
|
for (int i = 0; i < 200; ++i)
|
|
container.append(Aligned());
|
|
|
|
for (int i = 0; i < container.size(); ++i)
|
|
QVERIFY(container.at(i).checkAligned());
|
|
}
|
|
|
|
template<typename C>
|
|
void testContiguousCacheAlignment()
|
|
{
|
|
typedef typename C::value_type Aligned;
|
|
C container(150);
|
|
container.append(Aligned());
|
|
QVERIFY(container[container.firstIndex()].checkAligned());
|
|
|
|
for (int i = 0; i < 200; ++i)
|
|
container.append(Aligned());
|
|
|
|
for (int i = container.firstIndex(); i < container.lastIndex(); ++i)
|
|
QVERIFY(container.at(i).checkAligned());
|
|
}
|
|
|
|
template<typename C>
|
|
void testAssociativeContainerAlignment()
|
|
{
|
|
typedef typename C::key_type Key;
|
|
typedef typename C::mapped_type Value;
|
|
C container;
|
|
container.insert(Key(), Value());
|
|
|
|
typename C::const_iterator it = container.constBegin();
|
|
QVERIFY(it.key().checkAligned());
|
|
QVERIFY(it.value().checkAligned());
|
|
|
|
// add some more elements
|
|
for (int i = 0; i < 200; ++i)
|
|
container.insert(Key(i), Value(i));
|
|
|
|
it = container.constBegin();
|
|
for ( ; it != container.constEnd(); ++it) {
|
|
QVERIFY(it.key().checkAligned());
|
|
QVERIFY(it.value().checkAligned());
|
|
}
|
|
}
|
|
|
|
void tst_Collections::alignment()
|
|
{
|
|
testVectorAlignment<QVector<Aligned4> >();
|
|
testVectorAlignment<QVector<Aligned128> >();
|
|
testContiguousCacheAlignment<QContiguousCache<Aligned4> >();
|
|
testContiguousCacheAlignment<QContiguousCache<Aligned128> >();
|
|
testAssociativeContainerAlignment<QMap<Aligned4, Aligned4> >();
|
|
testAssociativeContainerAlignment<QMap<Aligned4, Aligned128> >();
|
|
testAssociativeContainerAlignment<QMap<Aligned128, Aligned4> >();
|
|
testAssociativeContainerAlignment<QMap<Aligned128, Aligned128> >();
|
|
testAssociativeContainerAlignment<QHash<Aligned4, Aligned4> >();
|
|
testAssociativeContainerAlignment<QHash<Aligned4, Aligned128> >();
|
|
testAssociativeContainerAlignment<QHash<Aligned128, Aligned4> >();
|
|
testAssociativeContainerAlignment<QHash<Aligned128, Aligned128> >();
|
|
}
|
|
|
|
#else
|
|
void tst_Collections::alignment()
|
|
{
|
|
QSKIP("Compiler doesn't support necessary extension keywords", SkipAll);
|
|
}
|
|
#endif
|
|
|
|
#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
|
|
|
|
template<template<class> class C>
|
|
struct QTBUG13079_Node {
|
|
C<QTBUG13079_Node> children;
|
|
QString s;
|
|
|
|
~QTBUG13079_Node() {
|
|
children.begin(); //play with memory
|
|
}
|
|
};
|
|
template<template<class> class C> void QTBUG13079_collectionInsideCollectionImpl()
|
|
{
|
|
C<QTBUG13079_Node<C> > nodeList;
|
|
nodeList << QTBUG13079_Node<C>();
|
|
nodeList.first().s = "parent";
|
|
nodeList.first().children << QTBUG13079_Node<C>();
|
|
nodeList.first().children.first().s = "child";
|
|
|
|
nodeList = nodeList.first().children;
|
|
QCOMPARE(nodeList.first().s, QString::fromLatin1("child"));
|
|
|
|
nodeList = nodeList.first().children;
|
|
QCOMPARE(nodeList.count(), 0);
|
|
nodeList << QTBUG13079_Node<C>();
|
|
}
|
|
|
|
template<template<class, class> class C>
|
|
struct QTBUG13079_NodeAssoc {
|
|
C<int, QTBUG13079_NodeAssoc> children;
|
|
QString s;
|
|
|
|
~QTBUG13079_NodeAssoc() {
|
|
children.begin(); //play with memory
|
|
}
|
|
};
|
|
template<template<class, class> class C> void QTBUG13079_collectionInsideCollectionAssocImpl()
|
|
{
|
|
C<int, QTBUG13079_NodeAssoc<C> > nodeMap;
|
|
nodeMap[18] = QTBUG13079_NodeAssoc<C>();
|
|
nodeMap[18].s = "parent";
|
|
nodeMap[18].children[12] = QTBUG13079_NodeAssoc<C>();
|
|
nodeMap[18].children[12].s = "child";
|
|
|
|
nodeMap = nodeMap[18].children;
|
|
QCOMPARE(nodeMap[12].s, QString::fromLatin1("child"));
|
|
|
|
nodeMap = nodeMap[12].children;
|
|
QCOMPARE(nodeMap.count(), 0);
|
|
nodeMap[42] = QTBUG13079_NodeAssoc<C>();
|
|
}
|
|
|
|
|
|
quint32 qHash(const QTBUG13079_Node<QSet> &)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
bool operator==(const QTBUG13079_Node<QSet> &a, const QTBUG13079_Node<QSet> &b)
|
|
{
|
|
return a.s == b.s && a.children == b.children;
|
|
}
|
|
|
|
template<template<class> class C>
|
|
struct QTBUG13079_NodePtr : QSharedData {
|
|
C<QTBUG13079_NodePtr> child;
|
|
QTBUG13079_NodePtr *next;
|
|
QString s;
|
|
|
|
QTBUG13079_NodePtr() : next(0) {}
|
|
~QTBUG13079_NodePtr() {
|
|
next = child.data(); //play with memory
|
|
}
|
|
};
|
|
template<template<class> class C> void QTBUG13079_collectionInsidePtrImpl()
|
|
{
|
|
typedef C<QTBUG13079_NodePtr<C> > Ptr;
|
|
{
|
|
Ptr nodePtr;
|
|
nodePtr = Ptr(new QTBUG13079_NodePtr<C>());
|
|
nodePtr->s = "parent";
|
|
nodePtr->child = Ptr(new QTBUG13079_NodePtr<C>());
|
|
nodePtr->child->s = "child";
|
|
nodePtr = nodePtr->child;
|
|
QCOMPARE(nodePtr->s, QString::fromLatin1("child"));
|
|
nodePtr = nodePtr->child;
|
|
QVERIFY(!nodePtr);
|
|
}
|
|
{
|
|
Ptr nodePtr;
|
|
nodePtr = Ptr(new QTBUG13079_NodePtr<C>());
|
|
nodePtr->s = "parent";
|
|
nodePtr->next = new QTBUG13079_NodePtr<C>();
|
|
nodePtr->next->s = "next";
|
|
nodePtr = Ptr(nodePtr->next);
|
|
QCOMPARE(nodePtr->s, QString::fromLatin1("next"));
|
|
nodePtr = Ptr(nodePtr->next);
|
|
QVERIFY(!nodePtr);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
void tst_Collections::QTBUG13079_collectionInsideCollection()
|
|
{
|
|
#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
|
|
QTBUG13079_collectionInsideCollectionImpl<QVector>();
|
|
QTBUG13079_collectionInsideCollectionImpl<QStack>();
|
|
QTBUG13079_collectionInsideCollectionImpl<QList>();
|
|
QTBUG13079_collectionInsideCollectionImpl<QLinkedList>();
|
|
QTBUG13079_collectionInsideCollectionImpl<QQueue>();
|
|
|
|
{
|
|
QSet<QTBUG13079_Node<QSet> > nodeSet;
|
|
nodeSet << QTBUG13079_Node<QSet>();
|
|
nodeSet = nodeSet.begin()->children;
|
|
QCOMPARE(nodeSet.count(), 0);
|
|
}
|
|
|
|
QTBUG13079_collectionInsideCollectionAssocImpl<QMap>();
|
|
QTBUG13079_collectionInsideCollectionAssocImpl<QHash>();
|
|
|
|
QTBUG13079_collectionInsidePtrImpl<QSharedPointer>();
|
|
QTBUG13079_collectionInsidePtrImpl<QExplicitlySharedDataPointer>();
|
|
QTBUG13079_collectionInsidePtrImpl<QSharedDataPointer>();
|
|
#endif
|
|
}
|
|
|
|
template<class Container> void foreach_test_arrays(const Container &container)
|
|
{
|
|
typedef typename Container::value_type T;
|
|
int i = 0;
|
|
QSet <T> set;
|
|
foreach(const T & val, container) {
|
|
QVERIFY( val == container[i] );
|
|
set << val;
|
|
i++;
|
|
}
|
|
QCOMPARE(set.count(), container.count());
|
|
|
|
//modify the container while iterating.
|
|
Container c2 = container;
|
|
Container c3;
|
|
i = 0;
|
|
foreach (T val, c2) {
|
|
c3 << val;
|
|
c2.insert((i * 89) % c2.size(), T() );
|
|
QVERIFY( val == container.at(i) );
|
|
val = T();
|
|
i++;
|
|
}
|
|
QVERIFY(c3 == container);
|
|
}
|
|
|
|
|
|
void tst_Collections::foreach_2()
|
|
{
|
|
QStringList strlist = QString::fromLatin1("a,b,c,d,e,f,g,h,ih,kl,mn,op,qr,st,uvw,xyz").split(",");
|
|
foreach_test_arrays(strlist);
|
|
foreach_test_arrays(QList<QString>(strlist));
|
|
foreach_test_arrays(strlist.toVector());
|
|
|
|
QList<int> intlist;
|
|
intlist << 1 << 2 << 3 << 4 <<5 << 6 << 7 << 8 << 9;
|
|
foreach_test_arrays(intlist);
|
|
foreach_test_arrays(intlist.toVector());
|
|
|
|
QVarLengthArray<int> varl1;
|
|
QVarLengthArray<int, 3> varl2;
|
|
QVarLengthArray<int, 10> varl3;
|
|
foreach(int i, intlist) {
|
|
varl1 << i;
|
|
varl2 << i;
|
|
varl3 << i;
|
|
}
|
|
QCOMPARE(varl1.count(), intlist.count());
|
|
QCOMPARE(varl2.count(), intlist.count());
|
|
QCOMPARE(varl3.count(), intlist.count());
|
|
foreach_test_arrays(varl1);
|
|
foreach_test_arrays(varl2);
|
|
foreach_test_arrays(varl3);
|
|
|
|
QVarLengthArray<QString> varl4;
|
|
QVarLengthArray<QString, 3> varl5;
|
|
QVarLengthArray<QString, 18> varl6;
|
|
foreach(const QString &str, strlist) {
|
|
varl4 << str;
|
|
varl5 << str;
|
|
varl6 << str;
|
|
}
|
|
QCOMPARE(varl4.count(), strlist.count());
|
|
QCOMPARE(varl5.count(), strlist.count());
|
|
QCOMPARE(varl6.count(), strlist.count());
|
|
foreach_test_arrays(varl4);
|
|
foreach_test_arrays(varl5);
|
|
foreach_test_arrays(varl6);
|
|
}
|
|
|
|
struct IntOrString
|
|
{
|
|
int val;
|
|
IntOrString(int v) : val(v) { }
|
|
IntOrString(const QString &v) : val(v.toInt()) { }
|
|
operator int() { return val; }
|
|
operator QString() { return QString::number(val); }
|
|
#ifndef QT_NO_STL
|
|
operator std::string() { return QString::number(val).toStdString(); }
|
|
IntOrString(const std::string &v) : val(QString::fromStdString(v).toInt()) { }
|
|
#endif
|
|
};
|
|
|
|
template<class Container> void insert_remove_loop_impl()
|
|
{
|
|
typedef typename Container::value_type T;
|
|
Container t;
|
|
t.append(T(IntOrString(1)));
|
|
t << (T(IntOrString(2)));
|
|
t += (T(IntOrString(3)));
|
|
t.prepend(T(IntOrString(4)));
|
|
t.insert(2, 3 , T(IntOrString(5)));
|
|
t.insert(4, T(IntOrString(6)));
|
|
t.insert(t.begin() + 2, T(IntOrString(7)));
|
|
t.insert(t.begin() + 5, 3, T(IntOrString(8)));
|
|
int expect1[] = { 4 , 1 , 7, 5 , 5 , 8, 8, 8, 6, 5, 2 , 3 };
|
|
QCOMPARE(size_t(t.count()), sizeof(expect1)/sizeof(int));
|
|
for (int i = 0; i < t.count(); i++) {
|
|
QCOMPARE(t[i], T(IntOrString(expect1[i])));
|
|
}
|
|
|
|
Container compare_test1 = t;
|
|
t.replace(5, T(IntOrString(9)));
|
|
Container compare_test2 = t;
|
|
QVERIFY(!(compare_test1 == t));
|
|
QVERIFY( (compare_test1 != t));
|
|
QVERIFY( (compare_test2 == t));
|
|
QVERIFY(!(compare_test2 != t));
|
|
t.remove(7);
|
|
t.remove(2, 3);
|
|
int expect2[] = { 4 , 1 , 9, 8, 6, 5, 2 , 3 };
|
|
QCOMPARE(size_t(t.count()), sizeof(expect2)/sizeof(int));
|
|
for (int i = 0; i < t.count(); i++) {
|
|
QCOMPARE(t[i], T(IntOrString(expect2[i])));
|
|
}
|
|
|
|
for (typename Container::iterator it = t.begin(); it != t.end(); ) {
|
|
if ( int(IntOrString(*it)) % 2 )
|
|
++it;
|
|
else
|
|
it = t.erase(it);
|
|
}
|
|
|
|
int expect3[] = { 1 , 9, 5, 3 };
|
|
QCOMPARE(size_t(t.count()), sizeof(expect3)/sizeof(int));
|
|
for (int i = 0; i < t.count(); i++) {
|
|
QCOMPARE(t[i], T(IntOrString(expect3[i])));
|
|
}
|
|
|
|
t.erase(t.begin() + 1, t.end() - 1);
|
|
|
|
int expect4[] = { 1 , 3 };
|
|
QCOMPARE(size_t(t.count()), sizeof(expect4)/sizeof(int));
|
|
for (int i = 0; i < t.count(); i++) {
|
|
QCOMPARE(t[i], T(IntOrString(expect4[i])));
|
|
}
|
|
|
|
t << T(IntOrString(10)) << T(IntOrString(11)) << T(IntOrString(12)) << T(IntOrString(13));
|
|
t << T(IntOrString(14)) << T(IntOrString(15)) << T(IntOrString(16)) << T(IntOrString(17));
|
|
t << T(IntOrString(18)) << T(IntOrString(19)) << T(IntOrString(20)) << T(IntOrString(21));
|
|
for (typename Container::iterator it = t.begin(); it != t.end(); ++it) {
|
|
int iv = int(IntOrString(*it));
|
|
if ( iv % 2 ) {
|
|
it = t.insert(it, T(IntOrString(iv * iv)));
|
|
it = t.insert(it + 2, T(IntOrString(iv * iv + 1)));
|
|
}
|
|
}
|
|
|
|
int expect5[] = { 1, 1, 2, 3*3, 3, 3*3+1, 10, 11*11, 11, 11*11+1, 12 , 13*13, 13, 13*13+1, 14,
|
|
15*15, 15, 15*15+1, 16 , 17*17, 17, 17*17+1 ,18 , 19*19, 19, 19*19+1, 20, 21*21, 21, 21*21+1 };
|
|
QCOMPARE(size_t(t.count()), sizeof(expect5)/sizeof(int));
|
|
for (int i = 0; i < t.count(); i++) {
|
|
QCOMPARE(t[i], T(IntOrString(expect5[i])));
|
|
}
|
|
}
|
|
|
|
|
|
//Add insert(int, int, T) so it has the same interface as QVector and QVarLengthArray for the test.
|
|
template<typename T>
|
|
struct ExtList : QList<T> {
|
|
using QList<T>::insert;
|
|
void insert(int before, int n, const T&x) {
|
|
while (n--) {
|
|
this->insert(before, x );
|
|
}
|
|
}
|
|
void insert(typename QList<T>::iterator before, int n, const T&x) {
|
|
while (n--) {
|
|
before = this->insert(before, x);
|
|
}
|
|
}
|
|
|
|
void remove(int i) {
|
|
this->removeAt(i);
|
|
}
|
|
void remove(int i, int n) {
|
|
while (n--) {
|
|
this->removeAt(i);
|
|
}
|
|
}
|
|
};
|
|
|
|
void tst_Collections::insert_remove_loop()
|
|
{
|
|
insert_remove_loop_impl<ExtList<int> >();
|
|
insert_remove_loop_impl<ExtList<QString> >();
|
|
insert_remove_loop_impl<QVector<int> >();
|
|
insert_remove_loop_impl<QVector<QString> >();
|
|
insert_remove_loop_impl<QVarLengthArray<int> >();
|
|
insert_remove_loop_impl<QVarLengthArray<QString> >();
|
|
insert_remove_loop_impl<QVarLengthArray<int, 10> >();
|
|
insert_remove_loop_impl<QVarLengthArray<QString, 10> >();
|
|
insert_remove_loop_impl<QVarLengthArray<int, 3> >();
|
|
insert_remove_loop_impl<QVarLengthArray<QString, 3> >();
|
|
insert_remove_loop_impl<QVarLengthArray<int, 15> >();
|
|
insert_remove_loop_impl<QVarLengthArray<QString, 15> >();
|
|
|
|
#ifndef QT_NO_STL
|
|
insert_remove_loop_impl<ExtList<std::string> >();
|
|
insert_remove_loop_impl<QVector<std::string> >();
|
|
insert_remove_loop_impl<QVarLengthArray<std::string> >();
|
|
insert_remove_loop_impl<QVarLengthArray<std::string, 10> >();
|
|
insert_remove_loop_impl<QVarLengthArray<std::string, 3> >();
|
|
insert_remove_loop_impl<QVarLengthArray<std::string, 15> >();
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
QTEST_APPLESS_MAIN(tst_Collections)
|
|
#include "tst_collections.moc"
|