1
/****************************************************************************
2
**
3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
7
** This file is part of the test suite of the Qt Toolkit.
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
**
18
** In addition, as a special exception, Nokia gives you certain additional
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21
**
22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
29
**
30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
33
**
34
**
35
**
36
**
37
**
38
** $QT_END_LICENSE$
39
**
40
****************************************************************************/
41
42
43
// test the container forwards
44
#include <QtContainerFwd>
45
46
static QCache<int, int> *cacheX;
47
static QHash<int, int> *hashX;
48
static QLinkedList<int> *linkedListX;
49
static QList<int> *listX;
50
static QMap<int, int> *mapX;
51
static QMultiHash<int, int> *multiHashX;
52
static QMultiMap<int, int> *multiMapX;
53
static QPair<int, int> *pairX;
54
static QQueue<int> *queueX;
55
static QSet<int> *setX;
56
static QStack<int> *stackX;
57
static QVarLengthArray<int> *varLengthArrayX;
58
static QVarLengthArray<int, 512> *varLengthArrayY;
59
static QVector<int> *vectorX;
60
61
void foo()
62
{
63
    cacheX = 0;
64
    hashX = 0;
65
    linkedListX = 0;
66
    listX = 0;
67
    mapX = 0;
68
    multiHashX = 0;
69
    multiMapX = 0;
70
    pairX = 0;
71
    queueX = 0;
72
    setX = 0;
73
    stackX = 0;
74
    varLengthArrayX = 0;
75
    varLengthArrayY = 0;
76
    vectorX = 0;
77
}
78
79
#include <QtTest/QtTest>
80
81
#ifndef QT_NO_STL
82
#  include <algorithm>
83
#endif
84
85
#include "qalgorithms.h"
86
#include "qbitarray.h"
87
#include "qbytearray.h"
88
#include "qcache.h"
89
#include "qhash.h"
90
#include "qlinkedlist.h"
91
#include "qlist.h"
92
#include "qmap.h"
93
#include "qpair.h"
94
#include "qregexp.h"
95
#include "qset.h"
96
#include "qstack.h"
97
#include "qstring.h"
98
#include "qstringlist.h"
99
#include "qvarlengtharray.h"
100
#include "qvector.h"
101
#include "qqueue.h"
102
103
#ifdef QT3_SUPPORT
104
#include "q3cleanuphandler.h"
105
#endif
106
107
template class QList<int>;
108
109
//TESTED_FILES=
110
111
class tst_Collections : public QObject
112
{
113
    Q_OBJECT
114
115
public:
116
    tst_Collections();
117
    ~tst_Collections();
118
119
public slots:
120
    void init();
121
    void cleanup();
122
private slots:
123
    void typeinfo();
124
    void qstring();
125
    void list();
126
    void linkedList();
127
    void vector();
128
    void byteArray();
129
    void stack();
130
    void hash();
131
    void map();
132
    void bitArray();
133
    void cache();
134
    void regexp();
135
    void pair();
136
    void cleanupHandler();
137
    void sharableQList();
138
    void sharableQLinkedList();
139
    void sharableQVector();
140
    void sharableQMap();
141
    void sharableQHash();
142
    void q_foreach();
143
    void conversions();
144
    void javaStyleIterators();
145
    void constAndNonConstStlIterators();
146
#ifndef QT_NO_STL
147
    void vector_stl_data();
148
    void vector_stl();
149
    void list_stl_data();
150
    void list_stl();
151
    void linkedlist_stl_data();
152
    void linkedlist_stl();
153
#endif
154
    void q_init();
155
    void pointersize();
156
    void containerInstantiation();
157
    void qtimerList();
158
    void containerTypedefs();
159
    void forwardDeclared();
160
    void alignment();
161
    void QTBUG13079_collectionInsideCollection();
162
163
    void foreach_2();
164
    void insert_remove_loop();
165
};
166
167
struct LargeStatic {
168
    static int count;
169
    LargeStatic():c(count) { ++count; }
170
    LargeStatic(const LargeStatic& o):c(o.c) { ++count; }
171
    ~LargeStatic() { --count; }
172
    int c;
173
    int data[8];
174
};
175
176
int LargeStatic::count = 0;
177
178
struct Movable {
179
    static int count;
180
    Movable():c(count) { ++count; }
181
    Movable(const Movable& o):c(o.c) { ++count; }
182
    ~Movable() { --count; }
183
    int c;
184
};
185
186
int Movable::count = 0;
187
QT_BEGIN_NAMESPACE
188
Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE);
189
QT_END_NAMESPACE
190
191
192
struct Pod {
193
    int i1, i2;
194
};
195
196
tst_Collections::tst_Collections()
197
{
198
}
199
200
tst_Collections::~tst_Collections()
201
{
202
203
}
204
205
void tst_Collections::init()
206
{
207
}
208
209
void tst_Collections::cleanup()
210
{
211
}
212
213
void tst_Collections::typeinfo()
214
{
215
    QVERIFY(QTypeInfo<int*>::isPointer);
216
    QVERIFY(!QTypeInfo<int>::isPointer);
217
    QVERIFY(QTypeInfo<QString>::isComplex);
218
    QVERIFY(!QTypeInfo<int>::isComplex);
219
}
220
221
void tst_Collections::list()
222
{
223
    {
224
	QList<int> list;
225
	QVERIFY(list.isEmpty());
226
	list.append(1);
227
	QVERIFY(list.size() == 1);
228
229
	QVERIFY(*list.begin() == 1);
230
231
	list.push_back(2);
232
	list += (3);
233
	list << 4 << 5 << 6;
234
	QVERIFY(!list.isEmpty());
235
	QVERIFY(list.size() == 6);
236
	QVERIFY(list.end() - list.begin() == list.size());
237
238
#if !defined(QT_NO_STL) && !defined(Q_CC_MSVC) && !defined(Q_CC_SUN)
239
	QVERIFY(std::binary_search(list.begin(), list.end(), 2) == true);
240
	QVERIFY(std::binary_search(list.begin(), list.end(), 9) == false);
241
#endif
242
	QVERIFY(qBinaryFind(list.begin(), list.end(), 2) == list.begin() + 1);
243
	QVERIFY(qLowerBound(list.begin(), list.end(), 2) == list.begin() + 1);
244
        QVERIFY(qUpperBound(list.begin(), list.end(), 2) == list.begin() + 2);
245
	QVERIFY(qBinaryFind(list.begin(), list.end(), 9) == list.end());
246
	QVERIFY(qLowerBound(list.begin(), list.end(), 9) == list.end());
247
        QVERIFY(qUpperBound(list.begin(), list.end(), 9) == list.end());
248
	{
249
	    int sum = 0;
250
	    QListIterator<int> i(list);
251
	    while (i.hasNext())
252
		sum += i.next();
253
	    QVERIFY(sum == 21);
254
	}
255
256
	{
257
	    QList<int> list1;
258
            list1 << 1 << 2 << 3 << 5 << 7 << 8 << 9;
259
	    QList<int> list2 = list1;
260
261
	    QMutableListIterator<int> i1(list1);
262
            while (i1.hasNext()) {
263
		if (i1.next() % 2 != 0)
264
		    i1.remove();
265
	    }
266
267
	    QMutableListIterator<int> i2(list2);
268
            i2.toBack();
269
            while (i2.hasPrevious()) {
270
		if (i2.previous() % 2 != 0)
271
		    i2.remove();
272
            }
273
            QVERIFY(list1.size() == 2);
274
            QVERIFY(list2.size() == 2);
275
            QVERIFY(list1 == list2);
276
        }
277
278
	{
279
	    int sum = 0;
280
	    for (int i = 0; i < list.size(); ++i)
281
		sum += list[i];
282
	    QVERIFY(sum == 21);
283
	}
284
	{
285
	    int sum = 0;
286
	    QList<int>::const_iterator i = list.begin();
287
	    while (i != list.end())
288
		sum += *i++;
289
	    QVERIFY(sum == 21);
290
	}
291
	{
292
	    int sum = 0;
293
	    QList<int>::ConstIterator i = list.begin();
294
	    while (i != list.end())
295
		sum += *i++;
296
	    QVERIFY(sum == 21);
297
	}
298
	{
299
	    QList<int>::Iterator i = list.begin();
300
            i += 2;
301
            QCOMPARE(*i, 3);
302
            i -= 1;
303
            QCOMPARE(*i, 2);
304
	}
305
	{
306
	    QList<int>::ConstIterator i = list.begin();
307
            i += 2;
308
            QCOMPARE(*i, 3);
309
            i -= 1;
310
            QCOMPARE(*i, 2);
311
	}
312
	{
313
	    int sum = 0;
314
	    int i;
315
	    for (i = 0; i < list.size(); ++i)
316
		list[i] = list[i] +1;
317
	    for (i = 0; i < list.size(); ++i)
318
		sum += list[i];
319
	    QVERIFY(sum == 21 + list.size());
320
	}
321
	{
322
	    int sum = 0;
323
	    int i;
324
	    for (i = 0; i < list.size(); ++i)
325
		--list[i];
326
	    for (i = 0; i < list.size(); ++i)
327
		sum += list[i];
328
	    QVERIFY(sum == 21);
329
	}
330
	{
331
	    QMutableListIterator<int> i(list);
332
	    while (i.hasNext())
333
		i.setValue(2*i.next());
334
	}
335
	{
336
	    int sum = 0;
337
	    QListIterator<int> i(list);
338
	    i.toBack();
339
	    while (i.hasPrevious())
340
		sum += i.previous();
341
	    QVERIFY(sum == 2*21);
342
	}
343
	{
344
	    QMutableListIterator<int> i(list);
345
	    i.toBack();
346
	    while (i.hasPrevious())
347
		i.setValue(2*i.previous());
348
	}
349
	{
350
	    int sum = 0;
351
	    QListIterator<int> i(list);
352
	    i.toBack();
353
	    while (i.hasPrevious())
354
		sum += i.previous();
355
	    QVERIFY(sum == 2*2*21);
356
	}
357
	{
358
	    QMutableListIterator<int> i(list);
359
	    while (i.hasNext()) {
360
		int a = i.next();
361
		i.insert(a);
362
	    }
363
	}
364
	{
365
	    int sum = 0;
366
	    QList<int>::iterator i = list.begin();
367
	    while (i != list.end())
368
		sum += *i++;
369
	    QVERIFY(sum == 2*2*2*21);
370
	}
371
	{
372
	    int duplicates = 0;
373
	    QListIterator<int> i(list);
374
	    while (i.hasNext()) {
375
		int a = i.next();
376
		if (i.hasNext() && a == i.peekNext())
377
		    duplicates++;
378
	    }
379
	    QVERIFY(duplicates == 6);
380
	}
381
	{
382
	    int duplicates = 0;
383
	    QListIterator<int> i(list);
384
	    i.toBack();
385
	    while (i.hasPrevious()) {
386
		int a = i.previous();
387
		if (i.hasPrevious() && a == i.peekPrevious())
388
		    duplicates++;
389
	    }
390
	    QVERIFY(duplicates == 6);
391
	}
392
	{
393
	    QMutableListIterator<int> i(list);
394
	    while (i.hasNext()) {
395
		int a = i.next();
396
		if (i.hasNext() &&
397
		     i.peekNext() == a)
398
		    i.remove();
399
	    }
400
	}
401
	{
402
	    int duplicates = 0;
403
	    QMutableListIterator<int> i = list;
404
	    i.toBack();
405
	    while (i.hasPrevious()) {
406
		int a = i.previous();
407
		if (i.hasPrevious() && a == i.peekPrevious())
408
		    duplicates++;
409
	    }
410
	    QVERIFY(duplicates == 0);
411
	}
412
	{
413
	    QVERIFY(list.size() == 6);
414
	    QMutableListIterator<int> i = list;
415
	    while (i.hasNext()) {
416
		int a = i.peekNext();
417
		i.insert(42);
418
		QVERIFY(i.peekPrevious() == 42 && i.peekNext() == a);
419
		i.next();
420
	    }
421
	    QVERIFY(list.size() == 12);
422
	    i.toFront();
423
	    while (i.findNext(42))
424
		i.remove();
425
	}
426
	{
427
	    QList<int> l;
428
	    l << 4 << 8 << 12 << 16 << 20 << 24;
429
	    QVERIFY(l == list);
430
	    QList<int> copy = list;
431
	    list += list;
432
	    QVERIFY(l != list && l.size() == list.size()/2 && l == copy);
433
	    l += copy;
434
	    QVERIFY(l == list);
435
	    list = copy;
436
	}
437
	{
438
	    QList<int> copy = list;
439
	    list << 8;
440
	    QVERIFY(list.indexOf(8) == 1);
441
	    QVERIFY(list.indexOf(8, list.indexOf(8)+1) == 6);
442
	    int a = list.indexOf(8);
443
	    QVERIFY(list.count(8) == 2);
444
	    int r = list.removeAll(8);
445
	    QVERIFY(r == 2);
446
	    list.insert(a, 8);
447
	    QVERIFY(list == copy);
448
	}
449
        {
450
            QList<QString> list;
451
            list << "one" << "two" << "three" << "four" << "five" << "six";
452
            while (!list.isEmpty())
453
                list.removeAll(list.first());
454
        }
455
        {
456
            QList<QString> list;
457
            list << "one" << "two" << "one" << "two";
458
            QVERIFY(!list.removeOne("three"));
459
            QVERIFY(list.removeOne("two"));
460
            QCOMPARE(list, QList<QString>() << "one" << "one" << "two");;
461
            QVERIFY(list.removeOne("two"));
462
            QCOMPARE(list, QList<QString>() << "one" << "one");
463
            QVERIFY(!list.removeOne("two"));
464
            QCOMPARE(list, QList<QString>() << "one" << "one");
465
            QVERIFY(list.removeOne("one"));
466
            QCOMPARE(list, QList<QString>() << "one");
467
            QVERIFY(list.removeOne("one"));
468
            QVERIFY(list.isEmpty());
469
            QVERIFY(!list.removeOne("one"));
470
            QVERIFY(list.isEmpty());
471
        }
472
	{
473
	    QList<int> copy = list;
474
	    list << 8;
475
	    QVERIFY(list.lastIndexOf(8) == 6);
476
	    QVERIFY(list.lastIndexOf(8, list.lastIndexOf(8)-1) == 1);
477
	    list = copy;
478
	}
479
	{
480
	    QList<int> copy = list;
481
	    list.insert(3, 999);
482
	    QVERIFY(list[3] == 999);
483
	    list.replace(3, 222);
484
	    QVERIFY(list[3] == 222);
485
	    QVERIFY(list.contains(222) && ! list.contains(999));
486
	    list.removeAt(3);
487
	    list = copy;
488
	    QVERIFY(list == copy);
489
	}
490
	{
491
	    list.clear();
492
	    QVERIFY(list.isEmpty());
493
	    QVERIFY(list.begin() == list.end());
494
	    QListIterator<int> i(list);
495
	    QVERIFY(!i.hasNext() && !i.hasPrevious());
496
	}
497
	{
498
	    QList<int> l1;
499
	    QList<int> l2;
500
	    l1 << 1 << 2 << 3;
501
	    l2 << 4 << 5 << 6;
502
	    QList<int> l3 = l1 + l2;
503
	    l1 += l2;
504
	    QVERIFY(l3 == l1);
505
	}
506
	{
507
	    QList<int> list;
508
	    QVERIFY(list.isEmpty());
509
	    list.append(1);
510
	    QList<int> list2;
511
	    list2 = list;
512
	    list2.clear();
513
	    QVERIFY(list2.size() == 0);
514
	    QVERIFY(list.size() == 1);
515
	}
516
	{
517
	    QList<int> list;
518
	    list.append(1);
519
	    list = list;
520
	    QVERIFY(list.size() == 1);
521
	}
522
    }
523
    {
524
	QList<void*> list;
525
	list.append(0);
526
	list.append((void*)42);
527
	QCOMPARE(list.size(), 2);
528
	QCOMPARE(list.at(0), (void*)0);
529
	QCOMPARE(list.at(1), (void*)42);
530
    }
531
532
    {
533
	QVector<QString> vector(5);
534
        vector[0] = "99";
535
        vector[4] ="100";
536
        QList<QString> list = vector.toList();
537
538
	QVERIFY(list.size() == 5);
539
        QVERIFY(list.at(0) == "99");
540
        QVERIFY(list.at(4) == "100");
541
        list[0] = "10";
542
        QVERIFY(list.at(0) == "10");
543
        QVERIFY(vector.at(0) == "99");
544
545
    }
546
547
    {
548
        QList<QString> list;
549
        list.append("Hello");
550
551
        QList<QString>::iterator it = list.begin();
552
        QVERIFY((*it)[0] == QChar('H'));
553
        QVERIFY(it->constData()[0] == QChar('H'));
554
        it->replace(QChar('H'), QChar('X'));
555
        QVERIFY(list.first() == "Xello");
556
557
        QList<QString>::const_iterator cit = list.constBegin();
558
        QVERIFY((*cit).toLower() == "xello");
559
        QVERIFY(cit->toUpper() == "XELLO");
560
    }
561
562
    {
563
        QList<int *> list;
564
        QVERIFY(list.value(0) == 0);
565
        int i;
566
        list.append(&i);
567
        QVERIFY(list.value(0) == &i);
568
    }
569
    {
570
        QList<const int *> list;
571
        QVERIFY(list.value(0) == 0);
572
        int i;
573
        list.append(&i);
574
        QVERIFY(list.value(0) == &i);
575
    }
576
    {
577
        QList<int> list;
578
        QVERIFY(list.value(0) == 0);
579
        list.append(10);
580
        QVERIFY(list.value(0) == 10);
581
    }
582
    {
583
        QList<Pod> list;
584
        QCOMPARE(list.value(0).i1, 0);
585
        QCOMPARE(list.value(0).i2, 0);
586
    }
587
588
    {
589
        QList<QString> list;
590
        list << "alpha" << "beta";
591
        list += list;
592
        QVERIFY(list.size() == 4);
593
        QVERIFY(list.at(0) == "alpha");
594
        QVERIFY(list.at(1) == "beta");
595
        QVERIFY(list.at(2) == "alpha");
596
        QVERIFY(list.at(3) == "beta");
597
    }
598
599
    // test endcases for inserting into a qlist
600
    {
601
        QList<QString> list;
602
        list << "foo" << "bar";
603
        QVERIFY(!list.isEmpty());
604
605
        list.insert(-1, "lessthanzero");
606
        QCOMPARE(list.at(0), QString("lessthanzero"));
607
608
        list.insert(0, "atzero");
609
        QCOMPARE(list.at(0), QString("atzero"));
610
611
        int listCount = list.count();
612
        list.insert(listCount, "atcount");
613
        QCOMPARE(list.at(listCount), QString("atcount"));
614
615
        listCount = list.count();
616
        list.insert(listCount + 1, "beyondcount");
617
        QCOMPARE(list.at(listCount), QString("beyondcount"));
618
    }
619
620
    {
621
        QList<int> list1;
622
        list1 << 0 << 1 << 2 << 3;
623
        list1.removeFirst();
624
625
        list1.swap(0, 0);
626
        QVERIFY(list1 == QList<int>() << 1 << 2 << 3);
627
628
        list1.swap(1, 1);
629
        QVERIFY(list1 == QList<int>() << 1 << 2 << 3);
630
631
        list1.swap(2, 2);
632
        QVERIFY(list1 == QList<int>() << 1 << 2 << 3);
633
634
        list1.swap(0, 1);
635
        QVERIFY(list1 == QList<int>() << 2 << 1 << 3);
636
637
        list1.swap(0, 2);
638
        QVERIFY(list1 == QList<int>() << 3 << 1 << 2);
639
640
        list1.swap(1, 2);
641
        QVERIFY(list1 == QList<int>() << 3 << 2 << 1);
642
643
        list1.swap(1, 2);
644
        QVERIFY(list1 == QList<int>() << 3 << 1 << 2);
645
646
        QList<QString> list2;
647
        list2 << "1" << "2" << "3";
648
649
        list2.swap(0, 0);
650
        QVERIFY(list2 == QList<QString>() << "1" << "2" << "3");
651
652
        list2.swap(1, 1);
653
        QVERIFY(list2 == QList<QString>() << "1" << "2" << "3");
654
655
        list2.swap(2, 2);
656
        QVERIFY(list2 == QList<QString>() << "1" << "2" << "3");
657
658
        list2.swap(0, 1);
659
        QVERIFY(list2 == QList<QString>() << "2" << "1" << "3");
660
661
        list2.swap(0, 2);
662
        QVERIFY(list2 == QList<QString>() << "3" << "1" << "2");
663
664
        list2.swap(1, 2);
665
        QVERIFY(list2 == QList<QString>() << "3" << "2" << "1");
666
667
        list2.swap(1, 2);
668
        QVERIFY(list2 == QList<QString>() << "3" << "1" << "2");
669
670
        QList<double> list3;
671
        list3 << 1.0 << 2.0 << 3.0;
672
673
        list3.swap(0, 0);
674
        QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0);
675
676
        list3.swap(1, 1);
677
        QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0);
