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//#define QT_STRICT_ITERATORS
30
31#include <QtTest/QtTest>
32#include <qset.h>
33#include <qdebug.h>
34
35int toNumber(const QString &str)
36{
37 int res = 0;
38 for (int i = 0; i < str.length(); ++i)
39 res = (res * 10) + str[i].digitValue();
40 return res;
41}
42
43class tst_QSet : public QObject
44{
45 Q_OBJECT
46
47private slots:
48 void operator_eq();
49 void swap();
50 void size();
51 void capacity();
52 void reserve();
53 void squeeze();
54 void detach();
55 void isDetached();
56 void clear();
57 void cpp17ctad();
58 void remove();
59 void contains();
60 void containsSet();
61 void begin();
62 void end();
63 void insert();
64 void reverseIterators();
65 void setOperations();
66 void stlIterator();
67 void stlMutableIterator();
68 void javaIterator();
69 void javaMutableIterator();
70 void makeSureTheComfortFunctionsCompile();
71 void initializerList();
72 void qhash();
73 void intersects();
74};
75
76struct IdentityTracker {
77 int value, id;
78};
79
80inline uint qHash(IdentityTracker key) { return qHash(key: key.value); }
81inline bool operator==(IdentityTracker lhs, IdentityTracker rhs) { return lhs.value == rhs.value; }
82
83void tst_QSet::operator_eq()
84{
85 {
86 QSet<int> set1, set2;
87 QVERIFY(set1 == set2);
88 QVERIFY(!(set1 != set2));
89
90 set1.insert(value: 1);
91 QVERIFY(set1 != set2);
92 QVERIFY(!(set1 == set2));
93
94 set2.insert(value: 1);
95 QVERIFY(set1 == set2);
96 QVERIFY(!(set1 != set2));
97
98 set2.insert(value: 1);
99 QVERIFY(set1 == set2);
100 QVERIFY(!(set1 != set2));
101
102 set1.insert(value: 2);
103 QVERIFY(set1 != set2);
104 QVERIFY(!(set1 == set2));
105 }
106
107 {
108 QSet<QString> set1, set2;
109 QVERIFY(set1 == set2);
110 QVERIFY(!(set1 != set2));
111
112 set1.insert(value: "one");
113 QVERIFY(set1 != set2);
114 QVERIFY(!(set1 == set2));
115
116 set2.insert(value: "one");
117 QVERIFY(set1 == set2);
118 QVERIFY(!(set1 != set2));
119
120 set2.insert(value: "one");
121 QVERIFY(set1 == set2);
122 QVERIFY(!(set1 != set2));
123
124 set1.insert(value: "two");
125 QVERIFY(set1 != set2);
126 QVERIFY(!(set1 == set2));
127 }
128
129 {
130 QSet<QString> a;
131 QSet<QString> b;
132
133 a += "otto";
134 b += "willy";
135
136 QVERIFY(a != b);
137 QVERIFY(!(a == b));
138 }
139
140 {
141 QSet<int> s1, s2;
142 s1.reserve(asize: 100);
143 s2.reserve(asize: 4);
144 QVERIFY(s1 == s2);
145 s1 << 100 << 200 << 300 << 400;
146 s2 << 400 << 300 << 200 << 100;
147 QVERIFY(s1 == s2);
148 }
149}
150
151void tst_QSet::swap()
152{
153 QSet<int> s1, s2;
154 s1.insert(value: 1);
155 s2.insert(value: 2);
156 s1.swap(other&: s2);
157 QCOMPARE(*s1.begin(),2);
158 QCOMPARE(*s2.begin(),1);
159}
160
161void tst_QSet::size()
162{
163 QSet<int> set;
164 QVERIFY(set.size() == 0);
165 QVERIFY(set.isEmpty());
166 QVERIFY(set.count() == set.size());
167 QVERIFY(set.isEmpty() == set.empty());
168
169 set.insert(value: 1);
170 QVERIFY(set.size() == 1);
171 QVERIFY(!set.isEmpty());
172 QVERIFY(set.count() == set.size());
173 QVERIFY(set.isEmpty() == set.empty());
174
175 set.insert(value: 1);
176 QVERIFY(set.size() == 1);
177 QVERIFY(!set.isEmpty());
178 QVERIFY(set.count() == set.size());
179 QVERIFY(set.isEmpty() == set.empty());
180
181 set.insert(value: 2);
182 QVERIFY(set.size() == 2);
183 QVERIFY(!set.isEmpty());
184 QVERIFY(set.count() == set.size());
185 QVERIFY(set.isEmpty() == set.empty());
186
187 set.remove(value: 1);
188 QVERIFY(set.size() == 1);
189 QVERIFY(!set.isEmpty());
190 QVERIFY(set.count() == set.size());
191 QVERIFY(set.isEmpty() == set.empty());
192
193 set.remove(value: 1);
194 QVERIFY(set.size() == 1);
195 QVERIFY(!set.isEmpty());
196 QVERIFY(set.count() == set.size());
197 QVERIFY(set.isEmpty() == set.empty());
198
199 set.remove(value: 2);
200 QVERIFY(set.size() == 0);
201 QVERIFY(set.isEmpty());
202 QVERIFY(set.count() == set.size());
203 QVERIFY(set.isEmpty() == set.empty());
204}
205
206void tst_QSet::capacity()
207{
208 QSet<int> set;
209 int n = set.capacity();
210 QVERIFY(n == 0);
211
212 for (int i = 0; i < 1000; ++i) {
213 set.insert(value: i);
214 QVERIFY(set.capacity() >= set.size());
215 }
216}
217
218void tst_QSet::reserve()
219{
220 QSet<int> set;
221 int n = set.capacity();
222 QVERIFY(n == 0);
223
224 set.reserve(asize: 1000);
225 QVERIFY(set.capacity() >= 1000);
226
227 for (int i = 0; i < 500; ++i)
228 set.insert(value: i);
229
230 QVERIFY(set.capacity() >= 1000);
231
232 for (int j = 0; j < 500; ++j)
233 set.remove(value: j);
234
235 QVERIFY(set.capacity() >= 1000);
236
237 set.clear();
238 QVERIFY(set.capacity() == 0);
239}
240
241void tst_QSet::squeeze()
242{
243 QSet<int> set;
244 int n = set.capacity();
245 QVERIFY(n == 0);
246
247 set.reserve(asize: 1000);
248 QVERIFY(set.capacity() >= 1000);
249
250 set.squeeze();
251 QVERIFY(set.capacity() < 100);
252
253 for (int i = 0; i < 500; ++i)
254 set.insert(value: i);
255 QVERIFY(set.capacity() >= 500 && set.capacity() < 10000);
256
257 set.reserve(asize: 50000);
258 QVERIFY(set.capacity() >= 50000);
259
260 set.squeeze();
261 QVERIFY(set.capacity() < 500);
262
263 set.remove(value: 499);
264 QVERIFY(set.capacity() < 500);
265
266 set.insert(value: 499);
267 QVERIFY(set.capacity() >= 500);
268
269 for (int i = 0; i < 500; ++i)
270 set.remove(value: i);
271 set.squeeze();
272 QVERIFY(set.capacity() < 100);
273}
274
275void tst_QSet::detach()
276{
277 QSet<int> set;
278 set.detach();
279
280 set.insert(value: 1);
281 set.insert(value: 2);
282 set.detach();
283
284 QSet<int> copy = set;
285 set.detach();
286}
287
288void tst_QSet::isDetached()
289{
290 QSet<int> set1, set2;
291 QVERIFY(!set1.isDetached()); // shared_null
292 QVERIFY(!set2.isDetached()); // shared_null
293
294 set1.insert(value: 1);
295 QVERIFY(set1.isDetached());
296 QVERIFY(!set2.isDetached()); // shared_null
297
298 set2 = set1;
299 QVERIFY(!set1.isDetached());
300 QVERIFY(!set2.isDetached());
301
302 set1.detach();
303 QVERIFY(set1.isDetached());
304 QVERIFY(set2.isDetached());
305}
306
307void tst_QSet::clear()
308{
309 QSet<QString> set1, set2;
310 QVERIFY(set1.size() == 0);
311
312 set1.clear();
313 QVERIFY(set1.size() == 0);
314
315 set1.insert(value: "foo");
316 QVERIFY(set1.size() != 0);
317
318 set2 = set1;
319
320 set1.clear();
321 QVERIFY(set1.size() == 0);
322 QVERIFY(set2.size() != 0);
323
324 set2.clear();
325 QVERIFY(set1.size() == 0);
326 QVERIFY(set2.size() == 0);
327}
328
329void tst_QSet::cpp17ctad()
330{
331#ifdef __cpp_deduction_guides
332#define QVERIFY_IS_SET_OF(obj, Type) \
333 QVERIFY2((std::is_same<decltype(obj), QSet<Type>>::value), \
334 QMetaType::typeName(qMetaTypeId<decltype(obj)::value_type>()))
335#define CHECK(Type, One, Two, Three) \
336 do { \
337 const Type v[] = {One, Two, Three}; \
338 QSet v1 = {One, Two, Three}; \
339 QVERIFY_IS_SET_OF(v1, Type); \
340 QSet v2(v1.begin(), v1.end()); \
341 QVERIFY_IS_SET_OF(v2, Type); \
342 QSet v3(std::begin(v), std::end(v)); \
343 QVERIFY_IS_SET_OF(v3, Type); \
344 } while (false) \
345 /*end*/
346 CHECK(int, 1, 2, 3);
347 CHECK(double, 1.0, 2.0, 3.0);
348 CHECK(QString, QStringLiteral("one"), QStringLiteral("two"), QStringLiteral("three"));
349#undef QVERIFY_IS_SET_OF
350#undef CHECK
351#else
352 QSKIP("This test requires C++17 Constructor Template Argument Deduction support enabled in the compiler.");
353#endif
354}
355
356void tst_QSet::remove()
357{
358 QSet<QString> set1;
359
360 for (int i = 0; i < 500; ++i)
361 set1.insert(value: QString::number(i));
362
363 QCOMPARE(set1.size(), 500);
364
365 for (int j = 0; j < 500; ++j) {
366 set1.remove(value: QString::number((j * 17) % 500));
367 QCOMPARE(set1.size(), 500 - j - 1);
368 }
369}
370
371void tst_QSet::contains()
372{
373 QSet<QString> set1;
374
375 for (int i = 0; i < 500; ++i) {
376 QVERIFY(!set1.contains(QString::number(i)));
377 set1.insert(value: QString::number(i));
378 QVERIFY(set1.contains(QString::number(i)));
379 }
380
381 QCOMPARE(set1.size(), 500);
382
383 for (int j = 0; j < 500; ++j) {
384 int i = (j * 17) % 500;
385 QVERIFY(set1.contains(QString::number(i)));
386 set1.remove(value: QString::number(i));
387 QVERIFY(!set1.contains(QString::number(i)));
388 }
389}
390
391void tst_QSet::containsSet()
392{
393 QSet<QString> set1;
394 QSet<QString> set2;
395
396 // empty set contains the empty set
397 QVERIFY(set1.contains(set2));
398
399 for (int i = 0; i < 500; ++i) {
400 set1.insert(value: QString::number(i));
401 set2.insert(value: QString::number(i));
402 }
403 QVERIFY(set1.contains(set2));
404
405 set2.remove(value: QString::number(19));
406 set2.remove(value: QString::number(82));
407 set2.remove(value: QString::number(7));
408 QVERIFY(set1.contains(set2));
409
410 set1.remove(value: QString::number(23));
411 QVERIFY(!set1.contains(set2));
412
413 // filled set contains the empty set as well
414 QSet<QString> set3;
415 QVERIFY(set1.contains(set3));
416
417 // the empty set doesn't contain a filled set
418 QVERIFY(!set3.contains(set1));
419
420 // verify const signature
421 const QSet<QString> set4;
422 QVERIFY(set3.contains(set4));
423}
424
425void tst_QSet::begin()
426{
427 QSet<int> set1;
428 QSet<int> set2 = set1;
429
430 {
431 QSet<int>::const_iterator i = set1.constBegin();
432 QSet<int>::const_iterator j = set1.cbegin();
433 QSet<int>::const_iterator k = set2.constBegin();
434 QSet<int>::const_iterator ell = set2.cbegin();
435
436 QVERIFY(i == j);
437 QVERIFY(k == ell);
438 QVERIFY(i == k);
439 QVERIFY(j == ell);
440 }
441
442 set1.insert(value: 44);
443
444 {
445 QSet<int>::const_iterator i = set1.constBegin();
446 QSet<int>::const_iterator j = set1.cbegin();
447 QSet<int>::const_iterator k = set2.constBegin();
448 QSet<int>::const_iterator ell = set2.cbegin();
449
450 QVERIFY(i == j);
451 QVERIFY(k == ell);
452 QVERIFY(i != k);
453 QVERIFY(j != ell);
454 }
455
456 set2 = set1;
457
458 {
459 QSet<int>::const_iterator i = set1.constBegin();
460 QSet<int>::const_iterator j = set1.cbegin();
461 QSet<int>::const_iterator k = set2.constBegin();
462 QSet<int>::const_iterator ell = set2.cbegin();
463
464 QVERIFY(i == j);
465 QVERIFY(k == ell);
466 QVERIFY(i == k);
467 QVERIFY(j == ell);
468 }
469}
470
471void tst_QSet::end()
472{
473 QSet<int> set1;
474 QSet<int> set2 = set1;
475
476 {
477 QSet<int>::const_iterator i = set1.constEnd();
478 QSet<int>::const_iterator j = set1.cend();
479 QSet<int>::const_iterator k = set2.constEnd();
480 QSet<int>::const_iterator ell = set2.cend();
481
482 QVERIFY(i == j);
483 QVERIFY(k == ell);
484 QVERIFY(i == k);
485 QVERIFY(j == ell);
486
487 QVERIFY(set1.constBegin() == set1.constEnd());
488 QVERIFY(set2.constBegin() == set2.constEnd());
489 }
490
491 set1.insert(value: 44);
492
493 {
494 QSet<int>::const_iterator i = set1.constEnd();
495 QSet<int>::const_iterator j = set1.cend();
496 QSet<int>::const_iterator k = set2.constEnd();
497 QSet<int>::const_iterator ell = set2.cend();
498
499 QVERIFY(i == j);
500 QVERIFY(k == ell);
501 QVERIFY(i != k);
502 QVERIFY(j != ell);
503
504 QVERIFY(set1.constBegin() != set1.constEnd());
505 QVERIFY(set2.constBegin() == set2.constEnd());
506 }
507
508 set2 = set1;
509
510 {
511 QSet<int>::const_iterator i = set1.constEnd();
512 QSet<int>::const_iterator j = set1.cend();
513 QSet<int>::const_iterator k = set2.constEnd();
514 QSet<int>::const_iterator ell = set2.cend();
515
516 QVERIFY(i == j);
517 QVERIFY(k == ell);
518 QVERIFY(i == k);
519 QVERIFY(j == ell);
520
521 QVERIFY(set1.constBegin() != set1.constEnd());
522 QVERIFY(set2.constBegin() != set2.constEnd());
523 }
524
525 set1.clear();
526 set2.clear();
527 QVERIFY(set1.constBegin() == set1.constEnd());
528 QVERIFY(set2.constBegin() == set2.constEnd());
529}
530
531void tst_QSet::insert()
532{
533 {
534 QSet<int> set1;
535 QVERIFY(set1.size() == 0);
536 set1.insert(value: 1);
537 QVERIFY(set1.size() == 1);
538 set1.insert(value: 2);
539 QVERIFY(set1.size() == 2);
540 set1.insert(value: 2);
541 QVERIFY(set1.size() == 2);
542 QVERIFY(set1.contains(2));
543 set1.remove(value: 2);
544 QVERIFY(set1.size() == 1);
545 QVERIFY(!set1.contains(2));
546 set1.insert(value: 2);
547 QVERIFY(set1.size() == 2);
548 QVERIFY(set1.contains(2));
549 }
550
551 {
552 QSet<int> set1;
553 QVERIFY(set1.size() == 0);
554 set1 << 1;
555 QVERIFY(set1.size() == 1);
556 set1 << 2;
557 QVERIFY(set1.size() == 2);
558 set1 << 2;
559 QVERIFY(set1.size() == 2);
560 QVERIFY(set1.contains(2));
561 set1.remove(value: 2);
562 QVERIFY(set1.size() == 1);
563 QVERIFY(!set1.contains(2));
564 set1 << 2;
565 QVERIFY(set1.size() == 2);
566 QVERIFY(set1.contains(2));
567 }
568
569 {
570 QSet<IdentityTracker> set;
571 QCOMPARE(set.size(), 0);
572 const int dummy = -1;
573 IdentityTracker id00 = {.value: 0, .id: 0}, id01 = {.value: 0, .id: 1}, searchKey = {.value: 0, .id: dummy};
574 QCOMPARE(set.insert(id00)->id, id00.id);
575 QCOMPARE(set.size(), 1);
576 QCOMPARE(set.insert(id01)->id, id00.id); // first inserted is kept
577 QCOMPARE(set.size(), 1);
578 QCOMPARE(set.find(searchKey)->id, id00.id);
579 }
580}
581
582void tst_QSet::reverseIterators()
583{
584 QSet<int> s;
585 s << 1 << 17 << 61 << 127 << 911;
586 std::vector<int> v(s.begin(), s.end());
587 std::reverse(first: v.begin(), last: v.end());
588 const QSet<int> &cs = s;
589 QVERIFY(std::equal(v.begin(), v.end(), s.rbegin()));
590 QVERIFY(std::equal(v.begin(), v.end(), s.crbegin()));
591 QVERIFY(std::equal(v.begin(), v.end(), cs.rbegin()));
592 QVERIFY(std::equal(s.rbegin(), s.rend(), v.begin()));
593 QVERIFY(std::equal(s.crbegin(), s.crend(), v.begin()));
594 QVERIFY(std::equal(cs.rbegin(), cs.rend(), v.begin()));
595}
596
597void tst_QSet::setOperations()
598{
599 QSet<QString> set1, set2;
600 set1 << "alpha" << "beta" << "gamma" << "delta" << "zeta" << "omega";
601 set2 << "beta" << "gamma" << "delta" << "epsilon" << "iota" << "omega";
602
603 QSet<QString> set3 = set1;
604 set3.unite(other: set2);
605 QVERIFY(set3.size() == 8);
606 QVERIFY(set3.contains("alpha"));
607 QVERIFY(set3.contains("beta"));
608 QVERIFY(set3.contains("gamma"));
609 QVERIFY(set3.contains("delta"));
610 QVERIFY(set3.contains("epsilon"));
611 QVERIFY(set3.contains("zeta"));
612 QVERIFY(set3.contains("iota"));
613 QVERIFY(set3.contains("omega"));
614
615 QSet<QString> set4 = set2;
616 set4.unite(other: set1);
617 QVERIFY(set4.size() == 8);
618 QVERIFY(set4.contains("alpha"));
619 QVERIFY(set4.contains("beta"));
620 QVERIFY(set4.contains("gamma"));
621 QVERIFY(set4.contains("delta"));
622 QVERIFY(set4.contains("epsilon"));
623 QVERIFY(set4.contains("zeta"));
624 QVERIFY(set4.contains("iota"));
625 QVERIFY(set4.contains("omega"));
626
627 QVERIFY(set3 == set4);
628
629 QSet<QString> set5 = set1;
630 set5.intersect(other: set2);
631 QVERIFY(set5.size() == 4);
632 QVERIFY(set5.contains("beta"));
633 QVERIFY(set5.contains("gamma"));
634 QVERIFY(set5.contains("delta"));
635 QVERIFY(set5.contains("omega"));
636
637 QSet<QString> set6 = set2;
638 set6.intersect(other: set1);
639 QVERIFY(set6.size() == 4);
640 QVERIFY(set6.contains("beta"));
641 QVERIFY(set6.contains("gamma"));
642 QVERIFY(set6.contains("delta"));
643 QVERIFY(set6.contains("omega"));
644
645 QVERIFY(set5 == set6);
646
647 QSet<QString> set7 = set1;
648 set7.subtract(other: set2);
649 QVERIFY(set7.size() == 2);
650 QVERIFY(set7.contains("alpha"));
651 QVERIFY(set7.contains("zeta"));
652
653 QSet<QString> set8 = set2;
654 set8.subtract(other: set1);
655 QVERIFY(set8.size() == 2);
656 QVERIFY(set8.contains("epsilon"));
657 QVERIFY(set8.contains("iota"));
658
659 QSet<QString> set9 = set1 | set2;
660 QVERIFY(set9 == set3);
661
662 QSet<QString> set10 = set1 & set2;
663 QVERIFY(set10 == set5);
664
665 QSet<QString> set11 = set1 + set2;
666 QVERIFY(set11 == set3);
667
668 QSet<QString> set12 = set1 - set2;
669 QVERIFY(set12 == set7);
670
671 QSet<QString> set13 = set2 - set1;
672 QVERIFY(set13 == set8);
673
674 QSet<QString> set14 = set1;
675 set14 |= set2;
676 QVERIFY(set14 == set3);
677
678 QSet<QString> set15 = set1;
679 set15 &= set2;
680 QVERIFY(set15 == set5);
681
682 QSet<QString> set16 = set1;
683 set16 += set2;
684 QVERIFY(set16 == set3);
685
686 QSet<QString> set17 = set1;
687 set17 -= set2;
688 QVERIFY(set17 == set7);
689
690 QSet<QString> set18 = set2;
691 set18 -= set1;
692 QVERIFY(set18 == set8);
693}
694
695void tst_QSet::stlIterator()
696{
697 QSet<QString> set1;
698 for (int i = 0; i < 25000; ++i)
699 set1.insert(value: QString::number(i));
700
701 {
702 int sum = 0;
703 QSet<QString>::const_iterator i = set1.begin();
704 while (i != set1.end()) {
705 sum += toNumber(str: *i);
706 ++i;
707 }
708 QVERIFY(sum == 24999 * 25000 / 2);
709 }
710
711 {
712 int sum = 0;
713 QSet<QString>::const_iterator i = set1.end();
714 while (i != set1.begin()) {
715 --i;
716 sum += toNumber(str: *i);
717 }
718 QVERIFY(sum == 24999 * 25000 / 2);
719 }
720}
721
722void tst_QSet::stlMutableIterator()
723{
724 QSet<QString> set1;
725 for (int i = 0; i < 25000; ++i)
726 set1.insert(value: QString::number(i));
727
728 {
729 int sum = 0;
730 QSet<QString>::iterator i = set1.begin();
731 while (i != set1.end()) {
732 sum += toNumber(str: *i);
733 ++i;
734 }
735 QVERIFY(sum == 24999 * 25000 / 2);
736 }
737
738 {
739 int sum = 0;
740 QSet<QString>::iterator i = set1.end();
741 while (i != set1.begin()) {
742 --i;
743 sum += toNumber(str: *i);
744 }
745 QVERIFY(sum == 24999 * 25000 / 2);
746 }
747
748 {
749 QSet<QString> set2 = set1;
750 QSet<QString> set3 = set2;
751
752 QSet<QString>::iterator i = set2.begin();
753 QSet<QString>::iterator j = set3.begin();
754
755 while (i != set2.end()) {
756 i = set2.erase(i);
757 }
758 QVERIFY(set2.isEmpty());
759 QVERIFY(!set3.isEmpty());
760
761 j = set3.end();
762 while (j != set3.begin()) {
763 j--;
764 if (j + 1 != set3.end())
765 set3.erase(i: j + 1);
766 }
767 if (set3.begin() != set3.end())
768 set3.erase(i: set3.begin());
769
770 QVERIFY(set2.isEmpty());
771 QVERIFY(set3.isEmpty());
772
773// #if QT_VERSION >= 0x050000
774// i = set2.insert("foo");
775// #else
776 QSet<QString>::const_iterator k = set2.insert(value: "foo");
777 i = reinterpret_cast<QSet<QString>::iterator &>(k);
778// #endif
779 QCOMPARE(*i, QLatin1String("foo"));
780 }
781}
782
783void tst_QSet::javaIterator()
784{
785 QSet<QString> set1;
786 for (int k = 0; k < 25000; ++k)
787 set1.insert(value: QString::number(k));
788
789 {
790 int sum = 0;
791 QSetIterator<QString> i(set1);
792 while (i.hasNext())
793 sum += toNumber(str: i.next());
794 QVERIFY(sum == 24999 * 25000 / 2);
795 }
796
797 {
798 int sum = 0;
799 QSetIterator<QString> i(set1);
800 while (i.hasNext()) {
801 sum += toNumber(str: i.peekNext());
802 i.next();
803 }
804 QVERIFY(sum == 24999 * 25000 / 2);
805 }
806
807 {
808 int sum = 0;
809 QSetIterator<QString> i(set1);
810 while (i.hasNext()) {
811 i.next();
812 sum += toNumber(str: i.peekPrevious());
813 }
814 QVERIFY(sum == 24999 * 25000 / 2);
815 }
816
817 {
818 int sum = 0;
819 QSetIterator<QString> i(set1);
820 i.toBack();
821 while (i.hasPrevious())
822 sum += toNumber(str: i.previous());
823 QVERIFY(sum == 24999 * 25000 / 2);
824 }
825
826 {
827 int sum = 0;
828 QSetIterator<QString> i(set1);
829 i.toBack();
830 while (i.hasPrevious()) {
831 sum += toNumber(str: i.peekPrevious());
832 i.previous();
833 }
834 QVERIFY(sum == 24999 * 25000 / 2);
835 }
836
837 {
838 int sum = 0;
839 QSetIterator<QString> i(set1);
840 i.toBack();
841 while (i.hasPrevious()) {
842 i.previous();
843 sum += toNumber(str: i.peekNext());
844 }
845 QVERIFY(sum == 24999 * 25000 / 2);
846 }
847
848 int sum1 = 0;
849 int sum2 = 0;
850 QSetIterator<QString> i(set1);
851 QSetIterator<QString> j(set1);
852
853 int n = 0;
854 while (i.hasNext()) {
855 QVERIFY(j.hasNext());
856 set1.remove(value: i.peekNext());
857 sum1 += toNumber(str: i.next());
858 sum2 += toNumber(str: j.next());
859 ++n;
860 }
861 QVERIFY(!j.hasNext());
862 QVERIFY(sum1 == 24999 * 25000 / 2);
863 QVERIFY(sum2 == sum1);
864 QVERIFY(set1.isEmpty());
865}
866
867void tst_QSet::javaMutableIterator()
868{
869 QSet<QString> set1;
870 for (int k = 0; k < 25000; ++k)
871 set1.insert(value: QString::number(k));
872
873 {
874 int sum = 0;
875 QMutableSetIterator<QString> i(set1);
876 while (i.hasNext())
877 sum += toNumber(str: i.next());
878 QVERIFY(sum == 24999 * 25000 / 2);
879 }
880
881 {
882 int sum = 0;
883 QMutableSetIterator<QString> i(set1);
884 while (i.hasNext()) {
885 i.next();
886 sum += toNumber(str: i.value());
887 }
888 QVERIFY(sum == 24999 * 25000 / 2);
889 }
890
891 {
892 int sum = 0;
893 QMutableSetIterator<QString> i(set1);
894 while (i.hasNext()) {
895 sum += toNumber(str: i.peekNext());
896 i.next();
897 }
898 QVERIFY(sum == 24999 * 25000 / 2);
899 }
900
901 {
902 int sum = 0;
903 QMutableSetIterator<QString> i(set1);
904 while (i.hasNext()) {
905 i.next();
906 sum += toNumber(str: i.peekPrevious());
907 }
908 QVERIFY(sum == 24999 * 25000 / 2);
909 }
910
911 {
912 int sum = 0;
913 QMutableSetIterator<QString> i(set1);
914 i.toBack();
915 while (i.hasPrevious())
916 sum += toNumber(str: i.previous());
917 QVERIFY(sum == 24999 * 25000 / 2);
918 }
919
920 {
921 int sum = 0;
922 QMutableSetIterator<QString> i(set1);
923 i.toBack();
924 while (i.hasPrevious()) {
925 sum += toNumber(str: i.peekPrevious());
926 i.previous();
927 }
928 QVERIFY(sum == 24999 * 25000 / 2);
929 }
930
931 {
932 int sum = 0;
933 QMutableSetIterator<QString> i(set1);
934 i.toBack();
935 while (i.hasPrevious()) {
936 i.previous();
937 sum += toNumber(str: i.peekNext());
938 }
939 QVERIFY(sum == 24999 * 25000 / 2);
940 }
941
942 {
943 QSet<QString> set2 = set1;
944 QSet<QString> set3 = set2;
945
946 QMutableSetIterator<QString> i(set2);
947 QMutableSetIterator<QString> j(set3);
948
949 while (i.hasNext()) {
950 i.next();
951 i.remove();
952 }
953 QVERIFY(set2.isEmpty());
954 QVERIFY(!set3.isEmpty());
955
956 j.toBack();
957 while (j.hasPrevious()) {
958 j.previous();
959 j.remove();
960 }
961 QVERIFY(set2.isEmpty());
962 QVERIFY(set3.isEmpty());
963 }
964}
965
966void tst_QSet::makeSureTheComfortFunctionsCompile()
967{
968 QSet<int> set1, set2, set3;
969 set1 << 5;
970 set1 |= set2;
971 set1 |= 5;
972 set1 &= set2;
973 set1 &= 5;
974 set1 += set2;
975 set1 += 5;
976 set1 -= set2;
977 set1 -= 5;
978 set1 = set2 | set3;
979 set1 = set2 & set3;
980 set1 = set2 + set3;
981 set1 = set2 - set3;
982}
983
984void tst_QSet::initializerList()
985{
986 QSet<int> set = {1, 1, 2, 3, 4, 5};
987 QCOMPARE(set.count(), 5);
988 QVERIFY(set.contains(1));
989 QVERIFY(set.contains(2));
990 QVERIFY(set.contains(3));
991 QVERIFY(set.contains(4));
992 QVERIFY(set.contains(5));
993
994 // check _which_ of the equal elements gets inserted (in the QHash/QMap case, it's the last):
995 const QSet<IdentityTracker> set2 = {{.value: 1, .id: 0}, {.value: 1, .id: 1}, {.value: 2, .id: 2}, {.value: 3, .id: 3}, {.value: 4, .id: 4}, {.value: 5, .id: 5}};
996 QCOMPARE(set2.count(), 5);
997 const int dummy = -1;
998 const IdentityTracker searchKey = {.value: 1, .id: dummy};
999 QCOMPARE(set2.find(searchKey)->id, 0);
1000
1001 QSet<int> emptySet{};
1002 QVERIFY(emptySet.isEmpty());
1003
1004 QSet<int> set3{{}, {}, {}};
1005 QVERIFY(!set3.isEmpty());
1006}
1007
1008void tst_QSet::qhash()
1009{
1010 //
1011 // check that sets containing the same elements hash to the same value
1012 //
1013 {
1014 // create some deterministic initial state:
1015 qSetGlobalQHashSeed(newSeed: 0);
1016
1017 QSet<int> s1;
1018 s1.reserve(asize: 4);
1019 s1 << 400 << 300 << 200 << 100;
1020
1021 // also change the seed:
1022 qSetGlobalQHashSeed(newSeed: 0x10101010);
1023
1024 QSet<int> s2;
1025 s2.reserve(asize: 100); // provoke different bucket counts
1026 s2 << 100 << 200 << 300 << 400; // and insert elements in different order, too
1027
1028 QVERIFY(s1.capacity() != s2.capacity());
1029 QCOMPARE(s1, s2);
1030 QVERIFY(!std::equal(s1.cbegin(), s1.cend(), s2.cbegin())); // verify that the order _is_ different
1031 QCOMPARE(qHash(s1), qHash(s2));
1032 }
1033
1034 //
1035 // check that sets of sets work:
1036 //
1037 {
1038 QSet<QSet<int> > intSetSet = { { 0, 1, 2 }, { 0, 1 }, { 1, 2 } };
1039 QCOMPARE(intSetSet.size(), 3);
1040 }
1041}
1042
1043void tst_QSet::intersects()
1044{
1045 QSet<int> s1;
1046 QSet<int> s2;
1047
1048 QVERIFY(!s1.intersects(s1));
1049 QVERIFY(!s1.intersects(s2));
1050
1051 s1 << 100;
1052 QVERIFY(s1.intersects(s1));
1053 QVERIFY(!s1.intersects(s2));
1054
1055 s2 << 200;
1056 QVERIFY(!s1.intersects(s2));
1057
1058 s1 << 200;
1059 QVERIFY(s1.intersects(s2));
1060
1061 qSetGlobalQHashSeed(newSeed: 0x10101010);
1062 QSet<int> s3;
1063 s3 << 500;
1064 QVERIFY(!s1.intersects(s3));
1065 s3 << 200;
1066 QVERIFY(s1.intersects(s3));
1067}
1068
1069QTEST_APPLESS_MAIN(tst_QSet)
1070
1071#include "tst_qset.moc"
1072

source code of qtbase/tests/auto/corelib/tools/qset/tst_qset.cpp