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

source code of qtbase/tests/auto/corelib/tools/collections/tst_collections.cpp