678
679
        list3.swap(2, 2);
680
        QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0);
681
682
        list3.swap(0, 1);
683
        QVERIFY(list3 == QList<double>() << 2.0 << 1.0 << 3.0);
684
685
        list3.swap(0, 2);
686
        QVERIFY(list3 == QList<double>() << 3.0 << 1.0 << 2.0);
687
688
        list3.swap(1, 2);
689
        QVERIFY(list3 == QList<double>() << 3.0 << 2.0 << 1.0);
690
691
        list3.swap(1, 2);
692
        QVERIFY(list3 == QList<double>() << 3.0 << 1.0 << 2.0);
693
    }
694
695
    // Check what happens when using references to own items.
696
    // Ideally we should run valgrind on this.
697
    {
698
        int i;
699
700
        QList<void *> list1;
701
        list1.append(reinterpret_cast<void *>(50));
702
703
        for (i = 1; i < 100; ++i) {
704
            list1.append(list1.at(i - 1));
705
            list1.prepend(list1.at(i));
706
            list1.insert(i, list1.at(i - 1));
707
            list1.insert(i, list1.at(i));
708
            list1.insert(i, list1.at(i + 1));
709
            list1.replace(i, list1.at(i - 1));
710
            list1.replace(i, list1.at(i));
711
            list1.replace(i, list1.at(i + 1));
712
        }
713
        QCOMPARE(list1.size(), 496);
714
        for (i = 0; i < list1.size(); ++i) {
715
            QCOMPARE(list1.at(i), reinterpret_cast<void *>(50));
716
        }
717
718
        QList<QString> list2;
719
        list2.append("50");
720
721
        for (i = 1; i < 100; ++i) {
722
            list2.append(list2.at(i - 1));
723
            list2.prepend(list2.at(i));
724
            list2.insert(i, list2.at(i - 1));
725
            list2.insert(i, list2.at(i));
726
            list2.insert(i, list2.at(i + 1));
727
            list2.replace(i, list2.at(i - 1));
728
            list2.replace(i, list2.at(i));
729
            list2.replace(i, list2.at(i + 1));
730
        }
731
        QCOMPARE(list2.size(), 496);
732
        for (i = 0; i < list2.size(); ++i) {
733
            QCOMPARE(list2.at(i), QString::fromLatin1("50"));
734
        }
735
736
        QList<double> list3;
737
        list3.append(50.0);
738
739
        for (i = 1; i < 100; ++i) {
740
            list3.append(list3.at(i - 1));
741
            list3.prepend(list3.at(i));
742
            list3.insert(i, list3.at(i - 1));
743
            list3.insert(i, list3.at(i));
744
            list3.insert(i, list3.at(i + 1));
745
            list3.replace(i, list3.at(i - 1));
746
            list3.replace(i, list3.at(i));
747
            list3.replace(i, list3.at(i + 1));
748
        }
749
        QCOMPARE(list3.size(), 496);
750
        for (i = 0; i < list3.size(); ++i) {
751
            QCOMPARE(list3.at(i), 50.0);
752
        }
753
754
        QList<QTime> list4;
755
        list4.append(QTime(12, 34, 56));
756
757
        for (i = 1; i < 100; ++i) {
758
            list4.append(list4.at(i - 1));
759
            list4.prepend(list4.at(i));
760
            list4.insert(i, list4.at(i - 1));
761
            list4.insert(i, list4.at(i));
762
            list4.insert(i, list4.at(i + 1));
763
            list4.replace(i, list4.at(i - 1));
764
            list4.replace(i, list4.at(i));
765
            list4.replace(i, list4.at(i + 1));
766
        }
767
        QCOMPARE(list4.size(), 496);
768
        for (i = 0; i < list4.size(); ++i) {
769
            QVERIFY(list4.at(i) == QTime(12, 34, 56));
770
        }
771
772
    }
773
    {
774
        QList<int> a;
775
        QCOMPARE(a.startsWith(1), false);
776
        QCOMPARE(a.endsWith(1), false);
777
        a.append(1);
778
        QCOMPARE(a.startsWith(1), true);
779
        QCOMPARE(a.startsWith(2), false);
780
        QCOMPARE(a.endsWith(1), true);
781
        QCOMPARE(a.endsWith(2), false);
782
        a.append(2);
783
        QCOMPARE(a.startsWith(1), true);
784
        QCOMPARE(a.startsWith(2), false);
785
        QCOMPARE(a.endsWith(1), false);
786
        QCOMPARE(a.endsWith(2), true);
787
    }
