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