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 | |
33 | static QCache<int, int> *cacheX; |
34 | static QHash<int, int> *hashX; |
35 | static QLinkedList<int> *linkedListX; |
36 | static QList<int> *listX; |
37 | static QMap<int, int> *mapX; |
38 | static QMultiHash<int, int> *multiHashX; |
39 | static QMultiMap<int, int> *multiMapX; |
40 | static QPair<int, int> *pairX; |
41 | static QQueue<int> *queueX; |
42 | static QSet<int> *setX; |
43 | static QStack<int> *stackX; |
44 | static QVarLengthArray<int> *varLengthArrayX; |
45 | static QVarLengthArray<int, 512> *varLengthArrayY; |
46 | static QVector<int> *vectorX; |
47 | |
48 | void 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 | |
87 | QT_BEGIN_NAMESPACE |
88 | template class QList<int>; |
89 | QT_END_NAMESPACE |
90 | |
91 | class tst_Collections : public QObject |
92 | { |
93 | Q_OBJECT |
94 | |
95 | private 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 | |
145 | struct 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 | |
154 | int LargeStatic::count = 0; |
155 | |
156 | struct 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 | |
164 | int Movable::count = 0; |
165 | QT_BEGIN_NAMESPACE |
166 | Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE); |
167 | QT_END_NAMESPACE |
168 | |
169 | |
170 | struct Pod { |
171 | int i1, i2; |
172 | }; |
173 | |
174 | void 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 | |
182 | void 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) |
746 | void tst_Collections::linkedList() |
747 | { |
748 | QT_WARNING_PUSH |
749 | QT_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 | } |
967 | QT_WARNING_POP |
968 | }; |
969 | #endif |
970 | |
971 | |
972 | void 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 | |
1189 | void 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 | |
1332 | void 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 | |
1355 | void 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 | |
1595 | void 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 | |
1916 | void 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 | |
2206 | void 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 | |
2236 | struct 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 | |
2245 | int CacheFoo::counter = 0; |
2246 | |
2247 | void 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) |
2287 | void 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 | |
2296 | void 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 | |
2335 | template <class Container> |
2336 | void populate(Container &); |
2337 | |
2338 | template <> |
2339 | void populate(QList<int> &container) |
2340 | { |
2341 | container << 1 << 2 << 4 << 8; |
2342 | } |
2343 | |
2344 | #if QT_DEPRECATED_SINCE(5, 15) |
2345 | QT_WARNING_PUSH |
2346 | QT_WARNING_DISABLE_DEPRECATED |
2347 | template <> |
2348 | void populate(QLinkedList<int> &container) |
2349 | { |
2350 | container << 1 << 2 << 4 << 8; |
2351 | } |
2352 | QT_WARNING_POP |
2353 | #endif |
2354 | |
2355 | template <> |
2356 | void populate(QVector<int> &container) |
2357 | { |
2358 | container << 1 << 2 << 4 << 8; |
2359 | } |
2360 | |
2361 | template <> |
2362 | void 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 | |
2370 | template <> |
2371 | void 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 | |
2379 | template <class Container> |
2380 | bool isSharable(const Container &container) |
2381 | { |
2382 | Container copy = container; |
2383 | return !container.isDetached(); |
2384 | } |
2385 | |
2386 | template <class Container> Container newInstance() { |
2387 | Container container; |
2388 | populate(container); |
2389 | if (!container.isEmpty()) |
2390 | return container; |
2391 | return Container(); |
2392 | } |
2393 | |
2394 | template <class Container, class ContainerMutableIterator> |
2395 | void 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 | |
2445 | void tst_Collections::sharableQList() |
2446 | { |
2447 | TEST_SEQUENTIAL_CONTAINER(List); |
2448 | } |
2449 | |
2450 | #if QT_DEPRECATED_SINCE(5, 15) |
2451 | QT_WARNING_PUSH |
2452 | QT_WARNING_DISABLE_DEPRECATED |
2453 | void tst_Collections::sharableQLinkedList() |
2454 | { |
2455 | TEST_SEQUENTIAL_CONTAINER(LinkedList); |
2456 | } |
2457 | QT_WARNING_POP |
2458 | #endif |
2459 | |
2460 | void tst_Collections::sharableQVector() |
2461 | { |
2462 | TEST_SEQUENTIAL_CONTAINER(Vector); |
2463 | } |
2464 | |
2465 | void tst_Collections::sharableQMap() |
2466 | { |
2467 | TEST_ASSOCIATIVE_CONTAINER(Map); |
2468 | } |
2469 | |
2470 | void tst_Collections::sharableQHash() |
2471 | { |
2472 | TEST_ASSOCIATIVE_CONTAINER(Hash); |
2473 | } |
2474 | |
2475 | static int getList_calls = 0; |
2476 | QList<int> getList() |
2477 | { |
2478 | ++getList_calls; |
2479 | QList<int> list; |
2480 | list << 1 << 2 << 3 << 4 << 5 << 6; |
2481 | return list; |
2482 | } |
2483 | |
2484 | |
2485 | void 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 | |
2528 | void 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 | |
2614 | void 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 | |
2631 | template <class Container> |
2632 | void 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 | |
2662 | template <class Container> |
2663 | void 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 | |
2743 | template <class Container> |
2744 | void 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 | |
2775 | void tst_Collections::constAndNonConstStlIterators() |
2776 | { |
2777 | testListLikeStlIterators<QList<int> >(); |
2778 | testListLikeStlIterators<QStringList >(); |
2779 | #if QT_DEPRECATED_SINCE(5, 15) |
2780 | QT_WARNING_PUSH |
2781 | QT_WARNING_DISABLE_DEPRECATED |
2782 | testLinkedListLikeStlIterators<QLinkedList<int> >(); |
2783 | QT_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 | |
2792 | void 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 | |
2802 | void 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) |
2828 | void tst_Collections::linkedlist_stl_data() |
2829 | { |
2830 | list_stl_data(); |
2831 | } |
2832 | |
2833 | void tst_Collections::linkedlist_stl() |
2834 | { |
2835 | QT_WARNING_PUSH |
2836 | QT_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); |
2853 | QT_WARNING_POP |
2854 | } |
2855 | #endif |
2856 | |
2857 | void 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 | |
2867 | void 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 | |
2893 | template <typename T> |
2894 | T qtInit(T * = 0) |
2895 | { |
2896 | return T(); |
2897 | } |
2898 | |
2899 | void 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 | |
2911 | void tst_Collections::pointersize() |
2912 | { |
2913 | QCOMPARE(int(sizeof(void *)), QT_POINTER_SIZE); |
2914 | } |
2915 | |
2916 | class LessThanComparable |
2917 | { |
2918 | public: |
2919 | bool operator<(const LessThanComparable &) const { return true; } |
2920 | }; |
2921 | |
2922 | class EqualsComparable |
2923 | { |
2924 | public: |
2925 | bool operator==(const EqualsComparable &) const { return true; } |
2926 | }; |
2927 | |
2928 | uint 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 | */ |
2945 | template <typename ContainerType, typename ValueType> |
2946 | void 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 | |
2974 | template <typename ContainerType, typename ValueType> |
2975 | void 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 | |
2990 | template <typename ContainerType, typename ValueType> |
2991 | void 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 | |
3001 | template <typename ContainerType, typename ValueType> |
3002 | void instantiateRandomAccess() |
3003 | { |
3004 | instantiateSequence<ContainerType, ValueType>(); |
3005 | |
3006 | ValueType value = ValueType(); |
3007 | ContainerType container; |
3008 | container.indexOf(value); |
3009 | container.lastIndexOf(value); |
3010 | } |
3011 | |
3012 | template <typename ContainerType, typename ValueType> |
3013 | void 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 | |
3048 | template <typename ContainerType, typename KeyType, typename ValueType> |
3049 | void 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 | */ |
3085 | void 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) |
3105 | QT_WARNING_PUSH |
3106 | QT_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 | } |
3116 | QT_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 | |
3141 | void 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 | |
3166 | template <typename Container> |
3167 | void 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 | |
3180 | template <typename Container> |
3181 | void 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 | |
3202 | template <typename Container> |
3203 | void 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 | */ |
3220 | void 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) |
3226 | QT_WARNING_PUSH |
3227 | QT_WARNING_DISABLE_DEPRECATED |
3228 | testContainerTypedefs(container: QLinkedList<int>()); |
3229 | QT_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 | |
3240 | class Key1; |
3241 | class T1; |
3242 | class T2; |
3243 | |
3244 | void 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) |
3253 | QT_WARNING_PUSH |
3254 | QT_WARNING_DISABLE_DEPRECATED |
3255 | { typedef QLinkedList<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } |
3256 | QT_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 | |
3266 | class Q_DECL_ALIGN(4) Aligned4 |
3267 | { |
3268 | char i; |
3269 | public: |
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 | }; |
3278 | Q_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 | |
3292 | class Q_DECL_ALIGN(BIGGEST_ALIGNMENT_TO_TEST) AlignedBiggest |
3293 | { |
3294 | char i; |
3295 | public: |
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 | }; |
3304 | Q_STATIC_ASSERT(Q_ALIGNOF(AlignedBiggest) % BIGGEST_ALIGNMENT_TO_TEST == 0); |
3305 | |
3306 | template<typename C> |
3307 | void 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 | |
3321 | template<typename C> |
3322 | void 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 | |
3336 | template<typename C> |
3337 | void 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 | |
3359 | void 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 |
3376 | void 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 | |
3384 | template<template<class> class C> |
3385 | struct QTBUG13079_Node { |
3386 | C<QTBUG13079_Node> children; |
3387 | QString s; |
3388 | |
3389 | ~QTBUG13079_Node() { |
3390 | children.begin(); //play with memory |
3391 | } |
3392 | }; |
3393 | template<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 | |
3409 | template<template<class, class> class C> |
3410 | struct QTBUG13079_NodeAssoc { |
3411 | C<int, QTBUG13079_NodeAssoc> children; |
3412 | QString s; |
3413 | |
3414 | ~QTBUG13079_NodeAssoc() { |
3415 | children.begin(); //play with memory |
3416 | } |
3417 | }; |
3418 | template<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 | |
3435 | quint32 qHash(const QTBUG13079_Node<QSet> &) |
3436 | { |
3437 | return 0; |
3438 | } |
3439 | |
3440 | bool operator==(const QTBUG13079_Node<QSet> &a, const QTBUG13079_Node<QSet> &b) |
3441 | { |
3442 | return a.s == b.s && a.children == b.children; |
3443 | } |
3444 | |
3445 | template<template<class> class C> |
3446 | struct 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 | }; |
3456 | template<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 | |
3485 | void 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) |
3492 | QT_WARNING_PUSH |
3493 | QT_WARNING_DISABLE_DEPRECATED |
3494 | QTBUG13079_collectionInsideCollectionImpl<QLinkedList>(); |
3495 | QT_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 | |
3515 | template<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 | |
3542 | void 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 | |
3585 | struct 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 | |
3596 | template<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. |
3671 | template<typename T> |
3672 | struct 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 | |
3695 | void 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 | |
3720 | QTEST_APPLESS_MAIN(tst_Collections) |
3721 | #include "tst_collections.moc" |
3722 | |