788
}
789
790
void tst_Collections::linkedList()
791
{
792
    {
793
	QLinkedList<int> list;
794
	QVERIFY(list.isEmpty());
795
	list.append(1);
796
	list.push_back(2);
797
	list += (3);
798
	list << 4 << 5 << 6;
799
	QVERIFY(!list.isEmpty());
800
	QVERIFY(list.size() == 6);
801
	{
802
	    int sum = 0;
803
	    QLinkedListIterator<int> i = list;
804
	    while (i.hasNext()) {
805
		sum += i.next();
806
	    }
807
	    QVERIFY(sum == 21);
808
	}
809
	{
810
	    int sum = 0;
811
	    QLinkedList<int>::const_iterator i = list.begin();
812
	    while (i != list.end())
813
		sum += *i++;
814
	    QVERIFY(sum == 21);
815
	}
816
	{
817
	    QMutableLinkedListIterator<int> i = list;
818
	    while (i.hasNext())
819
		i.setValue(2*i.next());
820
	}
821
	{
822
	    int sum = 0;
823
	    QLinkedListIterator<int> i = list;
824
	    i.toBack();
825
	    while (i.hasPrevious())
826
		sum += i.previous();
827
	    QVERIFY(sum == 2*21);
828
	}
829
	{
830
	    QMutableLinkedListIterator<int> i = list;
831
	    i.toBack();
832
	    while (i.hasPrevious())
833
		i.setValue(2*i.previous());
834
	}
835
	{
836
	    int sum = 0;
837
	    QLinkedListIterator<int> i = list;
838
	    i.toBack();
839
	    while (i.hasPrevious())
840
		sum += i.previous();
841
	    QVERIFY(sum == 2*2*21);
842
	}
843
	{
844
	    QMutableLinkedListIterator<int> i = list;
845
	    while (i.hasNext()) {
846
		int a = i.next();
847
		i.insert(a);
848
	    }
849
	}
850
	{
851
	    int sum = 0;
852
	    QLinkedList<int>::iterator i = list.begin();
853
	    while (i != list.end())
854
		sum += *i++;
855
	    QVERIFY(sum == 2*2*2*21);
856
	}
857
	{
858
	    int duplicates = 0;
859
	    QLinkedListIterator<int> i = list;
860
	    while (i.hasNext()) {
861
		int a = i.next();
862
		if (i.hasNext() && a == i.peekNext())
863
		    duplicates++;
864
	    }
865
	    QVERIFY(duplicates == 6);
866
	}
867
	{
868
	    int duplicates = 0;
869
	    QLinkedListIterator<int> i = list;
870
	    i.toBack();
871
	    while (i.hasPrevious()) {
872
		int a = i.previous();
873
		if (i.hasPrevious() && a == i.peekPrevious())
874
		    duplicates++;
875
	    }
876
	    QVERIFY(duplicates == 6);
877
	}
878
	{
879
	    QMutableLinkedListIterator<int> i = list;
880
	    while (i.hasNext()) {
881
		int a = i.next();
882
		if (i.hasNext() &&
883
		     i.peekNext() == a)
884
		    i.remove();
885
	    }
886
	}
887
	{
888
	    int duplicates = 0;
889
	    QMutableLinkedListIterator<int> i = list;
890
	    i.toBack();
891
	    while (i.hasPrevious()) {
892
		int a = i.previous();
893
		if (i.hasPrevious() && a == i.peekPrevious())
894
		    duplicates++;
895
	    }
896
	    QVERIFY(duplicates == 0);
897
	}
898
	{
899
	    QVERIFY(list.size() == 6);
900
	    QMutableLinkedListIterator<int> i = list;
901
	    while (i.hasNext()) {
902
		int a = i.peekNext();
903
		i.insert(42);
904
		QVERIFY(i.peekPrevious() == 42 && i.peekNext() == a);
905
		i.next();
906
	    }
907
	    QVERIFY(list.size() == 12);
908
	    i.toFront();
909
	    while (i.findNext(42))
910
		i.remove();
911
	}
912
	{
913
	    QLinkedList<int> l;
914
	    l << 4 << 8 << 12 << 16 << 20 << 24;
915
	    QVERIFY(l == list);
916
	    QLinkedList<int> copy = list;
917
	    list += list;
918
	    QVERIFY(l != list && l.size() == list.size()/2 && l == copy);
919
	    l += copy;
920
	    QVERIFY(l == list);
921
	    list = copy;
922
	}
923
	{
924
	    QLinkedList<int> copy = list;
925
	    list.prepend(999);
926
	    list.append(999);
927
	    QVERIFY(list.contains(999));
928
	    QVERIFY(list.count(999) == 2);
929
	    list.removeAll(999);
930
	    QVERIFY(list == copy);
931
	}
932
        {
933
            QLinkedList<QString> list;
934
            list << "one" << "two" << "three" << "four" << "five" << "six";
935
            while (!list.isEmpty())
936
                list.removeAll(list.first());
937
        }
938
        {
939
            QLinkedList<QString> list;
940
            list << "one" << "two" << "one" << "two";
941
            QVERIFY(!list.removeOne("three"));
942
            QVERIFY(list.removeOne("two"));
943
            QCOMPARE(list, QLinkedList<QString>() << "one" << "one" << "two");;
944
            QVERIFY(list.removeOne("two"));
945
            QCOMPARE(list, QLinkedList<QString>() << "one" << "one");
946
            QVERIFY(!list.removeOne("two"));
947
            QCOMPARE(list, QLinkedList<QString>() << "one" << "one");
948
            QVERIFY(list.removeOne("one"));
949
            QCOMPARE(list, QLinkedList<QString>() << "one");
950
            QVERIFY(list.removeOne("one"));
951
            QVERIFY(list.isEmpty());
952
            QVERIFY(!list.removeOne("one"));
953
            QVERIFY(list.isEmpty());
954
        }
955
        {
956
	    list.clear();
957
	    QVERIFY(list.isEmpty());
958
	    QVERIFY(list.begin() == list.end());
959
	    QLinkedListIterator<int> i(list);
960
	    QVERIFY(!i.hasNext() && !i.hasPrevious());
961
	}
962
    }
963
964
    {
965
        QLinkedList<QString> list;
966
        list.append("Hello");
967
968
        QLinkedList<QString>::iterator it = list.begin();
969
        QVERIFY((*it)[0] == QChar('H'));
970
        QVERIFY(it->constData()[0] == QChar('H'));
971
        it->replace(QChar('H'), QChar('X'));
972
        QVERIFY(list.first() == "Xello");
973
974
        QLinkedList<QString>::const_iterator cit = list.constBegin();
975
        QVERIFY((*cit).toLower() == "xello");
976
        QVERIFY(cit->toUpper() == "XELLO");
977
    }
978
979
    {
980
        QLinkedList<QString> list;
981
        list << "alpha" << "beta";
982
        list += list;
983
        QVERIFY(list.size() == 4);
984
        QVERIFY(*list.begin() == "alpha");
985
        QVERIFY(*(list.begin() + 1) == "beta");
986
        QVERIFY(*(list.begin() + 2) == "alpha");
987
        QVERIFY(*(list.begin() + 3) == "beta");
988
    }
989
990
    {
991
        QLinkedList<int> a;
992
        QCOMPARE(a.startsWith(1), false);
993
        QCOMPARE(a.endsWith(1), false);
994
        a.append(1);
995
        QCOMPARE(a.startsWith(1), true);
996
        QCOMPARE(a.startsWith(2), false);
997
        QCOMPARE(a.endsWith(1), true);
998
        QCOMPARE(a.endsWith(2), false);
999
        a.append(2);
1000
        QCOMPARE(a.startsWith(1), true);
1001
        QCOMPARE(a.startsWith(2), false);
1002
        QCOMPARE(a.endsWith(1), false);
1003
        QCOMPARE(a.endsWith(2), true);
1004
    }
1005
};
1006
1007
1008
void tst_Collections::vector()
1009
{
1010
    QVector<int> v1;
1011
    v1 << 1 << 2 << 3;
1012
    QVector<int> v2;
1013
    v2 << 4 << 5;
1014
    QVector<int> v3;
1015
    v3 << 1 << 2 << 3 << 4 << 5;
1016
    QVERIFY(v1 + v2 == v3);
1017
1018
    QVector<int> emptyVector;
1019
    QCOMPARE(emptyVector.size(), 0);
1020
#if 0
1021
    // this should trigger an assert
1022
    emptyVector.remove(3, -3);
1023
    QCOMPARE(emptyVector.size(), 0);
1024
#endif
1025
    emptyVector.remove(0, 0);
1026
    QCOMPARE(emptyVector.size(), 0);
1027
1028
    QVector<int> v4;
1029
    v4 << 1 << 2 << 3;
1030
    QCOMPARE(v4.size(), 3);
1031
    v4.remove(1, 0);
1032
    QCOMPARE(v4.size(), 3);
1033
1034
    QVector<int> v;
1035
    v.append(2);
1036
    QVERIFY(*v.begin() == 2);
1037
    v.prepend(1);
1038
1039
    v << 3 << 4 << 5 << 6;
1040
#if !defined(QT_NO_STL)
1041
    QVERIFY(std::binary_search(v.begin(), v.end(), 2) == true);
1042
    QVERIFY(std::binary_search(v.begin(), v.end(), 9) == false);
1043
#endif
1044
    QVERIFY(qBinaryFind(v.begin(), v.end(), 2) == v.begin() + 1);
1045
    QVERIFY(qLowerBound(v.begin(), v.end(), 2) == v.begin() + 1);
1046
    QVERIFY(qUpperBound(v.begin(), v.end(), 2) == v.begin() + 2);
1047
    QVERIFY(qBinaryFind(v.begin(), v.end(), 9) == v.end());
1048
    QVERIFY(qLowerBound(v.begin(), v.end(), 9) == v.end());
1049
    QVERIFY(qUpperBound(v.begin(), v.end(), 9) == v.end());
1050
1051
    v.clear();
1052
    v << 1 << 2 << 3;
1053
    v.insert(v.begin(), 0);
1054
    v.insert(v.end(), 4);
1055
    v.insert(v.begin()+2, 9);
1056
1057
    QVector<int> result;
1058
    result << 0 << 1 << 9 << 2 << 3 << 4;
1059
1060
    QVERIFY( v == result );
1061
1062
    v.clear();
1063
    v << 1 << 2 << 3;
1064
    v.insert(0, 0);
1065
    v.insert(4, 4);
1066
    v.insert(2, 9);
1067
1068
    QVERIFY( v == result );
1069
1070
    QVector<QString> vec;
1071
    vec << "foo" << "bar";
1072
    vec.reserve( 512 );
1073
    QVERIFY(vec[0] == "foo");
1074
    QVERIFY(vec[1] == "bar");
1075
1076
    int initialLargeStaticCount = LargeStatic::count;
1077
    {
1078
        QVector<LargeStatic> vector;
1079
        vector.append(LargeStatic());
1080
        vector.resize(0);
1081
    }
1082
    QCOMPARE(LargeStatic::count, initialLargeStaticCount);
1083
1084
    {
1085
        QVector<QString> vector;
1086
        vector << "alpha" << "beta";
1087
        vector += vector;
1088
        QVERIFY(vector.size() == 4);
1089
        QVERIFY(vector.at(0) == "alpha");
1090
        QVERIFY(vector.at(1) == "beta");
1091
        QVERIFY(vector.at(2) == "alpha");
1092
        QVERIFY(vector.at(3) == "beta");
1093
    }
1094
1095
    int originalLargeStaticCount = LargeStatic::count;
1096
    {
1097
        QVector<LargeStatic> vector(5);
1098
    }
1099
    QVERIFY(LargeStatic::count == originalLargeStaticCount);
1100
    {
1101
        QVector<LargeStatic> vector(5);
1102
        QList<LargeStatic> list = vector.toList();
1103
    }
1104
    QVERIFY(LargeStatic::count == originalLargeStaticCount);
1105
    {
1106
        QVector<LargeStatic> vector;
1107
        LargeStatic *dummy = 0;
1108
        for (int i = 0; i < 10000; ++i) {
1109
            delete dummy;
1110
            dummy = new LargeStatic;
1111
            vector.append(LargeStatic());
1112
        }
1113
	delete dummy;
1114
    }
1115
    QVERIFY(LargeStatic::count == originalLargeStaticCount);
1116
1117
    int originalMovableCount = Movable::count;
1118
    {
1119
        QVector<Movable> vector(5);
1120
    }
1121
    QVERIFY(Movable::count == originalMovableCount);
1122
    {
1123
        QVector<Movable> vector(5);
1124
        QList<Movable> list = vector.toList();
1125
    }
1126
    QVERIFY(Movable::count == originalMovableCount);
1127
    {
1128
        QVector<Movable> vector;
1129
        Movable *dummy = 0;
1130
        for (int i = 0; i < 10000; ++i) {
1131
            delete dummy;
1132
            dummy = new Movable;
1133
            vector.append(Movable());
1134
        }
1135
        delete dummy;
1136
    }
1137
    QVERIFY(Movable::count == originalMovableCount);
1138
1139
    // Check what happens when using references to own items.
1140
    // Ideally we should run valgrind on this.
1141
    {
1142
        int i;
1143
1144
        QVector<void *> vect1;
1145
        vect1.append(reinterpret_cast<void *>(50));
1146
1147
        for (i = 1; i < 100; ++i) {
1148
            vect1.append(vect1.at(i - 1));
1149
            vect1.prepend(vect1.at(i));
1150
            vect1.insert(i, vect1.at(i - 1));
1151
            vect1.insert(i, vect1.at(i));
1152
            vect1.insert(i, vect1.at(i + 1));
1153
            vect1.replace(i, vect1.at(i - 1));
1154
            vect1.replace(i, vect1.at(i));
1155
            vect1.replace(i, vect1.at(i + 1));
1156
        }
1157
        QCOMPARE(vect1.size(), 496);
1158
        for (i = 0; i < vect1.size(); ++i) {
1159
            QCOMPARE(vect1.at(i), reinterpret_cast<void *>(50));
1160
        }
1161
1162
        QVector<QString> vect2;
1163
        vect2.append("50");
1164
1165
        for (i = 1; i < 100; ++i) {
1166
            vect2.append(vect2.at(i - 1));
1167
            vect2.prepend(vect2.at(i));
1168
            vect2.insert(i, vect2.at(i - 1));
1169
            vect2.insert(i, vect2.at(i));
1170
            vect2.insert(i, vect2.at(i + 1));
1171
            vect2.replace(i, vect2.at(i - 1));
1172
            vect2.replace(i, vect2.at(i));
1173
            vect2.replace(i, vect2.at(i + 1));
1174
        }
1175
        QCOMPARE(vect2.size(), 496);
1176
        for (i = 0; i < vect2.size(); ++i) {
1177
            QCOMPARE(vect2.at(i), QString::fromLatin1("50"));
1178
        }
1179
1180
        QVector<double> vect3;
1181
        vect3.append(50.0);
1182
1183
        for (i = 1; i < 100; ++i) {
1184
            vect3.append(vect3.at(i - 1));
1185
            vect3.prepend(vect3.at(i));
1186
            vect3.insert(i, vect3.at(i - 1));
1187
            vect3.insert(i, vect3.at(i));
1188
            vect3.insert(i, vect3.at(i + 1));
1189
            vect3.replace(i, vect3.at(i - 1));
1190
            vect3.replace(i, vect3.at(i));
1191
            vect3.replace(i, vect3.at(i + 1));
1192
        }
1193
        QCOMPARE(vect3.size(), 496);
1194
        for (i = 0; i < vect3.size(); ++i) {
1195
            QCOMPARE(vect3.at(i), 50.0);
1196
        }
1197
1198
        QVector<QTime> vect4;
1199
        vect4.append(QTime(12, 34, 56));
1200
1201
        for (i = 1; i < 100; ++i) {
1202
            vect4.append(vect4.at(i - 1));
1203
            vect4.prepend(vect4.at(i));
1204
            vect4.insert(i, vect4.at(i - 1));
1205
            vect4.insert(i, vect4.at(i));
1206
            vect4.insert(i, vect4.at(i + 1));
1207
            vect4.replace(i, vect4.at(i - 1));
1208
            vect4.replace(i, vect4.at(i));
1209
            vect4.replace(i, vect4.at(i + 1));
1210
        }
1211
        QCOMPARE(vect4.size(), 496);
1212
        for (i = 0; i < vect4.size(); ++i) {
1213
            QVERIFY(vect4.at(i) == QTime(12, 34, 56));
1214
        }
1215
    }
1216
1217
    // this used to trigger an uninitialized read in valgrind
1218
    QVector<char> foo;
1219
    foo.resize(144);
1220
1221
    {
1222
        QVector<int> a;
1223
        QCOMPARE(a.startsWith(1), false);
1224
        QCOMPARE(a.endsWith(1), false);
1225
        a.append(1);
1226
        QCOMPARE(a.startsWith(1), true);
1227
        QCOMPARE(a.startsWith(2), false);
1228
        QCOMPARE(a.endsWith(1), true);
1229
        QCOMPARE(a.endsWith(2), false);
1230
        a.append(2);
1231
        QCOMPARE(a.startsWith(1), true);
1232
        QCOMPARE(a.startsWith(2), false);
1233
        QCOMPARE(a.endsWith(1), false);
1234
        QCOMPARE(a.endsWith(2), true);
1235
    }
1236
}
1237
1238
void tst_Collections::byteArray()
1239
{
1240
    QByteArray hello = "hello";
1241
    QByteArray ello = "ello";
1242
    QByteArray World = "World";
1243
    QByteArray Wor = "Wor";
1244
    QByteArray helloWorld = "helloWorld";
1245
    QVERIFY(hello + World == helloWorld);
1246
    QVERIFY(hello + "World" == helloWorld);
1247
    QVERIFY("hello" + World == helloWorld);
1248
1249
1250
    QByteArray l;
1251
    QVERIFY('h' + ello == hello);
1252
    QVERIFY(Wor + 'l' + 'd' == "World");
1253
    QVERIFY(hello + World == "helloWorld");
1254
    QVERIFY(hello + "World" == "helloWorld");
1255
    QVERIFY("hello" + World == "helloWorld");
1256
    QVERIFY('h' + ello == "hello");
1257
    QVERIFY(Wor + 'l' + 'd' == "World");
1258
    QVERIFY("helloWorld" == hello + World);
1259
    QVERIFY("helloWorld" == hello + "World");
1260
    QVERIFY("helloWorld" == "hello" + World);
1261
    QVERIFY("hello" == 'h' + ello);
1262
    QVERIFY("World" == Wor + 'l' + 'd');
1263
1264
    QVERIFY(hello.contains('e'));
1265
    QVERIFY (true == hello.contains('e'));
1266
    QVERIFY (hello.contains('e') != false);
1267
1268
    QVERIFY(hello.indexOf('e') == 1);
1269
    QVERIFY(hello.indexOf('e', -10) == 1);
1270
    QVERIFY(hello.indexOf('l') == 2);
1271
    QVERIFY(hello.indexOf('l',2) == 2);
1272
    QVERIFY(hello.indexOf('l',3) == 3);
1273
1274
    QByteArray large = "000 100 200 300 400 500 600 700 800 900";
1275
1276
    QVERIFY(large.indexOf("700") == 28);
1277
    QVERIFY(large.indexOf("700", 28) == 28);
1278
    QVERIFY(large.indexOf("700", 29) == -1);
1279
    QVERIFY(large.lastIndexOf("700") == 28);
1280
    QVERIFY(large.lastIndexOf("700", 28) == 28);
1281
    QVERIFY(large.lastIndexOf("700", 27) == -1);
1282
1283
    QVERIFY(large.contains("200"));
1284
    QVERIFY(!large.contains("201"));
1285
    QVERIFY(large.contains('3'));
1286
    QVERIFY(!large.contains('a'));
1287
1288
    QVERIFY(large.count("00") == 11);
1289
    QVERIFY(large.count('3') == 1);
1290
    QVERIFY(large.count('0') == 21);
1291
    QVERIFY(large.count("0") == 21);
1292
    QVERIFY(large.count("200") == 1);
1293
    QVERIFY(large.count("201") == 0);
1294
1295
    QVERIFY(hello.left(0) == "");
1296
    QVERIFY(!hello.left(0).isNull());
1297
    QVERIFY(hello.left(1) == "h");
1298
    QVERIFY(hello.left(2) == "he");
1299
    QVERIFY(hello.left(200) == "hello");
1300
    QVERIFY(hello.left(hello.size()) == hello);
1301
    QVERIFY(hello.left(hello.size()+1) == hello);
1302
1303
    QVERIFY(hello.right(0) == "");
1304
    QVERIFY(!hello.right(0).isNull());
1305
    QVERIFY(hello.right(1) == "o");
1306
    QVERIFY(hello.right(2) == "lo");
1307
    QVERIFY(hello.right(200) == "hello");
1308
    QVERIFY(hello.right(hello.size()) == hello);
1309
    QVERIFY(hello.right(hello.size()+1) == hello);
1310
1311
    QVERIFY(!hello.mid(0, 0).isNull());
1312
    QVERIFY(hello.mid(0, 1) == "h");
1313
    QVERIFY(hello.mid(0, 2) == "he");
1314
    QVERIFY(hello.mid(0, 200) == "hello");
1315
    QVERIFY(hello.mid(0) == "hello");
1316
    QVERIFY(hello.mid(0, hello.size()) == hello);
1317
    QVERIFY(hello.mid(0, hello.size()+1) == hello);
1318
1319
    QVERIFY(hello.mid(hello.size()-0) == "");
1320
1321
    QVERIFY(hello.mid(hello.size()-0).isNull()); // weird but valid 3.x semantics
1322
    QVERIFY(hello.mid(hello.size()-1) == "o");
1323
    QVERIFY(hello.mid(hello.size()-2) == "lo");
1324
    QVERIFY(hello.mid(hello.size()-200) == "hello");
1325
1326
    QByteArray null;
1327
    QByteArray nonNull = "";
1328
    QVERIFY(null.left(10).isNull());
1329
    QVERIFY(null.mid(0).isNull());
1330
1331
#if 0
1332
    QVERIFY(null == QByteArray::null);
1333
    QVERIFY(QByteArray::null  == null);
1334
    QVERIFY(nonNull != QByteArray::null);
1335
    QVERIFY(QByteArray::null != nonNull);
1336
    QVERIFY(null == nonNull);
1337
    QVERIFY(QByteArray::null == QByteArray::null);
1338
#endif
1339
1340
    QByteArray str = "Hello";
1341
    QByteArray cstr(str.data(), str.size());
1342
    QVERIFY(str == "Hello");
1343
    QVERIFY(cstr == "Hello");
1344
    cstr.clear();
1345
    QVERIFY(str == "Hello");
1346
    QVERIFY(cstr.isEmpty());
1347
1348
    {
1349
        QByteArray ba1("Foo");
1350
        ba1.prepend(ba1);
1351
        QCOMPARE(ba1, QByteArray("FooFoo"));
1352
        ba1.append(ba1);
1353
        QCOMPARE(ba1, QByteArray("FooFooFooFoo"));
1354
        ba1.insert(2, ba1);
1355
        QCOMPARE(ba1, QByteArray("FoFooFooFooFoooFooFooFoo"));
1356
        ba1.replace(3, 3, ba1);
1357
        QCOMPARE(ba1, QByteArray("FoFFoFooFooFooFoooFooFooFooooFooFoooFooFooFoo"));
1358
        ba1 = "FooFoo";
1359
        ba1.replace(char('F'), ba1);
1360
        QCOMPARE(ba1, QByteArray("FooFooooFooFoooo"));
1361
        ba1 = "FooFoo";
1362
        ba1.replace(char('o'), ba1);
1363
        QCOMPARE(ba1, QByteArray("FFooFooFooFooFFooFooFooFoo"));
1364
1365
        ba1.replace(ba1, "xxx");
1366
        QCOMPARE(ba1, QByteArray("xxx"));
1367
        ba1.replace(ba1, QByteArray("yyy"));
1368
        QCOMPARE(ba1, QByteArray("yyy"));
1369
        ba1 += ba1;
1370
        QCOMPARE(ba1, QByteArray("yyyyyy"));
1371
1372
	ba1.remove(1, -1); // do nothing
1373
	QCOMPARE(ba1, QByteArray("yyyyyy"));
1374
1375
	ba1.replace(0, -1, "ZZZ");
1376
	QCOMPARE(ba1, QByteArray("ZZZyyyyyy"));
1377
    }
1378
};
1379
1380
void tst_Collections::stack()
1381
{
1382
    QStack<int> stack;
1383
    stack.push(1);
1384
    stack.push(2);
1385
    stack.push(3);
1386
    QVectorIterator<int> i = stack;
1387
    i.toBack();
1388
    int sum = 0;
1389
    while (i.hasPrevious())
1390
	sum += i.previous();
1391
    QVERIFY(sum == 6);
1392
1393
    sum = 0;
1394
    for (QStack<int>::iterator i = stack.begin(); i != stack.end(); ++i)
1395
	sum += *i;
1396
    QVERIFY(sum == 6);
1397
1398
    while (!stack.isEmpty())
1399
	sum -= stack.pop();
1400
    QVERIFY(sum == 0);
1401
}
1402
1403
void tst_Collections::hash()
1404
{
1405
    const char *hello = "hello";
1406
    const char *world = "world";
1407
    const char *allo = "allo";
1408
    const char *monde = "monde";
1409
1410
    {
1411
	typedef QHash<QString, QString> Hash;
1412
	Hash hash;
1413
	QString key;
1414
	for (int i = 0; i < 10; ++i) {
1415
	    key[0] = i + '0';
1416
	    for (int j = 0; j < 10; ++j) {
1417
		key[1] = j + '0';
1418
		hash.insert(key, "V" + key);
1419
	    }
1420
	}
1421
1422
	for (int i = 0; i < 10; ++i) {
1423
	    key[0] = i + '0';
1424
	    for (int j = 0; j < 10; ++j) {
1425
		key[1] = j + '0';
1426
		hash.remove(key);
1427
	    }
1428
	}
1429
    }
1430
1431
    {
1432
	typedef QHash<int, const char *> Hash;
1433
	Hash hash;
1434
	hash.insert(1, hello);
1435
	hash.insert(2, world);
1436
1437
	QVERIFY(hash.size() == 2);
1438
	QVERIFY(!hash.isEmpty());
1439
1440
	{
1441
	    Hash hash2 = hash;
1442
	    hash2 = hash;
1443
	    hash = hash2;
1444
	    hash2 = hash2;
1445
	    hash = hash;
1446
	    hash2.clear();
1447
	    hash2 = hash2;
1448
	    QVERIFY(hash2.size() == 0);
1449
	    QVERIFY(hash2.isEmpty());
1450
	}
1451
	QVERIFY(hash.size() == 2);
1452
1453
	{
1454
	    Hash hash2 = hash;
1455
	    hash2[1] = allo;
1456
	    hash2[2] = monde;
1457
1458
	    QVERIFY(hash2[1] == allo);
1459
	    QVERIFY(hash2[2] == monde);
1460
	    QVERIFY(hash[1] == hello);
1461
	    QVERIFY(hash[2] == world);
1462
1463
	    hash2[1] = hash[1];
1464
	    hash2[2] = hash[2];
1465
1466
	    QVERIFY(hash2[1] == hello);
1467
	    QVERIFY(hash2[2] == world);
1468
1469
	    hash[1] = hash[1];
1470
	    QVERIFY(hash[1] == hello);
1471
	}
1472
1473
	{
1474
	    Hash hash2 = hash;
1475
	    hash2.detach();
1476
	    hash2.remove(1);
1477
	    QVERIFY(hash2.size() == 1);
1478
	    hash2.remove(1);
1479
	    QVERIFY(hash2.size() == 1);
1480
	    hash2.remove(0);
1481
	    QVERIFY(hash2.size() == 1);
1482
	    hash2.remove(2);
1483
	    QVERIFY(hash2.size() == 0);
1484
	    QVERIFY(hash.size() == 2);
1485
	}
1486
1487
	hash.detach();
1488
1489
	{
1490
	    Hash::iterator it1 = hash.find(1);
1491
	    QVERIFY(it1 != hash.end());
1492
1493
	    Hash::iterator it2 = hash.find(0);
1494
	    QVERIFY(it2 != hash.begin());
1495
	    QVERIFY(it2 == hash.end());
1496
1497
	    *it1 = monde;
1498
	    QVERIFY(*it1 == monde);
1499
	    QVERIFY(hash[1] == monde);
1500
1501
	    *it1 = hello;
1502
	    QVERIFY(*it1 == hello);
1503
	    QVERIFY(hash[1] == hello);
1504
1505
	    hash[1] = monde;
1506
	    QVERIFY(it1.key() == 1);
1507
	    QVERIFY(it1.value() == monde);
1508
	    QVERIFY(*it1 == monde);
1509
	    QVERIFY(hash[1] == monde);
1510
1511
	    hash[1] = hello;
1512
	    QVERIFY(*it1 == hello);
1513
	    QVERIFY(hash[1] == hello);
1514
	}
1515
1516
	{
1517
	    const Hash hash2 = hash;
1518
1519
	    Hash::const_iterator it1 = hash2.find(1);
1520
	    QVERIFY(it1 != hash2.end());
1521
	    QVERIFY(it1.key() == 1);
1522
	    QVERIFY(it1.value() == hello);
1523
	    QVERIFY(*it1 == hello);
1524
1525
	    Hash::const_iterator it2 = hash2.find(2);
1526
	    QVERIFY(it1 != it2);
1527
	    QVERIFY(it1 != hash2.end());
1528
	    QVERIFY(it2 != hash2.end());
1529
1530
	    int count = 0;
1531
	    it1 = hash2.begin();
1532
	    while (it1 != hash2.end()) {
1533
		count++;
1534
		++it1;
1535
	    }
1536
	    QVERIFY(count == 2);
1537
1538
	    count = 0;
1539
	    it1 = hash.begin();
1540
	    while (it1 != hash.end()) {
1541
		count++;
1542
		++it1;
1543
	    }
1544
	    QVERIFY(count == 2);
1545
	}
1546
1547
	{
1548
	    QVERIFY(hash.contains(1));
1549
	    QVERIFY(hash.contains(2));
1550
	    QVERIFY(!hash.contains(0));
1551
	    QVERIFY(!hash.contains(3));
1552
	}
1553
1554
	{
1555
	    QVERIFY(hash.value(1) == hello);
1556
	    QVERIFY(hash.value(2) == world);
1557
	    QVERIFY(hash.value(3) == 0);
1558
	    QVERIFY(hash.value(1, allo) == hello);
1559
	    QVERIFY(hash.value(2, allo) == world);
1560
	    QVERIFY(hash.value(3, allo) == allo);
1561
	    QVERIFY(hash.value(0, monde) == monde);
1562
	}
1563
1564
	{
1565
	    QHash<int,LargeStatic> hash;
1566
	    for (int i = 0; i < 10; i++)
1567
		hash.insert(i, LargeStatic());
1568
	    QVERIFY(LargeStatic::count == 10);
1569
	    hash.remove(7);
1570
	    QVERIFY(LargeStatic::count == 9);
1571
1572
	}
1573
	QVERIFY(LargeStatic::count == 0);
1574
	{
1575
	    QHash<int, int*> hash;
1576
	    QVERIFY(((const QHash<int,int*>*) &hash)->operator[](7) == 0);
1577
	}
1578
1579
	{
1580
	    /*
1581
                This test relies on a certain implementation of
1582
                QHash. If you change the way QHash works internally,
1583
                change this test as well.
1584
            */
1585
	    QHash<int, int> hash;
1586
            for (int i = 0; i < 1000; ++i)
1587
		hash.insert(i, i);
1588
	    QVERIFY(hash.capacity() == 1031);
1589
            hash.squeeze();
1590
            QVERIFY(hash.capacity() == 521);
1591
1592
	    hash.insert(12345, 12345);
1593
            QVERIFY(hash.capacity() == 1031);
1594
1595
	    for (int j = 0; j < 900; ++j)
1596
		hash.remove(j);
1597
            QVERIFY(hash.capacity() == 257);
1598
	    hash.squeeze();
1599
            QVERIFY(hash.capacity() == 67);
1600
            hash.reserve(0);
1601
        }
1602
    }
1603
1604
    {
1605
        QHash<int, QString> hash;
1606
        hash.insert(0, "Hello");
1607
1608
        QHash<int, QString>::iterator it = hash.begin();
1609
        QVERIFY((*it)[0] == QChar('H'));
1610
        QVERIFY(it->constData()[0] == QChar('H'));
1611
        it->replace(QChar('H'), QChar('X'));
1612
        QVERIFY(*hash.begin() == "Xello");
1613
1614
        QHash<int, QString>::const_iterator cit = hash.constBegin();
1615
        QVERIFY((*cit).toLower() == "xello");
1616
        QVERIFY(cit->toUpper() == "XELLO");
1617
    }
1618
1619
    {
1620
        QHash<int, QString> hash1, hash2;
1621
        hash1.insertMulti(1, "Alpha");
1622
        hash1.insertMulti(1, "Gamma");
1623
        hash2.insertMulti(1, "Beta");
1624
        hash2.insertMulti(1, "Gamma");
1625
        hash2.insertMulti(1, "Gamma");
1626
1627
        hash1.unite(hash2);
1628
        QCOMPARE(hash1.size(), 5);
1629
        QCOMPARE(hash1.values(),
1630
                (QList<QString>() << "Gamma" << "Gamma" << "Beta" << "Gamma" << "Alpha"));
1631
1632
        hash2 = hash1;
1633
        hash2.unite(hash2);
1634
        QCOMPARE(hash2.size(), 10);
1635
        QCOMPARE(hash2.values(), hash1.values() + hash1.values());
1636
    }
1637
1638
#if 0
1639
    {
1640
        QMultiHash<QString, int> hash1;
1641
        hash1.insert("1", 2);
1642
        hash1.insert("1", 1);
1643
        hash1.insert("a", 3);
1644
        hash1.insert("a", 2);
1645
        hash1.insert("a", 1);
1646
        hash1.insert("b", 2);
1647
        hash1.insert("b", 1);
1648
1649
        // hash1: [ "1" -> 1, "1" -> 2, "a" -> 1, "a" -> 2, "a" -> 3, "b" -> 1, "b" -> 2 ]
1650
1651
        QHashIterator<QString, int> i1(hash1);
1652
        i1.toBack();
1653
1654
        bool found;
1655
1656
        found = i1.findPreviousKey("1");
1657
        QVERIFY(found && i1.value() == 2);
1658
1659
        found = i1.findPreviousKey("1");
1660
        QVERIFY(found && i1.value() == 1);
1661
1662
        found = i1.findPreviousKey("1");
1663
        QVERIFY(!found);
1664
1665
        i1.toFront();
1666
        found = i1.findNextKey("1");
1667
        QVERIFY(found && i1.value() == 1);
1668
1669
        found = i1.findNextKey("1");
1670
        QVERIFY(found && i1.value() == 2);
1671
1672
        found = i1.findNextKey("1");
1673
        QVERIFY(!found);
1674
1675
        i1.toBack();
1676
        found = i1.findPreviousKey("b");
1677
        QVERIFY(found && i1.value() == 2);
1678
1679
        found = i1.findPreviousKey("b");
1680
        QVERIFY(found && i1.value() == 1);
1681
1682
        found = i1.findPreviousKey("b");
1683
        QVERIFY(!found);
1684
1685
        i1.toFront();
1686
        found = i1.findNextKey("b");
1687
        QVERIFY(found && i1.value() == 1);
1688
1689
        found = i1.findNextKey("b");
1690
        QVERIFY(found && i1.value() == 2);
1691
1692
        found = i1.findNextKey("b");
1693
        QVERIFY(!found);
1694
    }
1695
#endif
1696
}
1697
1698
void tst_Collections::map()
1699
{
1700
    const char *hello = "hello";
1701
    const char *world = "world";
1702
    const char *allo = "allo";
1703
    const char *monde = "monde";
1704
1705
    {
1706
	typedef QMap<int, const char *> Map;
1707
	Map map;
1708
	map.insert(1, hello);
1709
	map.insert(2, world);
1710
1711
	QVERIFY(*map.begin() == hello);
1712
1713
	QVERIFY(map.size() == 2);
1714
	QVERIFY(!map.isEmpty());
1715
1716
	{
1717
	    Map map2 = map;
1718
	    map2 = map;
1719
	    map = map2;
1720
	    map2 = map2;
1721
	    map = map;
1722
	    map2.clear();
1723
	    map2 = map2;
1724
	    QVERIFY(map2.size() == 0);
1725
	    QVERIFY(map2.isEmpty());
1726
	}
1727
	QVERIFY(map.size() == 2);
1728
1729
	{
1730
	    Map map2 = map;
1731
	    map2[1] = allo;
1732
	    map2[2] = monde;
1733
1734
	    QVERIFY(map2[1] == allo);
1735
	    QVERIFY(map2[2] == monde);
1736
	    QVERIFY(map[1] == hello);
1737
	    QVERIFY(map[2] == world);
1738
1739
	    map2[1] = map[1];
1740
	    map2[2] = map[2];
1741
1742
	    QVERIFY(map2[1] == hello);
1743
	    QVERIFY(map2[2] == world);
1744
1745
	    map[1] = map[1];
1746
	    QVERIFY(map[1] == hello);
1747
	}
1748
1749
	{
1750
	    Map map2 = map;
1751
	    map2.detach();
1752
	    map2.remove(1);
1753
	    QVERIFY(map2.size() == 1);
1754
	    map2.remove(1);
1755
	    QVERIFY(map2.size() == 1);
1756
	    map2.remove(0);
1757
	    QVERIFY(map2.size() == 1);
1758
	    map2.remove(2);
1759
	    QVERIFY(map2.size() == 0);
1760
	    QVERIFY(map.size() == 2);
1761
	}
1762
1763
	map.detach();
1764
1765
	{
1766
	    Map::iterator it1 = map.find(1);
1767
	    QVERIFY(it1 == map.begin());
1768
	    QVERIFY(it1 != map.end());
1769
1770
	    Map::iterator it2 = map.find(0);
1771
	    QVERIFY(it2 != map.begin());
1772
	    QVERIFY(it2 == map.end());
1773
1774
	    *it1 = monde;
1775
	    QVERIFY(*it1 == monde);
1776
	    QVERIFY(map[1] == monde);
1777
1778
	    *it1 = hello;
1779
	    QVERIFY(*it1 == hello);
1780
	    QVERIFY(map[1] == hello);
1781
1782
	    map[1] = monde;
1783
	    QVERIFY(it1.key() == 1);
1784
	    QVERIFY(it1.value() == monde);
1785
	    QVERIFY(*it1 == monde);
1786
	    QVERIFY(map[1] == monde);
1787
1788
	    map[1] = hello;
1789
	    QVERIFY(*it1 == hello);
1790
	    QVERIFY(map[1] == hello);
1791
1792
	    *++it1 = allo;
1793
	    QVERIFY(*it1 == allo);
1794
	    QVERIFY(map[2] == allo);
1795
	    *it1 = world;
1796
1797
	    ++it1;
1798
	    QVERIFY(it1 == map.end());
1799
1800
	    int count = 0;
1801
	    it1 = map.begin();
1802
	    while (it1 != map.end()) {
1803
		count++;
1804
		++it1;
1805
	    }
1806
	    QVERIFY(count == 2);
1807
	}
1808
1809
	{
1810
	    const Map map2 = map;
1811
1812
	    Map::const_iterator it1 = map2.find(1);
1813
	    QVERIFY(it1 != map2.end());
1814
	    QVERIFY(it1.key() == 1);
1815
	    QVERIFY(it1.value() == hello);
1816
	    QVERIFY(*it1 == hello);
1817
	    ++it1;
1818
1819
	    Map::const_iterator it2 = map2.find(2);
1820
	    QVERIFY(it1 == it2);
1821
	    ++it1;
1822
	    QVERIFY(it1 == map2.end());
1823
	    QVERIFY(it2 != map2.end());
1824
	    QVERIFY(it1 != it2);
1825
1826
	    int count = 0;
1827
	    it1 = map2.begin();
1828
	    while (it1 != map2.end()) {
1829
		count++;
1830
		++it1;
1831
	    }
1832
	    QVERIFY(count == 2);
1833
1834
	    count = 0;
1835
	    it1 = map.begin();
1836
	    while (it1 != map.end()) {
1837
		count++;
1838
		++it1;
1839
	    }
1840
	    QVERIFY(count == 2);
1841
	}
1842
1843
	{
1844
	    QVERIFY(map.contains(1));
1845
	    QVERIFY(map.contains(2));
1846
	    QVERIFY(!map.contains(0));
1847
	    QVERIFY(!map.contains(3));
1848
	}
1849
1850
	{
1851
	    QVERIFY(map.value(1) == hello);
1852
	    QVERIFY(map.value(2) == world);
1853
	    QVERIFY(map.value(3) == 0);
1854
	    QVERIFY(map.value(1, allo) == hello);
1855
	    QVERIFY(map.value(2, allo) == world);
1856
	    QVERIFY(map.value(3, allo) == allo);
1857
	    QVERIFY(map.value(0, monde) == monde);
1858
	}
1859
	int originalLargeStaticCount = LargeStatic::count;
1860
	{
1861
	    QMap<int,LargeStatic> map;
1862
	    for (int i = 0; i < 10; i++)
1863
		map.insert(i, LargeStatic());
1864
            QVERIFY(LargeStatic::count == (originalLargeStaticCount + 10));
1865
	    map.remove(7);
1866
	    QVERIFY(LargeStatic::count == (originalLargeStaticCount + 9));
1867
1868
	}
1869
	QVERIFY(LargeStatic::count == originalLargeStaticCount);
1870
	{
1871
	    QMap<int, int*> map;
1872
	    QVERIFY(((const QMap<int,int*>*) &map)->operator[](7) == 0);
1873
	}
1874
1875
	{
1876
	    QMap<int, int> map;
1877
	    map[0] = 1;
1878
	    map[1] = 2;
1879
	    map[2] = 4;
1880
	    map[3] = 8;
1881
	    int sum = 0;
1882
	    int sumkey = 0;
1883
	    QMapIterator<int,int> i = map;
1884
	    while (i.hasNext()) {
1885
		sum += i.next().value();
1886
		sumkey += i.key();
1887
	    }
1888
	    QVERIFY(sum == 15);
1889
	    QVERIFY(sumkey == 6);
1890
	}
1891
	{
1892
	    QMap<int, int> map;
1893
	    map[0] = 1;
1894
	    map[1] = 2;
1895
	    map[2] = 4;
1896
	    map[3] = 8;
1897
	    int sum = 0;
1898
	    QMutableMapIterator<int,int> i = map;
1899
	    while(i.hasNext())
1900
		if (i.next().key()  == 2)
1901
		    i.remove();
1902
	    i.toFront();
1903
	    while(i.hasNext()) {
1904
		sum += i.next().value();
1905
                i.setValue(10);
1906
                i.value() += 22;
1907
                QVERIFY(i.value() == 32);
1908
            }
1909
	    QVERIFY(sum == 11);
1910
	}
1911
        {
1912
            QMap<int, int> map;
1913
            map[0] = 1;
1914
            QMutableMapIterator<int,int> i(map);
1915
            i.toBack();
1916
            while (i.hasPrevious()) {
1917
                i.previous();
1918
                QCOMPARE(i.key(), 0);
1919
                QCOMPARE(i.value(), 1);
1920
            }
1921
        }
1922
    }
1923
1924
    {
1925
        QMultiMap<QString, int> map1;
1926
        map1.insert("1", 2);
1927
        map1.insert("1", 1);
1928
        map1.insert("a", 3);
1929
        map1.insert("a", 2);
1930
        map1.insert("a", 1);
1931
        map1.insert("b", 2);
1932
        map1.insert("b", 1);
1933
1934
	// map1: [ "1" -> 1, "1" -> 2, "a" -> 1, "a" -> 2, "a" -> 3, "b" -> 1, "b" -> 2 ]
1935
1936
#if 0
1937
        QMapIterator<QString, int> i1(map1);
1938
        i1.toBack();
1939
1940
        bool found;
1941
        found = i1.findPreviousKey("1");
1942
	QVERIFY(found && i1.value() == 2);
1943
1944
        found = i1.findPreviousKey("1");
1945
	QVERIFY(found && i1.value() == 1);
1946
1947
        found = i1.findPreviousKey("1");
1948
        QVERIFY(!found);
1949
1950
	i1.toFront();
1951
        found = i1.findNextKey("1");
1952
        QVERIFY(found && i1.value() == 1);
1953
1954
        found = i1.findNextKey("1");
1955
        QVERIFY(found && i1.value() == 2);
1956
1957
        found = i1.findNextKey("1");
1958
        QVERIFY(!found);
1959
1960
	i1.toBack();
1961
        found = i1.findPreviousKey("b");
1962
        QVERIFY(found && i1.value() == 2);
1963
1964
        found = i1.findPreviousKey("b");
1965
        QVERIFY(found && i1.value() == 1);
1966
1967
        found = i1.findPreviousKey("b");
1968
        QVERIFY(!found);
1969
1970
	i1.toFront();
1971
        found = i1.findNextKey("b");
1972
        QVERIFY(found && i1.value() == 1);
1973
1974
        found = i1.findNextKey("b");
1975
        QVERIFY(found && i1.value() == 2);
1976
1977
        found = i1.findNextKey("b");
1978
        QVERIFY(!found);
1979
#endif
1980
1981
        QMultiMap<QString, int>::iterator j1, k1;
1982
1983
        j1 = map1.lowerBound("0"); k1 = map1.upperBound("0");
1984
        QVERIFY(j1 == map1.begin() && k1 == j1);
1985
        j1 = map1.lowerBound("00"); k1 = map1.upperBound("00");
1986
        QVERIFY(j1 == map1.find("1") && k1 == j1);
1987
        j1 = map1.lowerBound("1"); k1 = map1.upperBound("1");
1988
        QVERIFY(j1 == map1.find("1") && --(--k1) == j1);
1989
        j1 = map1.lowerBound("11"); k1 = map1.upperBound("11");
1990
        QVERIFY(j1 == map1.find("a") && k1 == j1);
1991
        j1 = map1.lowerBound("a"); k1 = map1.upperBound("a");
1992
        QVERIFY(j1 == map1.find("a") && k1 == map1.find("b"));
1993
        QVERIFY(j1.value() == 1 && j1.value() == 1);
1994
        j1 = map1.lowerBound("aa"); k1 = map1.upperBound("aa");
1995
        QVERIFY(j1 == map1.find("b") && k1 == j1);
1996
        QVERIFY(j1.value() == 1);
1997
        j1 = map1.lowerBound("b"); k1 = map1.upperBound("b");
1998
        QVERIFY(j1 == map1.find("b") && k1 == map1.end());
1999
        QVERIFY(j1.value() == 1);
2000
        j1 = map1.lowerBound("bb"); k1 = map1.upperBound("bb");
2001
        QVERIFY(j1 == map1.end() && k1 == j1);
2002
2003
        const QMultiMap<QString, int> map2 = map1;
2004
        QMultiMap<QString, int>::const_iterator j2, k2;
2005
2006
        j2 = map2.lowerBound("0"); k2 = map2.upperBound("0");
2007
        QVERIFY(j2 == map2.begin() && k2 == j2);
2008
        j2 = map2.lowerBound("00"); k2 = map2.upperBound("00");
2009
        QVERIFY(j2 == map2.find("1") && k2 == j2);
2010
        j2 = map2.lowerBound("1"); k2 = map2.upperBound("1");
2011
        QVERIFY(j2 == map2.find("1") && --(--k2) == j2);
2012
        j2 = map2.lowerBound("11"); k2 = map2.upperBound("11");
2013
        QVERIFY(j2 == map2.find("a") && k2 == j2);
2014
        j2 = map2.lowerBound("a"); k2 = map2.upperBound("a");
2015
        QVERIFY(j2 == map2.find("a") && k2 == map2.find("b"));
2016
        QVERIFY(j2.value() == 1 && j2.value() == 1);
2017
        j2 = map2.lowerBound("aa"); k2 = map2.upperBound("aa");
2018
        QVERIFY(j2 == map2.find("b") && k2 == j2);
2019
        QVERIFY(j2.value() == 1);
2020
        j2 = map2.lowerBound("b"); k2 = map2.upperBound("b");
2021
        QVERIFY(j2 == map2.find("b") && k2 == map2.end());
2022
        QVERIFY(j2.value() == 1);
2023
        j2 = map2.lowerBound("bb"); k2 = map2.upperBound("bb");
2024
        QVERIFY(j2 == map2.end() && k2 == j2);
2025
    }
2026
2027
    {
2028
        QMap<int, QString> map;
2029
        map.insert(0, "Hello");
2030
2031
        QMap<int, QString>::iterator it = map.begin();
2032
        QVERIFY((*it)[0] == QChar('H'));
2033
        QVERIFY(it->constData()[0] == QChar('H'));
2034
        it->replace(QChar('H'), QChar('X'));
2035
        QVERIFY(*map.begin() == "Xello");
2036
2037
        QMap<int, QString>::const_iterator cit = map.constBegin();
2038
        QVERIFY((*cit).toLower() == "xello");
2039
        QVERIFY(cit->toUpper() == "XELLO");
2040
    }
2041
2042
    {
2043
        QMap<int, QString> map1, map2;
2044
        map1.insertMulti(1, "Alpha");
2045
        map1.insertMulti(1, "Gamma");
2046
        map2.insertMulti(1, "Beta");
2047
        map2.insertMulti(1, "Gamma");
2048
        map2.insertMulti(1, "Gamma");
2049
2050
        map1.unite(map2);
2051
        QCOMPARE(map1.size(), 5);
2052
        QCOMPARE(static_cast<QStringList>(map1.values()),
2053
                (QStringList() << "Gamma" << "Gamma" << "Beta" << "Gamma" << "Alpha"));
2054
2055
        map2 = map1;
2056
        map2.unite(map2);
2057
        QCOMPARE(map2.size(), 10);
2058
        QCOMPARE(map2.values(), map1.values() + map1.values());
2059
    }
2060
}
2061
2062
void tst_Collections::qstring()
2063
{
2064
    QString hello = "hello";
2065
    QString ello = "ello";
2066
    QString World = "World";
2067
    QString Wor = "Wor";
2068
    QString helloWorld = "helloWorld";
2069
2070
    QString s = hello + "World";
2071
    QVERIFY(hello + World == helloWorld);
2072
    QVERIFY(hello + "World" == helloWorld);
2073
    QVERIFY("hello" + World == helloWorld);
2074
2075
2076
    QString l;
2077
    QVERIFY('h' + ello == hello);
2078
    QVERIFY(Wor + 'l' + 'd' == "World");
2079
    QVERIFY(hello + World == "helloWorld");
2080
    QVERIFY(hello + "World" == "helloWorld");
2081
    QVERIFY("hello" + World == "helloWorld");
2082
    QVERIFY('h' + ello == "hello");
2083
    QVERIFY(Wor + 'l' + 'd' == "World");
2084
    QVERIFY("helloWorld" == hello + World);
2085
    QVERIFY("helloWorld" == hello + "World");
2086
    QVERIFY("helloWorld" == "hello" + World);
2087
    QVERIFY("hello" == 'h' + ello);
2088
    QVERIFY("World" == Wor + 'l' + 'd');
2089
2090
    QVERIFY(hello.contains('e'));
2091
    QVERIFY (true == hello.contains('e'));
2092
    QVERIFY (hello.contains('e') != false);
2093
2094
    QVERIFY(hello.indexOf('e') == 1);
2095
    QVERIFY(hello.indexOf('e', -10) == 1);
2096
    QVERIFY(hello.indexOf('l') == 2);
2097
    QVERIFY(hello.indexOf('l',2) == 2);
2098
    QVERIFY(hello.indexOf('l',3) == 3);
2099
2100
    QString large = "000 100 200 300 400 500 600 700 800 900";
2101
2102
    QVERIFY(large.indexOf("700") == 28);
2103
    QVERIFY(large.indexOf("700", 28) == 28);
2104
    QVERIFY(large.indexOf("700", 29) == -1);
2105
    QVERIFY(large.lastIndexOf("700") == 28);
2106
    QVERIFY(large.lastIndexOf("700", 28) == 28);
2107
    QVERIFY(large.lastIndexOf("700", 27) == -1);
2108
2109
    QVERIFY(large.contains("200"));
2110
    QVERIFY(!large.contains("201"));
2111
    QVERIFY(large.contains('3'));
2112
    QVERIFY(!large.contains('a'));
2113
2114
    QVERIFY(large.count("00") == 11);
2115
    QVERIFY(large.count('3') == 1);
2116
    QVERIFY(large.count('0') == 21);
2117
    QVERIFY(large.count("0") == 21);
2118
    QVERIFY(large.count("200") == 1);
2119
    QVERIFY(large.count("201") == 0);
2120
2121
    QVERIFY(hello.left(0) == "");
2122
    QVERIFY(!hello.left(0).isNull());
2123
    QVERIFY(hello.left(1) == "h");
2124
    QVERIFY(hello.left(2) == "he");
2125
    QVERIFY(hello.left(200) == "hello");
2126
    QVERIFY(hello.left(hello.size()) == hello);
2127
    QVERIFY(hello.left(hello.size()+1) == hello);
2128
2129
    QVERIFY(hello.right(0) == "");
2130
    QVERIFY(!hello.right(0).isNull());
2131
    QVERIFY(hello.right(1) == "o");
2132
    QVERIFY(hello.right(2) == "lo");
2133
    QVERIFY(hello.right(200) == "hello");
2134
    QVERIFY(hello.right(hello.size()) == hello);
2135
    QVERIFY(hello.right(hello.size()+1) == hello);
2136
2137
    QVERIFY(!hello.mid(0, 0).isNull());
2138
    QVERIFY(hello.mid(0, 1) == "h");
2139
    QVERIFY(hello.mid(0, 2) == "he");
2140
    QVERIFY(hello.mid(0, 200) == "hello");
2141
    QVERIFY(hello.mid(0) == "hello");
2142
    QVERIFY(hello.mid(0, hello.size()) == hello);
2143
    QVERIFY(hello.mid(0, hello.size()+1) == hello);
2144
2145
    QVERIFY(hello.mid(hello.size()-0) == "");
2146
2147
    QVERIFY(hello.mid(hello.size()-0).isNull());
2148
    QVERIFY(hello.mid(hello.size()-1) == "o");
2149
    QVERIFY(hello.mid(hello.size()-2) == "lo");
2150
    QVERIFY(hello.mid(hello.size()-200) == "hello");
2151
2152
    QString null;
2153
    QString nonNull = "";
2154
    QVERIFY(null.left(10).isNull());
2155
    QVERIFY(null.mid(0).isNull());
2156
2157
    QVERIFY(null == QString::null);
2158
    QVERIFY(QString::null  == null);
2159
    QVERIFY(nonNull != QString::null);
2160
    QVERIFY(QString::null != nonNull);
2161
    QVERIFY(null == nonNull);
2162
    QVERIFY(QString::null == QString::null);
2163
2164
    QString fill = "123";
2165
    fill.fill('a');
2166
    QVERIFY(fill == "aaa");
2167
2168
    s.clear();
2169
    s = hello;
2170
    s.append(World);
2171
    QVERIFY(s == helloWorld);
2172
    s.clear();
2173
    s = World;
2174
    s.insert(0,hello);
2175
    QVERIFY(s == helloWorld);
2176
    s = "012345";
2177
    s.insert(3, 'E');
2178
    QVERIFY(s == "012E345");
2179
    s.insert(3, "INSID");
2180
    QVERIFY(s == "012INSIDE345");
2181
    s = "short";
2182
    s.insert(7, 'E');
2183
    QVERIFY(s == "short  E");
2184
    s = "short";
2185
    s.insert(7, "END");
2186
    QVERIFY(s == "short  END");
2187
2188
    QVERIFY(QString::fromLatin1("hello") == "hello");
2189
2190
    s = "first";
2191
    QVERIFY(s.toLatin1() == "first");
2192
    s = "second";
2193
    QVERIFY(s.toLatin1() == "second");
2194
#ifdef QT3_SUPPORT
2195
    const char* cache = s.latin1();
2196
    QVERIFY(cache == s.latin1());
2197
#endif
2198
    s.clear();
2199
#ifdef QT3_SUPPORT
2200
    QVERIFY(*s.latin1() == '\0');
2201
#endif
2202
    QVERIFY(s.isNull());
2203
    QVERIFY(s.toLatin1().size() == 0);
2204
    QVERIFY(s.toLatin1().isEmpty());
2205
    QVERIFY(s.toLatin1().isNull());
2206
2207
    s = "first-utf8";
2208
    QVERIFY(s.toUtf8() == "first-utf8");
2209
    s = "second-utf8";
2210
    QVERIFY(s.toUtf8() == "second-utf8");
2211
#ifdef QT3_SUPPORT
2212
    cache = s.utf8();
2213
    QVERIFY(cache == s.utf8());
2214
#endif
2215
    s.clear();
2216
#ifdef QT3_SUPPORT
2217
    QVERIFY(*s.utf8() == '\0');
2218
#endif
2219
    QVERIFY(s.isNull());
2220
    QVERIFY(s.toUtf8().size() == 0);
2221
    QVERIFY(s.toUtf8().isEmpty());
2222
    QVERIFY(s.toUtf8().isNull());
2223
2224
    s = "first-utf8";
2225
    QVERIFY(s.toUtf8() == "first-utf8");
2226
    s = "second-utf8";
2227
    QVERIFY(s.toUtf8() == "second-utf8");
2228
#ifdef QT3_SUPPORT
2229
    cache = s.utf8();
2230
    QVERIFY(cache == s.utf8());
2231
#endif
2232
    s.clear();
2233
#ifdef QT3_SUPPORT
2234
    QVERIFY(*s.utf8() == '\0');
2235
#endif
2236
    QVERIFY(s.isNull());
2237
    QVERIFY(s.toUtf8().size() == 0);
2238
    QVERIFY(s.toUtf8().isEmpty());
2239
    QVERIFY(s.toUtf8().isNull());
2240
2241
    s = "first-local8Bit";
2242
    QVERIFY(s.toLocal8Bit() == "first-local8Bit");
2243
    s = "second-local8Bit";
2244
    QVERIFY(s.toLocal8Bit() == "second-local8Bit");
2245
#ifdef QT3_SUPPORT
2246
    cache = s.local8Bit();
2247
    QVERIFY(cache == s.local8Bit());
2248
#endif
2249
    s.clear();
2250
#ifdef QT3_SUPPORT
2251
    QVERIFY(*s.local8Bit() == '\0');
2252
#endif
2253
    QVERIFY(s.isNull());
2254
    QVERIFY(s.toLocal8Bit().size() == 0);
2255
    QVERIFY(s.toLocal8Bit().isEmpty());
2256
2257
    s = "first-ascii";
2258
    QVERIFY(s.toAscii() == "first-ascii");
2259
    s = "second-ascii";
2260
    QVERIFY(s.toAscii() == "second-ascii");
2261
#ifdef QT3_SUPPORT
2262
    cache = s.ascii();
2263
    QVERIFY(cache == s.ascii());
2264
#endif
2265
    s.clear();
2266
#ifdef QT3_SUPPORT
2267
    QVERIFY(*s.ascii() == '\0');
2268
#endif
2269
    QVERIFY(s.isNull());
2270
    QVERIFY(s.toAscii().size() == 0);
2271
    QVERIFY(s.toAscii().isEmpty());
2272
    QVERIFY(s.toAscii().isNull());
2273
2274
    s = "ascii";
2275
    s += (uchar) 0xb0;
2276
    QVERIFY(s.toUtf8() != s.toLatin1());
2277
    QString sa = s.toLatin1().constData();
2278
    QVERIFY(sa[sa.length()-1] == (ushort) 0xb0);
2279
    QVERIFY(sa.left(sa.length()-1) == "ascii");
2280
2281
    QVERIFY(s == QString::fromUtf8(s.toUtf8().constData()));
2282
2283
    s = "12";
2284
    s.append('3');
2285
    s += '4';
2286
    QVERIFY(s == "1234");
2287
2288
    s = "repend";
2289
    s.prepend('p');
2290
    QVERIFY(s == "prepend");
2291
    s.prepend("abc ");
2292
    QVERIFY(s == "abc prepend");
2293
2294
    s = "   whitespace        ";
2295
    QVERIFY(s.trimmed() == "whitespace");
2296
    s = "    lots      of  stuff       ";
2297
    QVERIFY(s.simplified() == "lots of stuff");
2298
2299
    s = "a hat, a stick, a ski";
2300
    QVERIFY(s[2] == 'h');
2301
    QVERIFY(s[1] < 'b');
2302
2303
2304
    s = "12223";
2305
    s.remove(1, 2);
2306
    QVERIFY(s == "123");
2307
2308
    s = "(%1)(%2)";
2309
    s = s.arg("foo").arg(7);
2310
    QVERIFY(s == "(foo)(7)");
2311
2312
2313
#if 0
2314
    s = "stl rocks";
2315
    std::string stl_string = s;
2316
    s = stl_string;
2317
    QVERIFY(s == "stl rocks");
2318
#endif
2319
2320
    {
2321
	QString str("Bananas");
2322
	QVERIFY(str.startsWith("Ban"));
2323
	QVERIFY(false == str.startsWith("Car"));
2324
    }
2325
    {
2326
	QString str("Bananas");
2327
	QVERIFY(str.endsWith("anas"));
2328
	QVERIFY(false == str.endsWith("pple"));
2329
    }
2330
2331
2332
    QString str = "Hello";
2333
    QString cstr = QString::fromRawData(str.unicode(), str.length());
2334
    QVERIFY(str == "Hello");
2335
    QVERIFY(cstr == "Hello");
2336
    cstr.clear();
2337
    QVERIFY(str == "Hello");
2338
    QVERIFY(cstr.isEmpty());
2339
2340
    {
2341
        QString str1("Foo");
2342
        str1.prepend(str1);
2343
        QCOMPARE(str1, QString("FooFoo"));
2344
        str1.append(str1);
2345
        QCOMPARE(str1, QString("FooFooFooFoo"));
2346
        str1.insert(2, str1);
2347
        QCOMPARE(str1, QString("FoFooFooFooFoooFooFooFoo"));
2348
        str1.replace(3, 3, str1);
2349
        QCOMPARE(str1, QString("FoFFoFooFooFooFoooFooFooFooooFooFoooFooFooFoo"));
2350
        str1 = "FooFoo";
2351
        str1.replace(char('F'), str1);
2352
        QCOMPARE(str1, QString("FooFooooFooFoooo"));
2353
        str1 = "FooFoo";
2354
        str1.replace(char('o'), str1);
2355
        QCOMPARE(str1, QString("FFooFooFooFooFFooFooFooFoo"));
2356
2357
        str1 = "Foo";
2358
        str1.replace("Foo", str1);
2359
        QCOMPARE(str1, QString("Foo"));
2360
        str1.replace(str1, str1);
2361
        QCOMPARE(str1, QString("Foo"));
2362
2363
        str1 = "Foo";
2364
        str1.replace("Foo", str1, Qt::CaseInsensitive);
2365
        QCOMPARE(str1, QString("Foo"));
2366
        str1.replace(str1, str1);
2367
        QCOMPARE(str1, QString("Foo"));
2368
2369
        str1 = "FooFoo";
2370
        str1.reserve(100);
2371
        str1.replace("oo", str1);
2372
        QCOMPARE(str1, QString("FFooFooFFooFoo"));
2373
2374
        str1 = "Bar";
2375
        str1.replace("FooFoo", str1);
2376
        QCOMPARE(str1, QString("Bar"));
2377
2378
        str1.replace(str1, "xxx");
2379
        QCOMPARE(str1, QString("xxx"));
2380
        str1.replace(str1, QString("yyy"));
2381
        QCOMPARE(str1, QString("yyy"));
2382
        str1 += str1;
2383
        QCOMPARE(str1, QString("yyyyyy"));
2384
    }
2385
}
2386
2387
2388
void tst_Collections::bitArray()
2389
{
2390
    QBitArray ba(20);
2391
    QVERIFY(ba.testBit(17) == false);
2392
    ba.setBit(17);
2393
    QVERIFY(ba.size() == 20);
2394
    QVERIFY(ba.testBit(17)==true);
2395
    QVERIFY(!ba.testBit(16));
2396
    ba[4] = true;
2397
    QVERIFY(ba.testBit(4));
2398
    QVERIFY(ba[4]);
2399
    int sum = 0;
2400
    for(int i = 0; i < 20; i++)
2401
	sum += ba.testBit(i) ? 1 : 0;
2402
    QVERIFY(sum == 2);
2403
2404
    ba = QBitArray(7, true);
2405
    QVERIFY(ba.size() == 7);
2406
    QVERIFY(ba[5]);
2407
2408
    ba = QBitArray(3);
2409
    ba[0] = ba[2] = true;
2410
2411
    QBitArray nba(3);
2412
    nba[1] = true;
2413
2414
    QVERIFY(~ba == nba);
2415
2416
};
2417
2418
struct CacheFoo
2419
{
2420
    CacheFoo(int v):val(v) { counter++; }
2421
    ~CacheFoo() { counter--; }
2422
    int val;
2423
    static int counter;
2424
    bool isDetached() const { return val != 2; }
2425
};
2426
2427
int CacheFoo::counter = 0;
2428
2429
void tst_Collections::cache()
2430
{
2431
    {
2432
	CacheFoo* cf;
2433
	QCache<int, CacheFoo> cache(120);
2434
	int i;
2435
	for (i = 0; i < 30; i++) {
2436
	    cf = cache.object(10);
2437
	    cache.insert(i, new CacheFoo(i), i);
2438
	}
2439
2440
	QVERIFY(cache.contains(10));
2441
	QVERIFY(!cache.contains(1));
2442
	QVERIFY(!cache.contains(2));
2443
	delete cache.take(10);
2444
    }
2445
#if 0
2446
    {
2447
	QCache<int, QString> cache(120);
2448
	int i;
2449
	QString two;
2450
	for (i = 0; i < 30; i++) {
2451
	    QString s = QString::number(i);
2452
	    cache.insert(i, new QString(s), i);
2453
	    if (i == 2)
2454
		two = s;
2455
	}
2456
	QVERIFY(!cache.contains(3));
2457
	QVERIFY(cache.contains(2));
2458
    }
2459
#endif
2460
    {
2461
	QCache<int, int> cache(100);
2462
	cache.insert(2, new int(2));
2463
	*cache[2] = 3;
2464
	QVERIFY(*cache.object(2) == 3);
2465
    }
2466
2467
    QVERIFY(CacheFoo::counter == 0);
2468
2469
}
2470
2471
void tst_Collections::regexp()
2472
{
2473
    QRegExp rx("^\\d\\d?$");
2474
    QVERIFY(rx.indexIn("123") == -1);
2475
    QVERIFY(rx.indexIn("-6") == -1);
2476
    QVERIFY(rx.indexIn("6") == 0) ;
2477
}
2478
2479
void tst_Collections::pair()
2480
{
2481
    QPair<double, int> p;
2482
    QVERIFY(p.first == 0.0);
2483
    QVERIFY(p.second == 0);
2484
2485
    QPair<int, QString> a(1, "Zebra"), b(2, "Ying"), c(3, "Yang"), d(3, "Ying"), e(5, "Alabama");
2486
    QVERIFY(a.first == 1);
2487
    QVERIFY(a.second == "Zebra");
2488
    QVERIFY(a == qMakePair(1, QString("Zebra")));
2489
2490
    QVERIFY(a == a && b == b && c == c && d == d && e == e);
2491
    QVERIFY(a != b && a != c && a != d && a != e && b != c && b != d && b != e && c != d && c != e
2492
           && d != e);
2493
2494
    QVERIFY(a < b && b < c && c < d && d < e);
2495
    QVERIFY(a <= b && b <= c && c <= d && d <= e);
2496
2497
    QVERIFY(e > d && d > c && c > b && b > a);
2498
    QVERIFY(e >= d && d >= c && c >= b && b >= a);
2499
2500
    QVERIFY(!(a > b || b > c || c > d || d > e));
2501
    QVERIFY(!(a >= b || b >= c || c >= d || d >= e));
2502
2503
    QVERIFY(!(e < d || d < c || c < b || b < a));
2504
    QVERIFY(!(e <= d || d <= c || c <= b || b <= a));
2505
2506
    QVERIFY(a <= a && b <= b && c <= c && d <= d && e <= e);
2507
    QVERIFY(!(a < a || b < b || c < c || d < d || e < e));
2508
2509
    QVERIFY(a >= a && b >= b && c >= c && d >= d && e >= e);
2510
    QVERIFY(!(a > a || b > b || c > c || d > d || e > e));
2511
}
2512
2513
void tst_Collections::cleanupHandler()
2514
{
2515
#ifdef QT3_SUPPORT
2516
    LargeStatic * f1 = 0;
2517
    LargeStatic * f2 = 0;
2518
    {
2519
	Q3CleanupHandler<LargeStatic> cleanup;
2520
	f1 = new LargeStatic;
2521
	f2 = new LargeStatic;
2522
	cleanup.add(&f1);
2523
	cleanup.add(&f2);
2524
    }
2525
    QVERIFY(f1 == 0 && f2 == 0);
2526
#else
2527
    QSKIP("No Qt3 support", SkipAll);
2528
#endif
2529
}
2530
2531
/*
2532
    These test that Java-style mutable iterators don't trash shared
2533
    copy (the setSharable() mechanism).
2534
*/
2535
2536
template <class Container>
2537
void populate(Container &);
2538
2539
template <>
2540
void populate(QList<int> &container)
2541
{
2542
    container << 1 << 2 << 4 << 8;
2543
}
2544
2545
template <>
2546
void populate(QLinkedList<int> &container)
2547
{
2548
    container << 1 << 2 << 4 << 8;
2549
}
2550
2551
template <>
2552
void populate(QVector<int> &container)
2553
{
2554
    container << 1 << 2 << 4 << 8;
2555
}
2556
2557
template <>
2558
void populate(QMap<int, int> &container)
2559
{
2560
    container.insert(1, 1);
2561
    container.insert(2, 2);
2562
    container.insert(4, 4);
2563
    container.insert(8, 8);
2564
}
2565
2566
template <>
2567
void populate(QHash<int, int> &container)
2568
{
2569
    container.insert(1, 1);
2570
    container.insert(2, 2);
2571
    container.insert(4, 4);
2572
    container.insert(8, 8);
2573
}
2574
2575
template <class Container>
2576
bool isSharable(const Container &container)
2577
{
2578
    Container copy = container;
2579
    return !container.isDetached();
2580
}
2581
2582
template <class Container, class ContainerMutableIterator>
2583
void testContainer()
2584
{
2585
    /*
2586
        Verify that shared_null's 'sharable' flag is set to true.
2587
    */
2588
    {
2589
        Container c1;
2590
        QVERIFY(!c1.isDetached());
2591
2592
        Container c2 = c1;
2593
        QVERIFY(!c1.isDetached());
2594
        QVERIFY(!c2.isDetached());
2595
    }
2596
2597
    /*
2598
        Verify that the 'sharable' flag is true while no mutable
2599
        iterator is active.
2600
    */
2601
    {
2602
        Container c1;
2603
        populate(c1);
2604
        QVERIFY(c1.size() == 4);
2605
        QVERIFY(c1.isDetached());
2606
2607
        Container c2 = c1;
2608
        QVERIFY(c1.size() == 4);
2609
        QVERIFY(c2.size() == 4);
2610
        QVERIFY(!c1.isDetached());
2611
        QVERIFY(!c2.isDetached());
2612
    }
2613
2614
    /*
2615
        Verify that the 'sharable' flag is set to false by the
2616
        mutable iterator.
2617
    */
2618
    {
2619
        Container c1;
2620
        populate(c1);
2621
        QVERIFY(c1.size() == 4);
2622
        QVERIFY(c1.isDetached());
2623
2624
        ContainerMutableIterator i(c1);
2625
        i.next();
2626
2627
        Container c2 = c1;
2628
        QVERIFY(c1.size() == 4);
2629
        QVERIFY(c2.size() == 4);
2630
        QVERIFY(c1.isDetached());
2631
        QVERIFY(c2.isDetached());
2632
2633
        i.remove();
2634
        QVERIFY(c1.size() == 3);
2635
        QVERIFY(c2.size() == 4);
2636
    }
2637
2638
    /*
2639
        Verify that the 'sharable' flag is reset to true by the
2640
        mutable iterator's destructor.
2641
    */
2642
    {
2643
        Container c1;
2644
        populate(c1);
2645
        QVERIFY(c1.size() == 4);
2646
        QVERIFY(c1.isDetached());
2647
2648
        {
2649
            ContainerMutableIterator i(c1);
2650
            i.next();
2651
        }
2652
2653
        Container c2 = c1;
2654
        QVERIFY(c1.size() == 4);
2655
        QVERIFY(c2.size() == 4);
2656
        QVERIFY(!c1.isDetached());
2657
        QVERIFY(!c2.isDetached());
2658
    }
2659
2660
    /*
2661
        Verify that the 'sharable' flag only affects the original
2662
        object, not the copies.
2663
    */
2664
    {
2665
        Container c1;
2666
        populate(c1);
2667
        QVERIFY(c1.size() == 4);
2668
        QVERIFY(c1.isDetached());
2669
2670
        Container c2 = c1;
2671
        QVERIFY(isSharable(c2));
2672
2673
        ContainerMutableIterator i(c1);
2674
        QVERIFY(!isSharable(c1));
2675
        QVERIFY(isSharable(c2));
2676
2677
        Container c3 = c1;
2678
        QVERIFY(!isSharable(c1));
2679
        QVERIFY(isSharable(c2));
2680
        QVERIFY(isSharable(c3));
2681
        QVERIFY(c1.isDetached());
2682
        QVERIFY(c2.isDetached());
2683
        QVERIFY(c3.isDetached());
2684
2685
        Container c4;
2686
        c4 = c1;
2687
        QVERIFY(!isSharable(c1));
2688
        QVERIFY(isSharable(c2));
2689
        QVERIFY(isSharable(c4));
2690
        QVERIFY(c1.isDetached());
2691
        QVERIFY(c2.isDetached());
2692
        QVERIFY(c4.isDetached());
2693
2694
        c3 = c2;
2695
        QVERIFY(!isSharable(c1));
2696
        QVERIFY(isSharable(c2));
2697
        QVERIFY(isSharable(c3));
2698
        QVERIFY(c1.isDetached());
2699
        QVERIFY(!c2.isDetached());
2700
        QVERIFY(!c3.isDetached());
2701
    }
2702
}
2703
2704
#define TEST_SEQUENTIAL_CONTAINER(Container) \
2705
    testContainer<Q##Container<int>, QMutable##Container##Iterator<int> >()
