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 | #include <QtTest/QtTest> |
30 | #include <QLinkedList> |
31 | |
32 | #if QT_DEPRECATED_SINCE(5, 15) |
33 | QT_WARNING_PUSH |
34 | QT_WARNING_DISABLE_DEPRECATED |
35 | |
36 | struct Movable |
37 | { |
38 | Movable(char input = 'j') : i(input), state(Constructed) |
39 | { |
40 | ++liveCount; |
41 | } |
42 | Movable(const Movable &other) |
43 | : i(other.i) |
44 | , state(Constructed) |
45 | { |
46 | check(state1: other.state, state2: Constructed); |
47 | ++liveCount; |
48 | } |
49 | |
50 | ~Movable() |
51 | { |
52 | check(state1: state, state2: Constructed); |
53 | i = 0; |
54 | --liveCount; |
55 | state = Destructed; |
56 | } |
57 | |
58 | bool operator ==(const Movable &other) const |
59 | { |
60 | check(state1: state, state2: Constructed); |
61 | check(state1: other.state, state2: Constructed); |
62 | return i == other.i; |
63 | } |
64 | |
65 | Movable &operator=(const Movable &other) |
66 | { |
67 | check(state1: state, state2: Constructed); |
68 | check(state1: other.state, state2: Constructed); |
69 | i = other.i; |
70 | return *this; |
71 | } |
72 | char i; |
73 | |
74 | static int getLiveCount() { return liveCount; } |
75 | private: |
76 | static int liveCount; |
77 | |
78 | enum State { Constructed = 106, Destructed = 110 }; |
79 | State state; |
80 | |
81 | static void check(const State state1, const State state2) |
82 | { |
83 | QCOMPARE(int(state1), int(state2)); |
84 | } |
85 | }; |
86 | |
87 | int Movable::liveCount = 0; |
88 | |
89 | QT_BEGIN_NAMESPACE |
90 | Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE); |
91 | QT_END_NAMESPACE |
92 | |
93 | Q_DECLARE_METATYPE(Movable); |
94 | |
95 | Q_DECLARE_METATYPE(QLinkedList<int>); |
96 | |
97 | |
98 | int qHash(const Movable& movable) |
99 | { |
100 | return qHash(key: movable.i); |
101 | } |
102 | |
103 | struct Complex |
104 | { |
105 | Complex(int val = 0) |
106 | : value(val) |
107 | , checkSum(this) |
108 | { |
109 | ++liveCount; |
110 | } |
111 | |
112 | Complex(Complex const &other) |
113 | : value(other.value) |
114 | , checkSum(this) |
115 | { |
116 | ++liveCount; |
117 | } |
118 | |
119 | Complex &operator=(Complex const &other) |
120 | { |
121 | check(); other.check(); |
122 | |
123 | value = other.value; |
124 | return *this; |
125 | } |
126 | |
127 | ~Complex() |
128 | { |
129 | --liveCount; |
130 | check(); |
131 | } |
132 | |
133 | operator int() const { return value; } |
134 | |
135 | bool operator==(Complex const &other) const |
136 | { |
137 | check(); other.check(); |
138 | return value == other.value; |
139 | } |
140 | |
141 | void check() const |
142 | { |
143 | QVERIFY(this == checkSum); |
144 | } |
145 | |
146 | static int getLiveCount() { return liveCount; } |
147 | private: |
148 | static int liveCount; |
149 | |
150 | int value; |
151 | void *checkSum; |
152 | }; |
153 | |
154 | int Complex::liveCount = 0; |
155 | |
156 | Q_DECLARE_METATYPE(Complex); |
157 | |
158 | // Tests depend on the fact that: |
159 | Q_STATIC_ASSERT(!QTypeInfo<int>::isStatic); |
160 | Q_STATIC_ASSERT(!QTypeInfo<int>::isComplex); |
161 | Q_STATIC_ASSERT(!QTypeInfo<Movable>::isStatic); |
162 | Q_STATIC_ASSERT(QTypeInfo<Movable>::isComplex); |
163 | Q_STATIC_ASSERT(QTypeInfo<Complex>::isStatic); |
164 | Q_STATIC_ASSERT(QTypeInfo<Complex>::isComplex); |
165 | |
166 | class tst_QLinkedList : public QObject |
167 | { |
168 | Q_OBJECT |
169 | private slots: |
170 | void eraseValidIteratorsOnSharedList() const; |
171 | void insertWithIteratorsOnSharedList() const; |
172 | void lengthInt() const; |
173 | void lengthMovable() const; |
174 | void lengthComplex() const; |
175 | void lengthSignature() const; |
176 | void firstInt() const; |
177 | void firstMovable() const; |
178 | void firstComplex() const; |
179 | void lastInt() const; |
180 | void lastMovable() const; |
181 | void lastComplex() const; |
182 | void beginInt() const; |
183 | void beginMovable() const; |
184 | void beginComplex() const; |
185 | void endInt() const; |
186 | void endMovable() const; |
187 | void endComplex() const; |
188 | void containsInt() const; |
189 | void containsMovable() const; |
190 | void containsComplex() const; |
191 | void countInt() const; |
192 | void countMovable() const; |
193 | void countComplex() const; |
194 | void cpp17ctad() const; |
195 | void emptyInt() const; |
196 | void emptyMovable() const; |
197 | void emptyComplex() const; |
198 | void endsWithInt() const; |
199 | void endsWithMovable() const; |
200 | void endsWithComplex() const; |
201 | void removeAllInt() const; |
202 | void removeAllMovable() const; |
203 | void removeAllComplex() const; |
204 | void removeOneInt() const; |
205 | void removeOneMovable() const; |
206 | void removeOneComplex() const; |
207 | void reverseIterators() const; |
208 | void startsWithInt() const; |
209 | void startsWithMovable() const; |
210 | void startsWithComplex() const; |
211 | void takeFirstInt() const; |
212 | void takeFirstMovable() const; |
213 | void takeFirstComplex() const; |
214 | void takeLastInt() const; |
215 | void takeLastMovable() const; |
216 | void takeLastComplex() const; |
217 | void toStdListInt() const; |
218 | void toStdListMovable() const; |
219 | void toStdListComplex() const; |
220 | void testOperatorsInt() const; |
221 | void testOperatorsMovable() const; |
222 | void testOperatorsComplex() const; |
223 | void testSTLIteratorsInt() const; |
224 | void testSTLIteratorsMovable() const; |
225 | void testSTLIteratorsComplex() const; |
226 | |
227 | void initializeList() const; |
228 | |
229 | void constSharedNullInt() const; |
230 | void constSharedNullMovable() const; |
231 | void constSharedNullComplex() const; |
232 | |
233 | void setSharableInt() const; |
234 | private: |
235 | template<typename T> void length() const; |
236 | template<typename T> void first() const; |
237 | template<typename T> void last() const; |
238 | template<typename T> void begin() const; |
239 | template<typename T> void end() const; |
240 | template<typename T> void contains() const; |
241 | template<typename T> void count() const; |
242 | template<typename T> void empty() const; |
243 | template<typename T> void endsWith() const; |
244 | template<typename T> void move() const; |
245 | template<typename T> void removeAll() const; |
246 | template<typename T> void removeOne() const; |
247 | template<typename T> void startsWith() const; |
248 | template<typename T> void swap() const; |
249 | template<typename T> void takeFirst() const; |
250 | template<typename T> void takeLast() const; |
251 | template<typename T> void toStdList() const; |
252 | template<typename T> void value() const; |
253 | |
254 | template<typename T> void testOperators() const; |
255 | template<typename T> void testSTLIterators() const; |
256 | |
257 | template<typename T> void constSharedNull() const; |
258 | |
259 | int dummyForGuard; |
260 | }; |
261 | |
262 | template<typename T> struct SimpleValue |
263 | { |
264 | static T at(int index) |
265 | { |
266 | return values[index % maxSize]; |
267 | } |
268 | static const uint maxSize = 7; |
269 | static const T values[maxSize]; |
270 | }; |
271 | |
272 | template<> |
273 | const int SimpleValue<int>::values[] = { 10, 20, 30, 40, 100, 101, 102 }; |
274 | template<> |
275 | const Movable SimpleValue<Movable>::values[] = { 10, 20, 30, 40, 100, 101, 102 }; |
276 | template<> |
277 | const Complex SimpleValue<Complex>::values[] = { 10, 20, 30, 40, 100, 101, 102 }; |
278 | |
279 | // Make some macros for the tests to use in order to be slightly more readable... |
280 | #define T_FOO SimpleValue<T>::at(0) |
281 | #define T_BAR SimpleValue<T>::at(1) |
282 | #define T_BAZ SimpleValue<T>::at(2) |
283 | #define T_CAT SimpleValue<T>::at(3) |
284 | #define T_DOG SimpleValue<T>::at(4) |
285 | #define T_BLAH SimpleValue<T>::at(5) |
286 | #define T_WEEE SimpleValue<T>::at(6) |
287 | |
288 | template<typename T> |
289 | void tst_QLinkedList::length() const |
290 | { |
291 | /* Empty list. */ |
292 | { |
293 | const QLinkedList<T> list; |
294 | QCOMPARE(list.size(), 0); |
295 | } |
296 | |
297 | /* One entry. */ |
298 | { |
299 | QLinkedList<T> list; |
300 | list.append(T_FOO); |
301 | QCOMPARE(list.size(), 1); |
302 | } |
303 | |
304 | /* Two entries. */ |
305 | { |
306 | QLinkedList<T> list; |
307 | list.append(T_FOO); |
308 | list.append(T_BAR); |
309 | QCOMPARE(list.size(), 2); |
310 | } |
311 | |
312 | /* Three entries. */ |
313 | { |
314 | QLinkedList<T> list; |
315 | list.append(T_FOO); |
316 | list.append(T_BAR); |
317 | list.append(T_BAZ); |
318 | QCOMPARE(list.size(), 3); |
319 | } |
320 | } |
321 | |
322 | void tst_QLinkedList::eraseValidIteratorsOnSharedList() const |
323 | { |
324 | QLinkedList<int> a, b; |
325 | a.append(t: 5); |
326 | a.append(t: 10); |
327 | a.append(t: 20); |
328 | a.append(t: 20); |
329 | a.append(t: 20); |
330 | a.append(t: 20); |
331 | a.append(t: 30); |
332 | |
333 | QLinkedList<int>::iterator i = a.begin(); |
334 | ++i; |
335 | ++i; |
336 | ++i; |
337 | b = a; |
338 | QLinkedList<int>::iterator r = a.erase(pos: i); |
339 | QCOMPARE(b.size(), 7); |
340 | QCOMPARE(a.size(), 6); |
341 | --r; |
342 | --r; |
343 | QCOMPARE(*r, 10); // Ensure that number 2 instance was removed; |
344 | } |
345 | |
346 | void tst_QLinkedList::insertWithIteratorsOnSharedList() const |
347 | { |
348 | QLinkedList<int> a, b; |
349 | a.append(t: 5); |
350 | a.append(t: 10); |
351 | a.append(t: 20); |
352 | QLinkedList<int>::iterator i = a.begin(); |
353 | ++i; |
354 | ++i; |
355 | b = a; |
356 | |
357 | QLinkedList<int>::iterator i2 = a.insert(before: i, t: 15); |
358 | QCOMPARE(b.size(), 3); |
359 | QCOMPARE(a.size(), 4); |
360 | --i2; |
361 | QCOMPARE(*i2, 10); |
362 | } |
363 | |
364 | void tst_QLinkedList::lengthInt() const |
365 | { |
366 | length<int>(); |
367 | } |
368 | |
369 | void tst_QLinkedList::lengthMovable() const |
370 | { |
371 | const int liveCount = Movable::getLiveCount(); |
372 | length<Movable>(); |
373 | QCOMPARE(liveCount, Movable::getLiveCount()); |
374 | } |
375 | |
376 | void tst_QLinkedList::lengthComplex() const |
377 | { |
378 | const int liveCount = Complex::getLiveCount(); |
379 | length<Complex>(); |
380 | QCOMPARE(liveCount, Complex::getLiveCount()); |
381 | } |
382 | |
383 | void tst_QLinkedList::lengthSignature() const |
384 | { |
385 | /* Constness. */ |
386 | { |
387 | const QLinkedList<int> list; |
388 | /* The function should be const. */ |
389 | list.size(); |
390 | } |
391 | } |
392 | |
393 | template<typename T> |
394 | void tst_QLinkedList::first() const |
395 | { |
396 | QLinkedList<T> list; |
397 | list << T_FOO << T_BAR; |
398 | |
399 | QCOMPARE(list.first(), T_FOO); |
400 | |
401 | // remove an item, make sure it still works |
402 | list.pop_front(); |
403 | QVERIFY(list.size() == 1); |
404 | QCOMPARE(list.first(), T_BAR); |
405 | } |
406 | |
407 | void tst_QLinkedList::firstInt() const |
408 | { |
409 | first<int>(); |
410 | } |
411 | |
412 | void tst_QLinkedList::firstMovable() const |
413 | { |
414 | const int liveCount = Movable::getLiveCount(); |
415 | first<Movable>(); |
416 | QCOMPARE(liveCount, Movable::getLiveCount()); |
417 | } |
418 | |
419 | void tst_QLinkedList::firstComplex() const |
420 | { |
421 | const int liveCount = Complex::getLiveCount(); |
422 | first<Complex>(); |
423 | QCOMPARE(liveCount, Complex::getLiveCount()); |
424 | } |
425 | |
426 | template<typename T> |
427 | void tst_QLinkedList::last() const |
428 | { |
429 | QLinkedList<T> list; |
430 | list << T_FOO << T_BAR; |
431 | |
432 | QCOMPARE(list.last(), T_BAR); |
433 | |
434 | // remove an item, make sure it still works |
435 | list.pop_back(); |
436 | QVERIFY(list.size() == 1); |
437 | QCOMPARE(list.last(), T_FOO); |
438 | } |
439 | |
440 | void tst_QLinkedList::lastInt() const |
441 | { |
442 | last<int>(); |
443 | } |
444 | |
445 | void tst_QLinkedList::lastMovable() const |
446 | { |
447 | const int liveCount = Movable::getLiveCount(); |
448 | last<Movable>(); |
449 | QCOMPARE(liveCount, Movable::getLiveCount()); |
450 | } |
451 | |
452 | void tst_QLinkedList::lastComplex() const |
453 | { |
454 | const int liveCount = Complex::getLiveCount(); |
455 | last<Complex>(); |
456 | QCOMPARE(liveCount, Complex::getLiveCount()); |
457 | } |
458 | |
459 | template<typename T> |
460 | void tst_QLinkedList::begin() const |
461 | { |
462 | QLinkedList<T> list; |
463 | list << T_FOO << T_BAR; |
464 | |
465 | QCOMPARE(*list.begin(), T_FOO); |
466 | |
467 | // remove an item, make sure it still works |
468 | list.pop_front(); |
469 | QVERIFY(list.size() == 1); |
470 | QCOMPARE(*list.begin(), T_BAR); |
471 | } |
472 | |
473 | void tst_QLinkedList::beginInt() const |
474 | { |
475 | begin<int>(); |
476 | } |
477 | |
478 | void tst_QLinkedList::beginMovable() const |
479 | { |
480 | const int liveCount = Movable::getLiveCount(); |
481 | begin<Movable>(); |
482 | QCOMPARE(liveCount, Movable::getLiveCount()); |
483 | } |
484 | |
485 | void tst_QLinkedList::beginComplex() const |
486 | { |
487 | const int liveCount = Complex::getLiveCount(); |
488 | begin<Complex>(); |
489 | QCOMPARE(liveCount, Complex::getLiveCount()); |
490 | } |
491 | |
492 | template<typename T> |
493 | void tst_QLinkedList::end() const |
494 | { |
495 | QLinkedList<T> list; |
496 | list << T_FOO << T_BAR; |
497 | |
498 | QCOMPARE(*--list.end(), T_BAR); |
499 | |
500 | // remove an item, make sure it still works |
501 | list.pop_back(); |
502 | QVERIFY(list.size() == 1); |
503 | QCOMPARE(*--list.end(), T_FOO); |
504 | } |
505 | |
506 | void tst_QLinkedList::endInt() const |
507 | { |
508 | end<int>(); |
509 | } |
510 | |
511 | void tst_QLinkedList::endMovable() const |
512 | { |
513 | const int liveCount = Movable::getLiveCount(); |
514 | end<Movable>(); |
515 | QCOMPARE(liveCount, Movable::getLiveCount()); |
516 | } |
517 | |
518 | void tst_QLinkedList::endComplex() const |
519 | { |
520 | const int liveCount = Complex::getLiveCount(); |
521 | end<Complex>(); |
522 | QCOMPARE(liveCount, Complex::getLiveCount()); |
523 | } |
524 | |
525 | template<typename T> |
526 | void tst_QLinkedList::contains() const |
527 | { |
528 | QLinkedList<T> list; |
529 | list << T_FOO << T_BAR << T_BAZ; |
530 | |
531 | QVERIFY(list.contains(T_FOO)); |
532 | QVERIFY(list.contains(T_BLAH) != true); |
533 | |
534 | // add it and make sure it matches |
535 | list.append(T_BLAH); |
536 | QVERIFY(list.contains(T_BLAH)); |
537 | } |
538 | |
539 | void tst_QLinkedList::containsInt() const |
540 | { |
541 | contains<int>(); |
542 | } |
543 | |
544 | void tst_QLinkedList::containsMovable() const |
545 | { |
546 | const int liveCount = Movable::getLiveCount(); |
547 | contains<Movable>(); |
548 | QCOMPARE(liveCount, Movable::getLiveCount()); |
549 | } |
550 | |
551 | void tst_QLinkedList::containsComplex() const |
552 | { |
553 | const int liveCount = Complex::getLiveCount(); |
554 | contains<Complex>(); |
555 | QCOMPARE(liveCount, Complex::getLiveCount()); |
556 | } |
557 | |
558 | template<typename T> |
559 | void tst_QLinkedList::count() const |
560 | { |
561 | QLinkedList<T> list; |
562 | |
563 | // starts empty |
564 | QVERIFY(list.count() == 0); |
565 | |
566 | // goes up |
567 | list.append(T_FOO); |
568 | QVERIFY(list.count() == 1); |
569 | |
570 | // and up |
571 | list.append(T_BAR); |
572 | QVERIFY(list.count() == 2); |
573 | |
574 | // and down |
575 | list.pop_back(); |
576 | QVERIFY(list.count() == 1); |
577 | |
578 | // and empty. :) |
579 | list.pop_back(); |
580 | QVERIFY(list.count() == 0); |
581 | } |
582 | |
583 | void tst_QLinkedList::countInt() const |
584 | { |
585 | count<int>(); |
586 | } |
587 | |
588 | void tst_QLinkedList::countMovable() const |
589 | { |
590 | const int liveCount = Movable::getLiveCount(); |
591 | count<Movable>(); |
592 | QCOMPARE(liveCount, Movable::getLiveCount()); |
593 | } |
594 | |
595 | void tst_QLinkedList::countComplex() const |
596 | { |
597 | const int liveCount = Complex::getLiveCount(); |
598 | count<Complex>(); |
599 | QCOMPARE(liveCount, Complex::getLiveCount()); |
600 | } |
601 | |
602 | void tst_QLinkedList::cpp17ctad() const |
603 | { |
604 | #ifdef __cpp_deduction_guides |
605 | #define QVERIFY_IS_LIST_OF(obj, Type) \ |
606 | QVERIFY2((std::is_same<decltype(obj), QLinkedList<Type>>::value), \ |
607 | QMetaType::typeName(qMetaTypeId<decltype(obj)::value_type>())) |
608 | #define CHECK(Type, One, Two, Three) \ |
609 | do { \ |
610 | const Type v[] = {One, Two, Three}; \ |
611 | QLinkedList v1 = {One, Two, Three}; \ |
612 | QVERIFY_IS_LIST_OF(v1, Type); \ |
613 | QLinkedList v2(v1.begin(), v1.end()); \ |
614 | QVERIFY_IS_LIST_OF(v2, Type); \ |
615 | QLinkedList v3(std::begin(v), std::end(v)); \ |
616 | QVERIFY_IS_LIST_OF(v3, Type); \ |
617 | } while (false) \ |
618 | /*end*/ |
619 | CHECK(int, 1, 2, 3); |
620 | CHECK(double, 1.0, 2.0, 3.0); |
621 | CHECK(QString, QStringLiteral("one" ), QStringLiteral("two" ), QStringLiteral("three" )); |
622 | #undef QVERIFY_IS_LIST_OF |
623 | #undef CHECK |
624 | #else |
625 | QSKIP("This test requires C++17 Constructor Template Argument Deduction support enabled in the compiler." ); |
626 | #endif |
627 | } |
628 | |
629 | template<typename T> |
630 | void tst_QLinkedList::empty() const |
631 | { |
632 | QLinkedList<T> list; |
633 | |
634 | // make sure it starts empty |
635 | QVERIFY(list.empty()); |
636 | |
637 | // and doesn't stay empty |
638 | list.append(T_FOO); |
639 | QVERIFY(!list.empty()); |
640 | |
641 | // and goes back to being empty |
642 | list.pop_back(); |
643 | QVERIFY(list.empty()); |
644 | } |
645 | |
646 | void tst_QLinkedList::emptyInt() const |
647 | { |
648 | empty<int>(); |
649 | } |
650 | |
651 | void tst_QLinkedList::emptyMovable() const |
652 | { |
653 | const int liveCount = Movable::getLiveCount(); |
654 | empty<Movable>(); |
655 | QCOMPARE(liveCount, Movable::getLiveCount()); |
656 | } |
657 | |
658 | void tst_QLinkedList::emptyComplex() const |
659 | { |
660 | const int liveCount = Complex::getLiveCount(); |
661 | empty<Complex>(); |
662 | QCOMPARE(liveCount, Complex::getLiveCount()); |
663 | } |
664 | |
665 | template<typename T> |
666 | void tst_QLinkedList::endsWith() const |
667 | { |
668 | QLinkedList<T> list; |
669 | list << T_FOO << T_BAR << T_BAZ; |
670 | |
671 | // test it returns correctly in both cases |
672 | QVERIFY(list.endsWith(T_BAZ)); |
673 | QVERIFY(!list.endsWith(T_BAR)); |
674 | |
675 | // remove an item and make sure the end item changes |
676 | list.pop_back(); |
677 | QVERIFY(list.endsWith(T_BAR)); |
678 | } |
679 | |
680 | void tst_QLinkedList::endsWithInt() const |
681 | { |
682 | endsWith<int>(); |
683 | } |
684 | |
685 | void tst_QLinkedList::endsWithMovable() const |
686 | { |
687 | const int liveCount = Movable::getLiveCount(); |
688 | endsWith<Movable>(); |
689 | QCOMPARE(liveCount, Movable::getLiveCount()); |
690 | } |
691 | |
692 | void tst_QLinkedList::endsWithComplex() const |
693 | { |
694 | const int liveCount = Complex::getLiveCount(); |
695 | endsWith<Complex>(); |
696 | QCOMPARE(liveCount, Complex::getLiveCount()); |
697 | } |
698 | |
699 | template<typename T> |
700 | void tst_QLinkedList::removeAll() const |
701 | { |
702 | QLinkedList<T> list; |
703 | list << T_FOO << T_BAR << T_BAZ; |
704 | |
705 | // remove one instance |
706 | list.removeAll(T_BAR); |
707 | QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ); |
708 | |
709 | // many instances |
710 | list << T_FOO << T_BAR << T_BAZ << T_FOO << T_BAR << T_BAZ << T_FOO << T_BAR << T_BAZ; |
711 | list.removeAll(T_BAR); |
712 | QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ); |
713 | |
714 | // try remove something that doesn't exist |
715 | list.removeAll(T_WEEE); |
716 | QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ); |
717 | } |
718 | |
719 | void tst_QLinkedList::removeAllInt() const |
720 | { |
721 | removeAll<int>(); |
722 | } |
723 | |
724 | void tst_QLinkedList::removeAllMovable() const |
725 | { |
726 | const int liveCount = Movable::getLiveCount(); |
727 | removeAll<Movable>(); |
728 | QCOMPARE(liveCount, Movable::getLiveCount()); |
729 | } |
730 | |
731 | void tst_QLinkedList::removeAllComplex() const |
732 | { |
733 | const int liveCount = Complex::getLiveCount(); |
734 | removeAll<Complex>(); |
735 | QCOMPARE(liveCount, Complex::getLiveCount()); |
736 | } |
737 | |
738 | template<typename T> |
739 | void tst_QLinkedList::removeOne() const |
740 | { |
741 | QLinkedList<T> list; |
742 | list << T_FOO << T_BAR << T_BAZ; |
743 | |
744 | // middle |
745 | list.removeOne(T_BAR); |
746 | QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ); |
747 | |
748 | // start |
749 | list.removeOne(T_FOO); |
750 | QCOMPARE(list, QLinkedList<T>() << T_BAZ); |
751 | |
752 | // last |
753 | list.removeOne(T_BAZ); |
754 | QCOMPARE(list, QLinkedList<T>()); |
755 | |
756 | // make sure it really only removes one :) |
757 | list << T_FOO << T_FOO; |
758 | list.removeOne(T_FOO); |
759 | QCOMPARE(list, QLinkedList<T>() << T_FOO); |
760 | |
761 | // try remove something that doesn't exist |
762 | list.removeOne(T_WEEE); |
763 | QCOMPARE(list, QLinkedList<T>() << T_FOO); |
764 | } |
765 | |
766 | void tst_QLinkedList::removeOneInt() const |
767 | { |
768 | removeOne<int>(); |
769 | } |
770 | |
771 | void tst_QLinkedList::removeOneMovable() const |
772 | { |
773 | const int liveCount = Movable::getLiveCount(); |
774 | removeOne<Movable>(); |
775 | QCOMPARE(liveCount, Movable::getLiveCount()); |
776 | } |
777 | |
778 | void tst_QLinkedList::removeOneComplex() const |
779 | { |
780 | const int liveCount = Complex::getLiveCount(); |
781 | removeOne<Complex>(); |
782 | QCOMPARE(liveCount, Complex::getLiveCount()); |
783 | } |
784 | |
785 | void tst_QLinkedList::reverseIterators() const |
786 | { |
787 | QLinkedList<int> l; |
788 | l << 1 << 2 << 3 << 4; |
789 | QLinkedList<int> lr = l; |
790 | std::reverse(first: lr.begin(), last: lr.end()); |
791 | const QLinkedList<int> &clr = lr; |
792 | QVERIFY(std::equal(l.begin(), l.end(), lr.rbegin())); |
793 | QVERIFY(std::equal(l.begin(), l.end(), lr.crbegin())); |
794 | QVERIFY(std::equal(l.begin(), l.end(), clr.rbegin())); |
795 | QVERIFY(std::equal(lr.rbegin(), lr.rend(), l.begin())); |
796 | QVERIFY(std::equal(lr.crbegin(), lr.crend(), l.begin())); |
797 | QVERIFY(std::equal(clr.rbegin(), clr.rend(), l.begin())); |
798 | } |
799 | |
800 | template<typename T> |
801 | void tst_QLinkedList::startsWith() const |
802 | { |
803 | QLinkedList<T> list; |
804 | list << T_FOO << T_BAR << T_BAZ; |
805 | |
806 | // make sure it starts ok |
807 | QVERIFY(list.startsWith(T_FOO)); |
808 | |
809 | // remove an item |
810 | list.removeFirst(); |
811 | QVERIFY(list.startsWith(T_BAR)); |
812 | } |
813 | |
814 | void tst_QLinkedList::startsWithInt() const |
815 | { |
816 | startsWith<int>(); |
817 | } |
818 | |
819 | void tst_QLinkedList::startsWithMovable() const |
820 | { |
821 | const int liveCount = Movable::getLiveCount(); |
822 | startsWith<Movable>(); |
823 | QCOMPARE(liveCount, Movable::getLiveCount()); |
824 | } |
825 | |
826 | void tst_QLinkedList::startsWithComplex() const |
827 | { |
828 | const int liveCount = Complex::getLiveCount(); |
829 | startsWith<Complex>(); |
830 | QCOMPARE(liveCount, Complex::getLiveCount()); |
831 | } |
832 | |
833 | template<typename T> |
834 | void tst_QLinkedList::takeFirst() const |
835 | { |
836 | QLinkedList<T> list; |
837 | list << T_FOO << T_BAR << T_BAZ; |
838 | |
839 | QCOMPARE(list.takeFirst(), T_FOO); |
840 | QVERIFY(list.size() == 2); |
841 | QCOMPARE(list.takeFirst(), T_BAR); |
842 | QVERIFY(list.size() == 1); |
843 | QCOMPARE(list.takeFirst(), T_BAZ); |
844 | QVERIFY(list.size() == 0); |
845 | } |
846 | |
847 | void tst_QLinkedList::takeFirstInt() const |
848 | { |
849 | takeFirst<int>(); |
850 | } |
851 | |
852 | void tst_QLinkedList::takeFirstMovable() const |
853 | { |
854 | const int liveCount = Movable::getLiveCount(); |
855 | takeFirst<Movable>(); |
856 | QCOMPARE(liveCount, Movable::getLiveCount()); |
857 | } |
858 | |
859 | void tst_QLinkedList::takeFirstComplex() const |
860 | { |
861 | const int liveCount = Complex::getLiveCount(); |
862 | takeFirst<Complex>(); |
863 | QCOMPARE(liveCount, Complex::getLiveCount()); |
864 | } |
865 | |
866 | template<typename T> |
867 | void tst_QLinkedList::takeLast() const |
868 | { |
869 | QLinkedList<T> list; |
870 | list << T_FOO << T_BAR << T_BAZ; |
871 | |
872 | QCOMPARE(list.takeLast(), T_BAZ); |
873 | QCOMPARE(list.takeLast(), T_BAR); |
874 | QCOMPARE(list.takeLast(), T_FOO); |
875 | } |
876 | |
877 | void tst_QLinkedList::takeLastInt() const |
878 | { |
879 | takeLast<int>(); |
880 | } |
881 | |
882 | void tst_QLinkedList::takeLastMovable() const |
883 | { |
884 | const int liveCount = Movable::getLiveCount(); |
885 | takeLast<Movable>(); |
886 | QCOMPARE(liveCount, Movable::getLiveCount()); |
887 | } |
888 | |
889 | void tst_QLinkedList::takeLastComplex() const |
890 | { |
891 | const int liveCount = Complex::getLiveCount(); |
892 | takeLast<Complex>(); |
893 | QCOMPARE(liveCount, Complex::getLiveCount()); |
894 | } |
895 | |
896 | template<typename T> |
897 | void tst_QLinkedList::toStdList() const |
898 | { |
899 | QLinkedList<T> list; |
900 | list << T_FOO << T_BAR << T_BAZ; |
901 | |
902 | // yuck. |
903 | std::list<T> slist; |
904 | slist.push_back(T_FOO); |
905 | slist.push_back(T_BAR); |
906 | slist.push_back(T_BAZ); |
907 | |
908 | QCOMPARE(list.toStdList(), slist); |
909 | QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAR << T_BAZ); |
910 | } |
911 | |
912 | void tst_QLinkedList::toStdListInt() const |
913 | { |
914 | toStdList<int>(); |
915 | } |
916 | |
917 | void tst_QLinkedList::toStdListMovable() const |
918 | { |
919 | const int liveCount = Movable::getLiveCount(); |
920 | toStdList<Movable>(); |
921 | QCOMPARE(liveCount, Movable::getLiveCount()); |
922 | } |
923 | |
924 | void tst_QLinkedList::toStdListComplex() const |
925 | { |
926 | const int liveCount = Complex::getLiveCount(); |
927 | toStdList<Complex>(); |
928 | QCOMPARE(liveCount, Complex::getLiveCount()); |
929 | } |
930 | |
931 | template<typename T> |
932 | void tst_QLinkedList::testOperators() const |
933 | { |
934 | QLinkedList<T> list; |
935 | list << T_FOO << T_BAR << T_BAZ; |
936 | |
937 | QLinkedList<T> listtwo; |
938 | listtwo << T_FOO << T_BAR << T_BAZ; |
939 | |
940 | // test equal |
941 | QVERIFY(list == listtwo); |
942 | |
943 | // not equal |
944 | listtwo.append(T_CAT); |
945 | QVERIFY(list != listtwo); |
946 | |
947 | // += |
948 | list += listtwo; |
949 | QVERIFY(list.size() == 7); |
950 | QVERIFY(listtwo.size() == 4); |
951 | QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAR << T_BAZ |
952 | << T_FOO << T_BAR << T_BAZ << T_CAT); |
953 | |
954 | // = |
955 | list = listtwo; |
956 | QCOMPARE(list, listtwo); |
957 | QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAR << T_BAZ << T_CAT); |
958 | } |
959 | |
960 | void tst_QLinkedList::testOperatorsInt() const |
961 | { |
962 | testOperators<int>(); |
963 | } |
964 | |
965 | void tst_QLinkedList::testOperatorsMovable() const |
966 | { |
967 | const int liveCount = Movable::getLiveCount(); |
968 | testOperators<Movable>(); |
969 | QCOMPARE(liveCount, Movable::getLiveCount()); |
970 | } |
971 | |
972 | void tst_QLinkedList::testOperatorsComplex() const |
973 | { |
974 | const int liveCount = Complex::getLiveCount(); |
975 | testOperators<Complex>(); |
976 | QCOMPARE(liveCount, Complex::getLiveCount()); |
977 | } |
978 | |
979 | template<typename T> |
980 | void tst_QLinkedList::testSTLIterators() const |
981 | { |
982 | QLinkedList<T> list; |
983 | |
984 | // create a list |
985 | list << T_FOO << T_BAR << T_BAZ; |
986 | typename QLinkedList<T>::iterator it = list.begin(); |
987 | QCOMPARE(*it, T_FOO); it++; |
988 | QCOMPARE(*it, T_BAR); it++; |
989 | QCOMPARE(*it, T_BAZ); it++; |
990 | QCOMPARE(it, list.end()); it--; |
991 | |
992 | // walk backwards |
993 | QCOMPARE(*it, T_BAZ); it--; |
994 | QCOMPARE(*it, T_BAR); it--; |
995 | QCOMPARE(*it, T_FOO); |
996 | |
997 | // test erase |
998 | it = list.erase(it); |
999 | QVERIFY(list.size() == 2); |
1000 | QCOMPARE(*it, T_BAR); |
1001 | |
1002 | // test multiple erase |
1003 | it = list.erase(it, it + 2); |
1004 | QVERIFY(list.size() == 0); |
1005 | QCOMPARE(it, list.end()); |
1006 | |
1007 | // insert again |
1008 | it = list.insert(it, T_FOO); |
1009 | QVERIFY(list.size() == 1); |
1010 | QCOMPARE(*it, T_FOO); |
1011 | |
1012 | // insert again |
1013 | it = list.insert(it, T_BAR); |
1014 | QVERIFY(list.size() == 2); |
1015 | QCOMPARE(*it++, T_BAR); |
1016 | QCOMPARE(*it, T_FOO); |
1017 | } |
1018 | |
1019 | void tst_QLinkedList::testSTLIteratorsInt() const |
1020 | { |
1021 | testSTLIterators<int>(); |
1022 | } |
1023 | |
1024 | void tst_QLinkedList::testSTLIteratorsMovable() const |
1025 | { |
1026 | const int liveCount = Movable::getLiveCount(); |
1027 | testSTLIterators<Movable>(); |
1028 | QCOMPARE(liveCount, Movable::getLiveCount()); |
1029 | } |
1030 | |
1031 | void tst_QLinkedList::testSTLIteratorsComplex() const |
1032 | { |
1033 | const int liveCount = Complex::getLiveCount(); |
1034 | testSTLIterators<Complex>(); |
1035 | QCOMPARE(liveCount, Complex::getLiveCount()); |
1036 | } |
1037 | |
1038 | void tst_QLinkedList::initializeList() const |
1039 | { |
1040 | QLinkedList<int> v1 { 2, 3, 4 }; |
1041 | QCOMPARE(v1, QLinkedList<int>() << 2 << 3 << 4); |
1042 | QCOMPARE(v1, (QLinkedList<int> { 2, 3, 4})); |
1043 | |
1044 | QLinkedList<QLinkedList<int>> v2{ v1, { 1 }, QLinkedList<int>(), { 2, 3, 4 } }; |
1045 | QLinkedList<QLinkedList<int>> v3; |
1046 | v3 << v1 << (QLinkedList<int>() << 1) << QLinkedList<int>() << v1; |
1047 | QCOMPARE(v3, v2); |
1048 | } |
1049 | |
1050 | |
1051 | template<typename T> |
1052 | void tst_QLinkedList::constSharedNull() const |
1053 | { |
1054 | QLinkedList<T> list2; |
1055 | #if !defined(QT_NO_UNSHARABLE_CONTAINERS) |
1056 | QLinkedList<T> list1; |
1057 | list1.setSharable(false); |
1058 | QVERIFY(list1.isDetached()); |
1059 | |
1060 | list2.setSharable(true); |
1061 | #endif |
1062 | QVERIFY(!list2.isDetached()); |
1063 | } |
1064 | |
1065 | void tst_QLinkedList::constSharedNullInt() const |
1066 | { |
1067 | constSharedNull<int>(); |
1068 | } |
1069 | |
1070 | void tst_QLinkedList::constSharedNullMovable() const |
1071 | { |
1072 | const int liveCount = Movable::getLiveCount(); |
1073 | constSharedNull<Movable>(); |
1074 | QCOMPARE(liveCount, Movable::getLiveCount()); |
1075 | } |
1076 | |
1077 | void tst_QLinkedList::constSharedNullComplex() const |
1078 | { |
1079 | const int liveCount = Complex::getLiveCount(); |
1080 | constSharedNull<Complex>(); |
1081 | QCOMPARE(liveCount, Complex::getLiveCount()); |
1082 | } |
1083 | |
1084 | |
1085 | void tst_QLinkedList::setSharableInt() const |
1086 | { |
1087 | #if !defined(QT_NO_UNSHARABLE_CONTAINERS) |
1088 | QLinkedList<int> orglist; |
1089 | orglist << 0 << 1 << 2 << 3 << 4 << 5; |
1090 | int size = 6; |
1091 | |
1092 | QLinkedList<int> list; |
1093 | list = orglist; |
1094 | |
1095 | QVERIFY(!list.isDetached()); |
1096 | list.setSharable(true); |
1097 | |
1098 | QCOMPARE(list.size(), size); |
1099 | |
1100 | { |
1101 | QLinkedList<int> copy(list); |
1102 | QVERIFY(!copy.isDetached()); |
1103 | QVERIFY(copy.isSharedWith(list)); |
1104 | } |
1105 | |
1106 | list.setSharable(false); |
1107 | QVERIFY(list.isDetached() || list.isSharedWith(QLinkedList<int>())); |
1108 | |
1109 | { |
1110 | QLinkedList<int> copy(list); |
1111 | |
1112 | QVERIFY(copy.isDetached() || copy.isSharedWith(QLinkedList<int>())); |
1113 | QCOMPARE(copy.size(), size); |
1114 | QCOMPARE(copy, list); |
1115 | } |
1116 | |
1117 | list.setSharable(true); |
1118 | |
1119 | { |
1120 | QLinkedList<int> copy(list); |
1121 | |
1122 | QVERIFY(!copy.isDetached()); |
1123 | QVERIFY(copy.isSharedWith(list)); |
1124 | } |
1125 | |
1126 | QLinkedList<int>::const_iterator it = list.constBegin(); |
1127 | for (int i = 0; i < list.size(); ++i) { |
1128 | QCOMPARE(int(*it), i); |
1129 | ++it; |
1130 | } |
1131 | |
1132 | QCOMPARE(list.size(), size); |
1133 | #endif |
1134 | } |
1135 | |
1136 | QT_WARNING_POP |
1137 | #else |
1138 | class tst_QLinkedList : public QObject |
1139 | { |
1140 | Q_OBJECT |
1141 | private slots: |
1142 | void initTestCase() { QSKIP("Deprecated APIs are disabled, skipping this test." ); } |
1143 | }; |
1144 | |
1145 | #endif // QT_DEPRECATED_SINCE(5, 15) |
1146 | |
1147 | QTEST_APPLESS_MAIN(tst_QLinkedList) |
1148 | #include "tst_qlinkedlist.moc" |
1149 | |