2706
2707
#define TEST_ASSOCIATIVE_CONTAINER(Container) \
2708
    testContainer<Q##Container<int, int>, QMutable##Container##Iterator<int, int> >()
2709
2710
void tst_Collections::sharableQList()
2711
{
2712
    TEST_SEQUENTIAL_CONTAINER(List);
2713
}
2714
2715
void tst_Collections::sharableQLinkedList()
2716
{
2717
    TEST_SEQUENTIAL_CONTAINER(LinkedList);
2718
}
2719
2720
void tst_Collections::sharableQVector()
2721
{
2722
    TEST_SEQUENTIAL_CONTAINER(Vector);
2723
}
2724
2725
void tst_Collections::sharableQMap()
2726
{
2727
    TEST_ASSOCIATIVE_CONTAINER(Map);
2728
}
2729
2730
void tst_Collections::sharableQHash()
2731
{
2732
    TEST_ASSOCIATIVE_CONTAINER(Hash);
2733
}
2734
2735
static int getList_calls = 0;
2736
QList<int> getList()
2737
{
2738
    ++getList_calls;
2739
    QList<int> list;
2740
    list << 1 << 2 << 3 << 4 << 5 << 6;
2741
    return list;
2742
}
2743
2744
2745
void tst_Collections::q_foreach()
2746
{
2747
    QList<int> list;
2748
    list << -2 << -1 << 0 << 1 << 2;
2749
2750
    int sum = 0;
2751
    int j = 0;
2752
    foreach(int i, list) {
2753
        QCOMPARE(i, list.at(j));
2754
        sum += i;
2755
        ++j;
2756
    }
2757
    QCOMPARE(sum, 0);
2758
2759
    // again, but without scope
2760
    foreach(int i, list)
2761
        sum += i;
2762
    QCOMPARE(sum, 0);
2763
2764
    foreach(int i, list) {
2765
        sum += i;
2766
        if (i == 0)
2767
            break;
2768
    }
2769
    QCOMPARE(sum, -3);
2770
2771
    sum = 0;
2772
    foreach(int i, list) {
2773
        if (i < 0)
2774
            continue;
2775
        sum += i;
2776
    }
2777
    QCOMPARE(sum, 3);
2778
2779
    sum = 0;
2780
    getList_calls = 0;
2781
    foreach(int i, getList())
2782
        sum += i;
2783
    QCOMPARE(sum, 21);
2784
    QCOMPARE(getList_calls, 1);
2785
}
2786
2787
2788
void tst_Collections::conversions()
2789
{
2790
#define STUFF "A" << "C" << "B" << "A"
2791
2792
    {
2793
        QList<QString> list1;
2794
        list1 << STUFF;
2795
2796
        QVector<QString> vect1 = list1.toVector();
2797
        QCOMPARE(list1.size(), 4);
2798
        QVERIFY(vect1 == (QVector<QString>() << STUFF));
2799
2800
        QList<QString> list2 = vect1.toList();
2801
        QCOMPARE(list2.size(), 4);
2802
        QVERIFY(list2 == (QList<QString>() << STUFF));
2803
2804
        QSet<QString> set1 = list1.toSet();
2805
        QCOMPARE(set1.size(), 3);
2806
        QVERIFY(set1.contains("A"));
2807
        QVERIFY(set1.contains("B"));
2808
        QVERIFY(set1.contains("C"));
2809
        QVERIFY(!set1.contains("D"));
2810
2811
        QList<QString> list3 = set1.toList();
2812
        QCOMPARE(list3.size(), 3);
2813
        QVERIFY(list3.contains("A"));
2814
        QVERIFY(list3.contains("B"));
2815
        QVERIFY(list3.contains("C"));
2816
        QVERIFY(!list3.contains("D"));
2817
2818
        QVERIFY(QList<int>().toVector().isEmpty());
2819
        QVERIFY(QList<int>().toSet().isEmpty());
2820
        QVERIFY(QVector<int>().toList().isEmpty());
2821
        QVERIFY(QSet<int>().toList().isEmpty());
2822
    }
2823
2824
    {
2825
        QList<QString> list1;
2826
        list1 << STUFF;
2827
2828
        QVector<QString> vect1 = QVector<QString>::fromList(list1);
2829
        QCOMPARE(list1.size(), 4);
2830
        QVERIFY(vect1 == (QVector<QString>() << STUFF));
2831
2832
        QList<QString> list2 = QList<QString>::fromVector(vect1);
2833
        QCOMPARE(list2.size(), 4);
2834
        QVERIFY(list2 == (QList<QString>() << STUFF));
2835
2836
        QSet<QString> set1 = QSet<QString>::fromList(list1);
2837
        QCOMPARE(set1.size(), 3);
2838
        QVERIFY(set1.contains("A"));
2839
        QVERIFY(set1.contains("B"));
2840
        QVERIFY(set1.contains("C"));
2841
        QVERIFY(!set1.contains("D"));
2842
2843
        QList<QString> list3 = QList<QString>::fromSet(set1);
2844
        QCOMPARE(list3.size(), 3);
2845
        QVERIFY(list3.contains("A"));
2846
        QVERIFY(list3.contains("B"));
2847
        QVERIFY(list3.contains("C"));
2848
        QVERIFY(!list3.contains("D"));
2849
2850
        QVERIFY(QVector<int>::fromList(QList<int>()).isEmpty());
2851
        QVERIFY(QSet<int>::fromList(QList<int>()).isEmpty());
2852
        QVERIFY(QList<int>::fromVector(QVector<int>()).isEmpty());
2853
        QVERIFY(QList<int>::fromSet(QSet<int>()).isEmpty());
2854
    }
2855
#undef STUFF
2856
}
2857
2858
void tst_Collections::javaStyleIterators()
2859
{
2860
    QStringList list;
2861
    list << "a" << "b" << "c";
2862
    QMutableStringListIterator i(list);
2863
    while (i.hasNext()) {
2864
        i.next();
2865
        i.setValue("");
2866
    }
2867
    while (i.hasPrevious()) {
2868
        i.previous();
2869
        QVERIFY(i.value().isEmpty());
2870
        i.value() = "x";
2871
        QCOMPARE(i.value(), QString("x"));
2872
    }
2873
}
2874
2875
template <class Container>
2876
void testLinkedListLikeStlIterators()
2877
{
2878
    Container fake;
2879
    typename Container::value_type t;
2880
    fake << t;
2881
2882
    typename Container::iterator i1 = fake.begin(), i2 = i1 + 1;
2883
    typename Container::const_iterator c1 = i1, c2 = c1 + 1;
2884
2885
    QVERIFY(i1 == i1);
2886
    QVERIFY(i1 == c1);
2887
    QVERIFY(c1 == i1);
2888
    QVERIFY(c1 == c1);
2889
    QVERIFY(i2 == i2);
2890
    QVERIFY(i2 == c2);
2891
    QVERIFY(c2 == i2);
2892
    QVERIFY(c2 == c2);
2893
2894
    QVERIFY(i1 != i2);
2895
    QVERIFY(i1 != c2);
2896
    QVERIFY(c1 != i2);
2897
    QVERIFY(c1 != c2);
2898
    QVERIFY(i2 != i1);
2899
    QVERIFY(i2 != c1);
2900
    QVERIFY(c2 != i1);
2901
    QVERIFY(c2 != c1);
2902
}
2903
2904
template <class Container>
2905
void testListLikeStlIterators()
2906
{
2907
    testLinkedListLikeStlIterators<Container>();
2908
2909
    Container fake;
2910
    typename Container::value_type t;
2911
    fake << t;
2912
2913
    typename Container::iterator i1 = fake.begin(), i2 = i1 + 1;
2914
    typename Container::const_iterator c1 = i1, c2 = c1 + 1;
2915
2916
    QVERIFY(i1 < i2);
2917
    QVERIFY(i1 < c2);
2918
    QVERIFY(c1 < i2);
2919
    QVERIFY(c1 < c2);
2920
    QVERIFY(!(i2 < i1));
2921
    QVERIFY(!(i2 < c1));
2922
    QVERIFY(!(c2 < i1));
2923
    QVERIFY(!(c2 < c1));
2924
    QVERIFY(!(i1 < i1));
2925
    QVERIFY(!(i1 < c1));
2926
    QVERIFY(!(c1 < i1));
2927
    QVERIFY(!(c1 < c1));
2928
    QVERIFY(!(i2 < i2));
2929
    QVERIFY(!(i2 < c2));
2930
    QVERIFY(!(c2 < i2));
2931
    QVERIFY(!(c2 < c2));
2932
2933
    QVERIFY(i2 > i1);
2934
    QVERIFY(i2 > c1);
2935
    QVERIFY(c2 > i1);
2936
    QVERIFY(c2 > c1);
2937
    QVERIFY(!(i1 > i2));
2938
    QVERIFY(!(i1 > c2));
2939
    QVERIFY(!(c1 > i2));
2940
    QVERIFY(!(c1 > c2));
2941
    QVERIFY(!(i1 > i1));
2942
    QVERIFY(!(i1 > c1));
2943
    QVERIFY(!(c1 > i1));
2944
    QVERIFY(!(c1 > c1));
2945
    QVERIFY(!(i2 > i2));
2946
    QVERIFY(!(i2 > c2));
2947
    QVERIFY(!(c2 > i2));
2948
    QVERIFY(!(c2 > c2));
2949
2950
    QVERIFY(!(i1 >= i2));
2951
    QVERIFY(!(i1 >= c2));
2952
    QVERIFY(!(c1 >= i2));
2953
    QVERIFY(!(c1 >= c2));
2954
    QVERIFY(i2 >= i1);
2955
    QVERIFY(i2 >= c1);
2956
    QVERIFY(c2 >= i1);
2957
    QVERIFY(c2 >= c1);
2958
    QVERIFY(i1 >= i1);
2959
    QVERIFY(i1 >= c1);
2960
    QVERIFY(c1 >= i1);
2961
    QVERIFY(c1 >= c1);
2962
    QVERIFY(i2 >= i2);
2963
    QVERIFY(i2 >= c2);
2964
    QVERIFY(c2 >= i2);
2965
    QVERIFY(c2 >= c2);
2966
2967
    QVERIFY(!(i2 <= i1));
2968
    QVERIFY(!(i2 <= c1));
2969
    QVERIFY(!(c2 <= i1));
2970
    QVERIFY(!(c2 <= c1));
2971
    QVERIFY(i1 <= i2);
2972
    QVERIFY(i1 <= c2);
2973
    QVERIFY(c1 <= i2);
2974
    QVERIFY(c1 <= c2);
2975
    QVERIFY(i1 <= i1);
2976
    QVERIFY(i1 <= c1);
2977
    QVERIFY(c1 <= i1);
2978
    QVERIFY(c1 <= c1);
2979
    QVERIFY(i2 <= i2);
2980
    QVERIFY(i2 <= c2);
2981
    QVERIFY(c2 <= i2);
2982
    QVERIFY(c2 <= c2);
2983
}
2984
2985
template <class Container>
2986
void testMapLikeStlIterators()
2987
{
2988
    Container fake;
2989
    QString k;
2990
    QString t;
2991
    fake.insert(k, t);
2992
2993
    typename Container::iterator i1 = fake.begin(), i2 = i1 + 1;
2994
    typename Container::const_iterator c1 = i1, c2 = c1 + 1;
2995
2996
    QVERIFY(i1 == i1);
2997
    QVERIFY(i1 == c1);
2998
    QVERIFY(c1 == i1);
2999
    QVERIFY(c1 == c1);
3000
    QVERIFY(i2 == i2);
3001
    QVERIFY(i2 == c2);
3002
    QVERIFY(c2 == i2);
3003
    QVERIFY(c2 == c2);
3004
3005
    QVERIFY(i1 != i2);
3006
    QVERIFY(i1 != c2);
3007
    QVERIFY(c1 != i2);
3008
    QVERIFY(c1 != c2);
3009
    QVERIFY(i2 != i1);
3010
    QVERIFY(i2 != c1);
3011
    QVERIFY(c2 != i1);
3012
    QVERIFY(c2 != c1);
3013
}
3014
3015
void tst_Collections::constAndNonConstStlIterators()
3016
{
3017
    testListLikeStlIterators<QList<int> >();
3018
    testListLikeStlIterators<QStringList >();
3019
    testLinkedListLikeStlIterators<QLinkedList<int> >();
3020
    testListLikeStlIterators<QVector<int> >();
3021
    testMapLikeStlIterators<QMap<QString, QString> >();
3022
    testMapLikeStlIterators<QMultiMap<QString, QString> >();
3023
    testMapLikeStlIterators<QHash<QString, QString> >();
3024
    testMapLikeStlIterators<QMultiHash<QString, QString> >();
3025
}
3026
3027
#ifndef QT_NO_STL
3028
void tst_Collections::vector_stl_data()
3029
{
3030
    QTest::addColumn<QStringList>("elements");
3031
3032
    QTest::newRow("empty") << QStringList();
3033
    QTest::newRow("one") << (QStringList() << "Hei");
3034
    QTest::newRow("two") << (QStringList() << "Hei" << "Hopp");
3035
    QTest::newRow("three") << (QStringList() << "Hei" << "Hopp" << "Sann");
3036
}
3037
3038
void tst_Collections::vector_stl()
3039
{
3040
    QFETCH(QStringList, elements);
3041
3042
    QVector<QString> vector;
3043
    for (int i = 0; i < elements.count(); ++i)
3044
        vector << elements.at(i);
3045
3046
    std::vector<QString> stdVector = vector.toStdVector();
3047
3048
    QCOMPARE(int(stdVector.size()), elements.size());
3049
3050
    std::vector<QString>::const_iterator it = stdVector.begin();
3051
    for (uint j = 0; j < stdVector.size() && it != stdVector.end(); ++j, ++it)
3052
        QCOMPARE(*it, vector[j]);
3053
3054
    QCOMPARE(QVector<QString>::fromStdVector(stdVector), vector);
3055
}
3056
3057
void tst_Collections::linkedlist_stl_data()
3058
{
3059
    list_stl_data();
3060
}
3061
3062
void tst_Collections::linkedlist_stl()
3063
{
3064
    QFETCH(QStringList, elements);
3065
3066
    QLinkedList<QString> list;
3067
    for (int i = 0; i < elements.count(); ++i)
3068
        list << elements.at(i);
3069
3070
    std::list<QString> stdList = list.toStdList();
3071
3072
    QCOMPARE(int(stdList.size()), elements.size());
3073
3074
    std::list<QString>::const_iterator it = stdList.begin();
3075
    QLinkedList<QString>::const_iterator it2 = list.constBegin();
3076
    for (uint j = 0; j < stdList.size(); ++j, ++it, ++it2)
3077
        QCOMPARE(*it, *it2);
3078
3079
    QCOMPARE(QLinkedList<QString>::fromStdList(stdList), list);
3080
}
3081
3082
void tst_Collections::list_stl_data()
3083
{
3084
    QTest::addColumn<QStringList>("elements");
3085
3086
    QTest::newRow("empty") << QStringList();
3087
    QTest::newRow("one") << (QStringList() << "Hei");
3088
    QTest::newRow("two") << (QStringList() << "Hei" << "Hopp");
3089
    QTest::newRow("three") << (QStringList() << "Hei" << "Hopp" << "Sann");
3090
}
3091
3092
void tst_Collections::list_stl()
3093
{
3094
    QFETCH(QStringList, elements);
3095
3096
    QList<QString> list;
3097
    for (int i = 0; i < elements.count(); ++i)
3098
        list << elements.at(i);
3099
3100
    std::list<QString> stdList = list.toStdList();
3101
3102
    QCOMPARE(int(stdList.size()), elements.size());
3103
3104
    std::list<QString>::const_iterator it = stdList.begin();
3105
    for (uint j = 0; j < stdList.size() && it != stdList.end(); ++j, ++it)
3106
        QCOMPARE(*it, list[j]);
3107
3108
    QCOMPARE(QList<QString>::fromStdList(stdList), list);
3109
}
3110
#endif
3111
3112
template <typename T>
3113
T qtInit(T * = 0)
3114
{
3115
    return T();
3116
}
3117
3118
void tst_Collections::q_init()
3119
{
3120
    QCOMPARE(qtInit<int>(), 0);
3121
    QCOMPARE(qtInit<double>(), 0.0);
3122
    QCOMPARE(qtInit<QString>(), QString());
3123
    QCOMPARE(qtInit<int *>(), static_cast<int *>(0));
3124
    QCOMPARE(qtInit<double *>(), static_cast<double *>(0));
3125
    QCOMPARE(qtInit<QString *>(), static_cast<QString *>(0));
3126
    QCOMPARE(qtInit<Pod>().i1, 0);
3127
    QCOMPARE(qtInit<Pod>().i2, 0);
3128
}
3129
3130
void tst_Collections::pointersize()
3131
{
3132
    QCOMPARE(int(sizeof(void *)), QT_POINTER_SIZE);
3133
}
3134
3135
class LessThanComparable
3136
{
3137
public:
3138
    bool operator<(const LessThanComparable &) const { return true; }
3139
};
3140
3141
class EqualsComparable
3142
{
3143
public:
3144
    bool operator==(const EqualsComparable &) const { return true; }
3145
};
3146
3147
uint qHash(const EqualsComparable &)
3148
{
3149
    return 0;
3150
}
3151
3152
/*
3153
    The following functions instatiates every member functions in the
3154
    Qt containers that requires either operator== or operator<.
3155
    They are ordered in a concept inheritance tree:
3156
3157
    Container
3158
        MutableIterationContainer
3159
            Sequence (QLinkedList)
3160
                Random Access (QVector, QList, QQueue, QStack)
3161
            Pair Associative (QHash, QMap)
3162
        Associative (QSet)
3163
*/
3164
template <typename ContainerType, typename ValueType>
3165
void instantiateContainer()
3166
{
3167
    const ValueType value = ValueType();
3168
    ContainerType container;
3169
    const ContainerType constContainer(container);
3170
3171
#ifndef QT_NO_STL
3172
    typename ContainerType::const_iterator constIt;
3173
    constIt = constContainer.begin();
3174
    container.constBegin();
3175
3176
    constIt = constContainer.end();
3177
    container.constEnd();
3178
#endif
3179
    container.clear();
3180
    container.contains(value);
3181
    container.count();
3182
    container.empty();
3183
    container.isEmpty();
3184
    container.size();
3185
3186
    container != constContainer;
3187
    container == constContainer;
3188
    container = constContainer;
3189
}
3190
3191
template <typename ContainerType, typename ValueType>
3192
void instantiateMutableIterationContainer()
3193
{
3194
    instantiateContainer<ContainerType, ValueType>();
3195
    ContainerType container;
3196
3197
#ifndef QT_NO_STL
3198
    typename ContainerType::iterator it;
3199
    it = container.begin();
3200
    it = container.end();
3201
#endif
3202
3203
    // QSet lacks count(T).
3204
    const ValueType value = ValueType();
3205
    container.count(value);
3206
}
3207
3208
template <typename ContainerType, typename ValueType>
3209
void instantiateSequence()
3210
{
3211
    instantiateMutableIterationContainer<ContainerType, ValueType>();
3212
3213
// QVector lacks removeAll(T)
3214
//    ValueType value = ValueType();
3215
//    ContainerType container;
3216
//    container.removeAll(value);
3217
}
3218
3219
template <typename ContainerType, typename ValueType>
3220
void instantiateRandomAccess()
3221
{
3222
    instantiateSequence<ContainerType, ValueType>();
3223
3224
    ValueType value = ValueType();
3225
    ContainerType container;
3226
    container.indexOf(value);
3227
    container.lastIndexOf(value);
3228
}
3229
3230
template <typename ContainerType, typename ValueType>
3231
void instantiateAssociative()
3232
{
3233
    instantiateContainer<ContainerType, ValueType>();
3234
3235
    const ValueType value = ValueType();
3236
    ContainerType container;
3237
    const ContainerType constContainer(container);
3238
3239
    container.reserve(1);
3240
    container.capacity();
3241
    container.squeeze();
3242
3243
    container.remove(value);
3244
    container.values();
3245
3246
    container.unite(constContainer);
3247
    container.intersect(constContainer);
3248
    container.subtract(constContainer);
3249
3250
    container != constContainer;
3251
    container == constContainer;
3252
    container & constContainer;
3253
    container &= constContainer;
3254
    container &= value;
3255
    container + constContainer;
3256
    container += constContainer;
3257
    container += value;
3258
    container - constContainer;
3259
    container -= constContainer;
3260
    container -= value;
3261
    container | constContainer;
3262
    container |= constContainer;
3263
    container |= value;
3264
}
3265
3266
template <typename ContainerType, typename KeyType, typename ValueType>
3267
void instantiatePairAssociative()
3268
{
3269
    instantiateMutableIterationContainer<ContainerType, KeyType>();
3270
3271
    typename ContainerType::iterator it;
3272
    typename ContainerType::const_iterator constIt;
3273
    const KeyType key = KeyType();
3274
    const ValueType value = ValueType();
3275
    ContainerType container;
3276
    const ContainerType constContainer(container);
3277
3278
    it = container.insert(key, value);
3279
    container.erase(it);
3280
    container.find(key);
3281
    container.constFind(key);
3282
    constContainer.find(key);
3283
3284
    container.key(value);
3285
    container.keys();
3286
    constContainer.keys();
3287
    container.remove(key);
3288
    container.take(key);
3289
    container.unite(constContainer);
3290
    container.value(key);
3291
    container.value(key, value);
3292
    container.values();
3293
    container.values(key);
3294
    container[key];
3295
    const int foo = constContainer[key];
3296
    Q_UNUSED(foo);
3297
}
3298
3299
/*
3300
    Instantiate all Qt containers using a datatype that
3301
    defines the minimum amount of operators.
3302
*/
3303
void tst_Collections::containerInstantiation()
3304
{
3305
    // Instantiate QHash member functions.
3306
    typedef QHash<EqualsComparable, int> Hash;
3307
    instantiatePairAssociative<Hash, EqualsComparable, int>();
3308
3309
    Hash hash;
3310
    hash.reserve(1);
3311
    hash.capacity();
3312
    hash.squeeze();
3313
3314
    // Instantiate QMap member functions.
3315
    typedef QMap<LessThanComparable, int> Map;
3316
    instantiatePairAssociative<Map, LessThanComparable, int>();
3317
3318
    // Instantiate QSet member functions.
3319
    typedef QSet<EqualsComparable> Set;
3320
    instantiateAssociative<Set, EqualsComparable>();
3321
3322
    //Instantiate QLinkedList member functions.
3323
    typedef QLinkedList<EqualsComparable> LinkedList;
3324
    instantiateSequence<LinkedList, EqualsComparable> ();
3325
    {
3326
        EqualsComparable value;
3327
        LinkedList list;
3328
        list.removeAll(value);
3329
    }
3330
3331
    //Instantiate QList member functions.
3332
    typedef QList<EqualsComparable> List;
3333
    instantiateRandomAccess<List, EqualsComparable>();
3334
    {
3335
        EqualsComparable value;
3336
        List list;
3337
        list.removeAll(value);
3338
    }
3339
3340
    //Instantiate QVector member functions.
3341
    typedef QVector<EqualsComparable> Vector;
3342
    instantiateRandomAccess<Vector, EqualsComparable>();
3343
3344
    //Instantiate QQueue member functions.
3345
    typedef QQueue<EqualsComparable> Queue;
3346
    instantiateRandomAccess<Queue, EqualsComparable>();
3347
3348
    //Instantiate QStack member functions.
3349
    typedef QStack<EqualsComparable> Stack;
3350
    instantiateRandomAccess<Stack, EqualsComparable>();
3351
}
3352
3353
void tst_Collections::qtimerList()
3354
{
3355
    QList<double> foo;
3356
    const int N = 10000;
3357
3358
    foo.append(99.9);
3359
    foo.append(99.9);
3360
    foo.append(99.9);
3361
3362
    for(int i = 0; i < N; i++) {
3363
        foo.removeFirst();
3364
        foo.insert(1, 99.9);
3365
    }
3366
3367
    QList<double>::Iterator end = foo.end();
3368
    for (int i = 0; i < (N / 2) - 10; ++i) {
3369
        foo.prepend(99.9);
3370
        if (foo.end() != end)
3371
            return;
3372
    }
3373
    QFAIL("QList preallocates too much memory");
3374
}
3375
3376
template <typename Container>
3377
void testContainerTypedefs(Container container)
3378
{
3379
    Q_UNUSED(container)
3380
    { typedef typename Container::value_type Foo; }
3381
    { typedef typename Container::iterator Foo; }
3382
    { typedef typename Container::const_iterator Foo; }
3383
    { typedef typename Container::reference Foo; }
3384
    { typedef typename Container::const_reference Foo; }
3385
    { typedef typename Container::pointer Foo; }
3386
    { typedef typename Container::difference_type Foo; }
3387
    { typedef typename Container::size_type Foo; }
3388
}
3389
3390
template <typename Container>
3391
void testPairAssociativeContainerTypedefs(Container container)
3392
{
3393
    Q_UNUSED(container)
3394
3395
//  TODO: Not sure how to define value_type for our associative containers
3396
//    { typedef typename Container::value_type Foo; }
3397
//    { typedef typename Container::const_iterator Foo; }
3398
//    { typedef typename Container::reference Foo; }
3399
//    { typedef typename Container::const_reference Foo; }
3400
//    { typedef typename Container::pointer Foo; }
3401
3402
    { typedef typename Container::difference_type Foo; }
3403
    { typedef typename Container::size_type Foo; }
3404
    { typedef typename Container::iterator Foo; }
3405
    { typedef typename Container::key_type Foo; }
3406
    { typedef typename Container::mapped_type Foo; }
3407
// TODO
3408
//    { typedef typename Container::key_compare Foo; }
3409
//    { typedef typename Container::value_comare Foo; }
3410
}
3411
3412
template <typename Container>
3413
void testSetContainerTypedefs(Container container)
3414
{
3415
    Q_UNUSED(container)
3416
    { typedef typename Container::iterator Foo; }
3417
    { typedef typename Container::const_iterator Foo; }
3418
    { typedef typename Container::reference Foo; }
3419
    { typedef typename Container::const_reference Foo; }
3420
    { typedef typename Container::pointer Foo; }
3421
    { typedef typename Container::difference_type Foo; }
3422
    { typedef typename Container::size_type Foo; }
3423
    { typedef typename Container::key_type Foo; }
3424
}
3425
3426
/*
3427
    Compile-time test that verifies that the Qt containers
3428
    have STL-compatable typedefs.
3429
*/
3430
void tst_Collections::containerTypedefs()
3431
{
3432
    testContainerTypedefs(QVector<int>());
3433
    testContainerTypedefs(QStack<int>());
3434
    testContainerTypedefs(QList<int>());
3435
    testContainerTypedefs(QLinkedList<int>());
3436
    testContainerTypedefs(QQueue<int>());
3437
3438
    testPairAssociativeContainerTypedefs(QMap<int, int>());
3439
    testPairAssociativeContainerTypedefs(QMultiMap<int, int>());
3440
    testPairAssociativeContainerTypedefs(QHash<int, int>());
3441
3442
    testSetContainerTypedefs(QSet<int>());
3443
}
3444
3445
class Key1;
3446
class T1;
3447
class T2;
3448
3449
void tst_Collections::forwardDeclared()
3450
{
3451
    { typedef QHash<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
3452
    { typedef QMultiHash<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
3453
    { typedef QMap<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
3454
    { typedef QMultiMap<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
3455
#if !defined(Q_CC_RVCT)
3456
    // RVCT can't handle forward declared template parameters if those are used to declare
3457
    // class members inside templated class.
3458
    { typedef QPair<T1, T2> C; C *x = 0; Q_UNUSED(x) }
3459
#endif
3460
    { typedef QList<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
3461
    { typedef QLinkedList<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
3462
    { typedef QVector<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) Q_UNUSED(i) Q_UNUSED(j) }
3463
    { typedef QStack<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) Q_UNUSED(i) Q_UNUSED(j) }
3464
    { typedef QQueue<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
3465
    { typedef QSet<T1> C; C *x = 0; /* C::iterator i; */ C::const_iterator j; Q_UNUSED(x) }
3466
}
3467
3468
#if defined(Q_ALIGNOF) && defined(Q_DECL_ALIGN)
3469
3470
class Q_DECL_ALIGN(4) Aligned4
3471
{
3472
    char i;
3473
public:
3474
    Aligned4(int i = 0) : i(i) {}
3475
    bool checkAligned() const
3476
    {
3477
        return (quintptr(this) & 3) == 0;
3478
    }
3479
3480
    inline bool operator==(const Aligned4 &other) const { return i == other.i; }
3481
    inline bool operator<(const Aligned4 &other) const { return i < other.i; }
3482
    friend inline int qHash(const Aligned4 &a) { return qHash(a.i); }
3483
};
3484
3485
class Q_DECL_ALIGN(128) Aligned128
3486
{
3487
    char i;
3488
public:
3489
    Aligned128(int i = 0) : i(i) {}
3490
    bool checkAligned() const
3491
    {
3492
        return (quintptr(this) & 127) == 0;
3493
    }
3494
3495
    inline bool operator==(const Aligned128 &other) const { return i == other.i; }
3496
    inline bool operator<(const Aligned128 &other) const { return i < other.i; }
3497
    friend inline int qHash(const Aligned128 &a) { return qHash(a.i); }
3498
};
3499
3500
template<typename C>
3501
void testVectorAlignment()
3502
{
3503
    typedef typename C::value_type Aligned;
3504
    C container;
3505
    container.append(Aligned());
3506
    QVERIFY(container[0].checkAligned());
3507
3508
    for (int i = 0; i < 200; ++i)
3509
        container.append(Aligned());
3510
3511
    for (int i = 0; i < container.size(); ++i)
3512
        QVERIFY(container.at(i).checkAligned());
3513
}
3514
3515
template<typename C>
3516
void testContiguousCacheAlignment()
3517
{
3518
    typedef typename C::value_type Aligned;
3519
    C container(150);
3520
    container.append(Aligned());
3521
    QVERIFY(container[container.firstIndex()].checkAligned());
3522
3523
    for (int i = 0; i < 200; ++i)
3524
        container.append(Aligned());
3525
3526
    for (int i = container.firstIndex(); i < container.lastIndex(); ++i)
3527
        QVERIFY(container.at(i).checkAligned());
3528
}
3529
3530
template<typename C>
3531
void testAssociativeContainerAlignment()
3532
{
3533
    typedef typename C::key_type Key;
3534
    typedef typename C::mapped_type Value;
3535
    C container;
3536
    container.insert(Key(), Value());
3537
3538
    typename C::const_iterator it = container.constBegin();
3539
    QVERIFY(it.key().checkAligned());
3540
    QVERIFY(it.value().checkAligned());
3541
3542
    // add some more elements
3543
    for (int i = 0; i < 200; ++i)
3544
        container.insert(Key(i), Value(i));
3545
3546
    it = container.constBegin();
3547
    for ( ; it != container.constEnd(); ++it) {
3548
        QVERIFY(it.key().checkAligned());
3549
        QVERIFY(it.value().checkAligned());
3550
    }
3551
}
3552
3553
void tst_Collections::alignment()
3554
{
3555
    testVectorAlignment<QVector<Aligned4> >();
3556
    testVectorAlignment<QVector<Aligned128> >();
3557
    testContiguousCacheAlignment<QContiguousCache<Aligned4> >();
3558
    testContiguousCacheAlignment<QContiguousCache<Aligned128> >();
3559
    testAssociativeContainerAlignment<QMap<Aligned4, Aligned4> >();
3560
    testAssociativeContainerAlignment<QMap<Aligned4, Aligned128> >();
3561
    testAssociativeContainerAlignment<QMap<Aligned128, Aligned4> >();
3562
    testAssociativeContainerAlignment<QMap<Aligned128, Aligned128> >();
3563
    testAssociativeContainerAlignment<QHash<Aligned4, Aligned4> >();
3564
    testAssociativeContainerAlignment<QHash<Aligned4, Aligned128> >();
3565
    testAssociativeContainerAlignment<QHash<Aligned128, Aligned4> >();
3566
    testAssociativeContainerAlignment<QHash<Aligned128, Aligned128> >();
3567
}
3568
3569
#else
3570
void tst_Collections::alignment()
3571
{
3572
    QSKIP("Compiler doesn't support necessary extension keywords", SkipAll);
3573
}
3574
#endif
3575
3576
#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
3577
3578
template<template<class> class C>
3579
struct QTBUG13079_Node {
3580
    C<QTBUG13079_Node> children;
3581
    QString s;
3582
3583
    ~QTBUG13079_Node() {
3584
        children.begin(); //play with memory
3585
    }
3586
};
3587
template<template<class> class C> void QTBUG13079_collectionInsideCollectionImpl()
3588
{
3589
    C<QTBUG13079_Node<C> > nodeList;
3590
    nodeList << QTBUG13079_Node<C>();
3591
    nodeList.first().s = "parent";
3592
    nodeList.first().children << QTBUG13079_Node<C>();
3593
    nodeList.first().children.first().s = "child";
3594
3595
    nodeList = nodeList.first().children;
3596
    QCOMPARE(nodeList.first().s, QString::fromLatin1("child"));
3597
3598
    nodeList = nodeList.first().children;
3599
    QCOMPARE(nodeList.count(), 0);
3600
    nodeList << QTBUG13079_Node<C>();
3601
}
3602
3603
template<template<class, class> class C>
3604
struct QTBUG13079_NodeAssoc {
3605
    C<int, QTBUG13079_NodeAssoc> children;
3606
    QString s;
3607
3608
    ~QTBUG13079_NodeAssoc() {
3609
        children.begin(); //play with memory
3610
    }
3611
};
3612
template<template<class, class> class C> void QTBUG13079_collectionInsideCollectionAssocImpl()
3613
{
3614
    C<int, QTBUG13079_NodeAssoc<C> > nodeMap;
3615
    nodeMap[18] = QTBUG13079_NodeAssoc<C>();
3616
    nodeMap[18].s = "parent";
3617
    nodeMap[18].children[12] = QTBUG13079_NodeAssoc<C>();
3618
    nodeMap[18].children[12].s = "child";
3619
3620
    nodeMap = nodeMap[18].children;
3621
    QCOMPARE(nodeMap[12].s, QString::fromLatin1("child"));
3622
3623
    nodeMap = nodeMap[12].children;
3624
    QCOMPARE(nodeMap.count(), 0);
3625
    nodeMap[42] = QTBUG13079_NodeAssoc<C>();
3626
}
3627
3628
3629
quint32 qHash(const QTBUG13079_Node<QSet> &)
3630
{
3631
    return 0;
3632
}
3633
3634
bool operator==(const QTBUG13079_Node<QSet> &a, const QTBUG13079_Node<QSet> &b)
3635
{
3636
    return a.s == b.s && a.children == b.children;
3637
}
3638
3639
template<template<class> class C>
3640
struct QTBUG13079_NodePtr : QSharedData {
3641
    C<QTBUG13079_NodePtr> child;
3642
    QTBUG13079_NodePtr *next;
3643
    QString s;
3644
3645
    QTBUG13079_NodePtr() : next(0) {}
3646
    ~QTBUG13079_NodePtr() {
3647
        next = child.data(); //play with memory
3648
    }
3649
};
3650
template<template<class> class C> void QTBUG13079_collectionInsidePtrImpl()
3651
{
3652
    typedef C<QTBUG13079_NodePtr<C> > Ptr;
3653
    {
3654
        Ptr nodePtr;
3655
        nodePtr = Ptr(new QTBUG13079_NodePtr<C>());
3656
        nodePtr->s = "parent";
3657
        nodePtr->child = Ptr(new QTBUG13079_NodePtr<C>());
3658
        nodePtr->child->s = "child";
3659
        nodePtr = nodePtr->child;
3660
        QCOMPARE(nodePtr->s, QString::fromLatin1("child"));
3661
        nodePtr = nodePtr->child;
3662
        QVERIFY(!nodePtr);
3663
    }
3664
    {
3665
        Ptr nodePtr;
3666
        nodePtr = Ptr(new QTBUG13079_NodePtr<C>());
3667
        nodePtr->s = "parent";
3668
        nodePtr->next = new QTBUG13079_NodePtr<C>();
3669
        nodePtr->next->s = "next";
3670
        nodePtr = Ptr(nodePtr->next);
3671
        QCOMPARE(nodePtr->s, QString::fromLatin1("next"));
3672
        nodePtr = Ptr(nodePtr->next);
3673
        QVERIFY(!nodePtr);
3674
    }
3675
}
3676
3677
#endif
3678
3679
void tst_Collections::QTBUG13079_collectionInsideCollection()
3680
{
3681
#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
3682
    QTBUG13079_collectionInsideCollectionImpl<QVector>();
3683
    QTBUG13079_collectionInsideCollectionImpl<QStack>();
3684
    QTBUG13079_collectionInsideCollectionImpl<QList>();
3685
    QTBUG13079_collectionInsideCollectionImpl<QLinkedList>();
3686
    QTBUG13079_collectionInsideCollectionImpl<QQueue>();
3687
3688
    {
3689
        QSet<QTBUG13079_Node<QSet> > nodeSet;
3690
        nodeSet << QTBUG13079_Node<QSet>();
3691
        nodeSet = nodeSet.begin()->children;
3692
        QCOMPARE(nodeSet.count(), 0);
3693
    }
3694
3695
    QTBUG13079_collectionInsideCollectionAssocImpl<QMap>();
3696
    QTBUG13079_collectionInsideCollectionAssocImpl<QHash>();
3697
3698
    QTBUG13079_collectionInsidePtrImpl<QSharedPointer>();
3699
    QTBUG13079_collectionInsidePtrImpl<QExplicitlySharedDataPointer>();
3700
    QTBUG13079_collectionInsidePtrImpl<QSharedDataPointer>();
3701
#endif
3702
}
3703
3704
template<class Container> void foreach_test_arrays(const Container &container)
3705
{
3706
    typedef typename Container::value_type T;
3707
    int i = 0;
3708
    QSet <T> set;
3709
    foreach(const T & val, container) {
3710
        QVERIFY( val == container[i] );
3711
        set << val;
3712
        i++;
3713
    }
3714
    QCOMPARE(set.count(), container.count());
3715
3716
    //modify the container while iterating.
3717
    Container c2 = container;
3718
    Container c3;
3719
    i = 0;
3720
    foreach (T val, c2) {
3721
        c3 << val;
3722
        c2.insert((i * 89) % c2.size(), T() );
3723
        QVERIFY( val == container.at(i) );
3724
        val = T();
3725
        i++;
3726
    }
3727
    QVERIFY(c3 == container);
3728
}
3729
3730
3731
void tst_Collections::foreach_2()
3732
{
3733
    QStringList strlist = QString::fromLatin1("a,b,c,d,e,f,g,h,ih,kl,mn,op,qr,st,uvw,xyz").split(",");
3734
    foreach_test_arrays(strlist);
3735
    foreach_test_arrays(QList<QString>(strlist));
3736
    foreach_test_arrays(strlist.toVector());
3737
3738
    QList<int> intlist;
3739
    intlist << 1 << 2 << 3 << 4 <<5 << 6 << 7 << 8 << 9;
3740
    foreach_test_arrays(intlist);
3741
    foreach_test_arrays(intlist.toVector());
3742
3743
    QVarLengthArray<int> varl1;
3744
    QVarLengthArray<int, 3> varl2;
3745
    QVarLengthArray<int, 10> varl3;
3746
    foreach(int i, intlist) {
3747
        varl1 << i;
3748
        varl2 << i;
3749
        varl3 << i;
3750
    }
3751
    QCOMPARE(varl1.count(), intlist.count());
3752
    QCOMPARE(varl2.count(), intlist.count());
3753
    QCOMPARE(varl3.count(), intlist.count());
3754
    foreach_test_arrays(varl1);
3755
    foreach_test_arrays(varl2);
3756
    foreach_test_arrays(varl3);
3757
3758
    QVarLengthArray<QString> varl4;
3759
    QVarLengthArray<QString, 3> varl5;
3760
    QVarLengthArray<QString, 18> varl6;
3761
    foreach(const QString &str, strlist) {
3762
        varl4 << str;
3763
        varl5 << str;
3764
        varl6 << str;
3765
    }
3766
    QCOMPARE(varl4.count(), strlist.count());
3767
    QCOMPARE(varl5.count(), strlist.count());
3768
    QCOMPARE(varl6.count(), strlist.count());
3769
    foreach_test_arrays(varl4);
3770
    foreach_test_arrays(varl5);
3771
    foreach_test_arrays(varl6);
3772
}
3773
3774
struct IntOrString
3775
{
3776
    int val;
3777
    IntOrString(int v) : val(v) { }
3778
    IntOrString(const QString &v) : val(v.toInt()) { }
3779
    operator int() { return val; }
3780
    operator QString() { return QString::number(val); }
3781
#ifndef QT_NO_STL
3782
    operator std::string() { return QString::number(val).toStdString(); }
3783
    IntOrString(const std::string &v) : val(QString::fromStdString(v).toInt()) { }
3784
#endif
3785
};
3786
3787
template<class Container> void insert_remove_loop_impl()
3788
{
3789
    typedef typename Container::value_type T;
3790
    Container t;
3791
    t.append(T(IntOrString(1)));
3792
    t << (T(IntOrString(2)));
3793
    t += (T(IntOrString(3)));
3794
    t.prepend(T(IntOrString(4)));
3795
    t.insert(2, 3 , T(IntOrString(5)));
3796
    t.insert(4, T(IntOrString(6)));
3797
    t.insert(t.begin() + 2, T(IntOrString(7)));
3798
    t.insert(t.begin() + 5, 3,  T(IntOrString(8)));
3799
    int expect1[] = { 4 , 1 , 7, 5 , 5 , 8, 8, 8, 6, 5, 2 , 3 };
3800
    QCOMPARE(size_t(t.count()), sizeof(expect1)/sizeof(int));
3801
    for (int i = 0; i < t.count(); i++) {
3802
        QCOMPARE(t[i], T(IntOrString(expect1[i])));
3803
    }
3804
3805
    Container compare_test1 = t;
3806
    t.replace(5, T(IntOrString(9)));
3807
    Container compare_test2 = t;
3808
    QVERIFY(!(compare_test1 == t));
3809
    QVERIFY( (compare_test1 != t));
3810
    QVERIFY( (compare_test2 == t));
3811
    QVERIFY(!(compare_test2 != t));
3812
    t.remove(7);
3813
    t.remove(2, 3);
3814
    int expect2[] = { 4 , 1 , 9, 8, 6, 5, 2 , 3 };
3815
    QCOMPARE(size_t(t.count()), sizeof(expect2)/sizeof(int));
3816
    for (int i = 0; i < t.count(); i++) {
3817
        QCOMPARE(t[i], T(IntOrString(expect2[i])));
3818
    }
3819
3820
    for (typename Container::iterator it = t.begin(); it != t.end(); ) {
3821
        if ( int(IntOrString(*it)) % 2 )
3822
            ++it;
3823
        else
3824
            it = t.erase(it);
3825
    }
3826
3827
    int expect3[] = { 1 , 9, 5, 3 };
3828
    QCOMPARE(size_t(t.count()), sizeof(expect3)/sizeof(int));
3829
    for (int i = 0; i < t.count(); i++) {
3830
        QCOMPARE(t[i], T(IntOrString(expect3[i])));
3831
    }
3832
3833
    t.erase(t.begin() + 1, t.end() - 1);
3834
3835
    int expect4[] = { 1 , 3 };
3836
    QCOMPARE(size_t(t.count()), sizeof(expect4)/sizeof(int));
3837
    for (int i = 0; i < t.count(); i++) {
3838
        QCOMPARE(t[i], T(IntOrString(expect4[i])));
3839
    }
3840
3841
    t << T(IntOrString(10)) << T(IntOrString(11)) << T(IntOrString(12)) << T(IntOrString(13));
3842
    t << T(IntOrString(14)) << T(IntOrString(15)) << T(IntOrString(16)) << T(IntOrString(17));
3843
    t << T(IntOrString(18)) << T(IntOrString(19)) << T(IntOrString(20)) << T(IntOrString(21));
3844
    for (typename Container::iterator it = t.begin(); it != t.end(); ++it) {
3845
        int iv = int(IntOrString(*it));
3846
        if ( iv % 2 ) {
3847
            it = t.insert(it, T(IntOrString(iv * iv)));
3848
            it = t.insert(it + 2, T(IntOrString(iv * iv + 1)));
3849
        }
3850
    }
3851
3852
    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,
3853
                      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 };
3854
    QCOMPARE(size_t(t.count()), sizeof(expect5)/sizeof(int));
3855
    for (int i = 0; i < t.count(); i++) {
3856
        QCOMPARE(t[i], T(IntOrString(expect5[i])));
3857
    }
3858
}
3859
3860
3861
//Add insert(int, int, T) so it has the same interface as QVector and QVarLengthArray for the test.
3862
template<typename T>
3863
struct ExtList : QList<T> {
3864
    using QList<T>::insert;
3865
    void insert(int before, int n, const T&x) {
3866
        while (n--) {
3867
            this->insert(before, x );
3868
        }
3869
    }
3870
    void insert(typename QList<T>::iterator before, int n, const T&x) {
3871
        while (n--) {
3872
            before = this->insert(before, x);
3873
        }
3874
    }
3875
3876
    void remove(int i) {
3877
        this->removeAt(i);
3878
    }
3879
    void remove(int i, int n) {
3880
        while (n--) {
3881
            this->removeAt(i);
3882
        }
3883
    }
3884
};
3885
3886
void tst_Collections::insert_remove_loop()
3887
{
3888
    insert_remove_loop_impl<ExtList<int> >();
3889
    insert_remove_loop_impl<ExtList<QString> >();
3890
    insert_remove_loop_impl<QVector<int> >();
3891
    insert_remove_loop_impl<QVector<QString> >();
3892
    insert_remove_loop_impl<QVarLengthArray<int> >();
3893
    insert_remove_loop_impl<QVarLengthArray<QString> >();
3894
    insert_remove_loop_impl<QVarLengthArray<int, 10> >();
3895
    insert_remove_loop_impl<QVarLengthArray<QString, 10> >();
3896
    insert_remove_loop_impl<QVarLengthArray<int, 3> >();
3897
    insert_remove_loop_impl<QVarLengthArray<QString, 3> >();
3898
    insert_remove_loop_impl<QVarLengthArray<int, 15> >();
3899
    insert_remove_loop_impl<QVarLengthArray<QString, 15> >();
3900
3901
#ifndef QT_NO_STL
3902
    insert_remove_loop_impl<ExtList<std::string> >();
3903
    insert_remove_loop_impl<QVector<std::string> >();
3904
    insert_remove_loop_impl<QVarLengthArray<std::string> >();
3905
    insert_remove_loop_impl<QVarLengthArray<std::string, 10> >();
3906
    insert_remove_loop_impl<QVarLengthArray<std::string, 3> >();
3907
    insert_remove_loop_impl<QVarLengthArray<std::string, 15> >();
3908
#endif
3909
}
3910
3911
3912
3913
QTEST_APPLESS_MAIN(tst_Collections)
3914
#include "tst_collections.moc"