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/QTest> |
30 | #include <qvarlengtharray.h> |
31 | #include <qvariant.h> |
32 | #include <qscopedvaluerollback.h> |
33 | |
34 | #include <memory> |
35 | |
36 | class tst_QVarLengthArray : public QObject |
37 | { |
38 | Q_OBJECT |
39 | private slots: |
40 | void defaultConstructor_int() { defaultConstructor<int>(); } |
41 | void defaultConstructor_QString() { defaultConstructor<QString>(); } |
42 | void append(); |
43 | void removeLast(); |
44 | void oldTests(); |
45 | void appendCausingRealloc(); |
46 | void appendIsStronglyExceptionSafe(); |
47 | void resize(); |
48 | void realloc(); |
49 | void reverseIterators(); |
50 | void count(); |
51 | void cpp17ctad(); |
52 | void first(); |
53 | void last(); |
54 | void squeeze(); |
55 | void operators(); |
56 | void indexOf(); |
57 | void lastIndexOf(); |
58 | void contains(); |
59 | void clear(); |
60 | void initializeListInt(); |
61 | void initializeListMovable(); |
62 | void initializeListComplex(); |
63 | void insertMove(); |
64 | void nonCopyable(); |
65 | void implicitDefaultCtor(); |
66 | |
67 | private: |
68 | template <typename T> |
69 | void defaultConstructor(); |
70 | template<typename T> |
71 | void initializeList(); |
72 | }; |
73 | |
74 | struct Tracker |
75 | { |
76 | static int count; |
77 | Tracker() { ++count; } |
78 | Tracker(const Tracker &) { ++count; } |
79 | Tracker(Tracker &&) { ++count; } |
80 | |
81 | Tracker &operator=(const Tracker &) = default; |
82 | Tracker &operator=(Tracker &&) = default; |
83 | |
84 | ~Tracker() { --count; } |
85 | }; |
86 | |
87 | int Tracker::count = 0; |
88 | |
89 | template <typename T> |
90 | void tst_QVarLengthArray::defaultConstructor() |
91 | { |
92 | { |
93 | QVarLengthArray<T, 123> vla; |
94 | QCOMPARE(vla.size(), 0); |
95 | QVERIFY(vla.empty()); |
96 | QVERIFY(vla.isEmpty()); |
97 | QCOMPARE(vla.begin(), vla.end()); |
98 | QCOMPARE(vla.capacity(), 123); |
99 | } |
100 | { |
101 | QVarLengthArray<T> vla; |
102 | QCOMPARE(vla.capacity(), 256); // notice, should we change the default |
103 | } |
104 | } |
105 | |
106 | void tst_QVarLengthArray::append() |
107 | { |
108 | QVarLengthArray<QString, 2> v; |
109 | v.append(t: QString("1" )); |
110 | v.append(t: v.front()); |
111 | QCOMPARE(v.capacity(), 2); |
112 | // transition from prealloc to heap: |
113 | v.append(t: v.front()); |
114 | QVERIFY(v.capacity() > 2); |
115 | QCOMPARE(v.front(), v.back()); |
116 | while (v.size() < v.capacity()) |
117 | v.push_back(t: v[0]); |
118 | QCOMPARE(v.back(), v.front()); |
119 | QCOMPARE(v.size(), v.capacity()); |
120 | // transition from heap to larger heap: |
121 | v.push_back(t: v.front()); |
122 | QCOMPARE(v.back(), v.front()); |
123 | |
124 | QVarLengthArray<int> v2; // rocket! |
125 | v2.append(t: 5); |
126 | } |
127 | |
128 | void tst_QVarLengthArray::removeLast() |
129 | { |
130 | { |
131 | QVarLengthArray<char, 2> v; |
132 | v.append(t: 0); |
133 | v.append(t: 1); |
134 | QCOMPARE(v.size(), 2); |
135 | v.append(t: 2); |
136 | v.append(t: 3); |
137 | QCOMPARE(v.size(), 4); |
138 | v.removeLast(); |
139 | QCOMPARE(v.size(), 3); |
140 | v.removeLast(); |
141 | QCOMPARE(v.size(), 2); |
142 | } |
143 | |
144 | { |
145 | QVarLengthArray<QString, 2> v; |
146 | v.append(t: "0" ); |
147 | v.append(t: "1" ); |
148 | QCOMPARE(v.size(), 2); |
149 | v.append(t: "2" ); |
150 | v.append(t: "3" ); |
151 | QCOMPARE(v.size(), 4); |
152 | v.removeLast(); |
153 | QCOMPARE(v.size(), 3); |
154 | v.removeLast(); |
155 | QCOMPARE(v.size(), 2); |
156 | } |
157 | |
158 | { |
159 | Tracker t; |
160 | QCOMPARE(Tracker::count, 1); |
161 | QVarLengthArray<Tracker, 2> v; |
162 | v.append(t); |
163 | v.append(t: {}); |
164 | QCOMPARE(Tracker::count, 3); |
165 | v.removeLast(); |
166 | QCOMPARE(Tracker::count, 2); |
167 | v.append(t); |
168 | v.append(t: {}); |
169 | QCOMPARE(Tracker::count, 4); |
170 | v.removeLast(); |
171 | QCOMPARE(Tracker::count, 3); |
172 | } |
173 | QCOMPARE(Tracker::count, 0); |
174 | } |
175 | |
176 | void tst_QVarLengthArray::oldTests() |
177 | { |
178 | { |
179 | QVarLengthArray<int, 256> sa(128); |
180 | QVERIFY(sa.data() == &sa[0]); |
181 | sa[0] = 0xfee; |
182 | sa[10] = 0xff; |
183 | QVERIFY(sa[0] == 0xfee); |
184 | QVERIFY(sa[10] == 0xff); |
185 | sa.resize(asize: 512); |
186 | QVERIFY(sa.data() == &sa[0]); |
187 | QVERIFY(sa[0] == 0xfee); |
188 | QVERIFY(sa[10] == 0xff); |
189 | QVERIFY(sa.at(0) == 0xfee); |
190 | QVERIFY(sa.at(10) == 0xff); |
191 | QVERIFY(sa.value(0) == 0xfee); |
192 | QVERIFY(sa.value(10) == 0xff); |
193 | QVERIFY(sa.value(1000) == 0); |
194 | QVERIFY(sa.value(1000, 12) == 12); |
195 | QVERIFY(sa.size() == 512); |
196 | sa.reserve(asize: 1024); |
197 | QVERIFY(sa.capacity() == 1024); |
198 | QVERIFY(sa.size() == 512); |
199 | } |
200 | { |
201 | QVarLengthArray<QString> sa(10); |
202 | sa[0] = "Hello" ; |
203 | sa[9] = "World" ; |
204 | QCOMPARE(*sa.data(), QLatin1String("Hello" )); |
205 | QCOMPARE(sa[9], QLatin1String("World" )); |
206 | sa.reserve(asize: 512); |
207 | QCOMPARE(*sa.data(), QLatin1String("Hello" )); |
208 | QCOMPARE(sa[9], QLatin1String("World" )); |
209 | sa.resize(asize: 512); |
210 | QCOMPARE(*sa.data(), QLatin1String("Hello" )); |
211 | QCOMPARE(sa[9], QLatin1String("World" )); |
212 | } |
213 | { |
214 | int arr[2] = {1, 2}; |
215 | QVarLengthArray<int> sa(10); |
216 | QCOMPARE(sa.size(), 10); |
217 | sa.append(abuf: arr, increment: 2); |
218 | QCOMPARE(sa.size(), 12); |
219 | QCOMPARE(sa[10], 1); |
220 | QCOMPARE(sa[11], 2); |
221 | } |
222 | { |
223 | QString arr[2] = { QString("hello" ), QString("world" ) }; |
224 | QVarLengthArray<QString> sa(10); |
225 | QCOMPARE(sa.size(), 10); |
226 | sa.append(abuf: arr, increment: 2); |
227 | QCOMPARE(sa.size(), 12); |
228 | QCOMPARE(sa[10], QString("hello" )); |
229 | QCOMPARE(sa[11], QString("world" )); |
230 | QCOMPARE(sa.at(10), QString("hello" )); |
231 | QCOMPARE(sa.at(11), QString("world" )); |
232 | QCOMPARE(sa.value(10), QString("hello" )); |
233 | QCOMPARE(sa.value(11), QString("world" )); |
234 | QCOMPARE(sa.value(10000), QString()); |
235 | QCOMPARE(sa.value(1212112, QString("none" )), QString("none" )); |
236 | QCOMPARE(sa.value(-12, QString("neg" )), QString("neg" )); |
237 | |
238 | sa.append(abuf: arr, increment: 1); |
239 | QCOMPARE(sa.size(), 13); |
240 | QCOMPARE(sa[12], QString("hello" )); |
241 | |
242 | sa.append(abuf: arr, increment: 0); |
243 | QCOMPARE(sa.size(), 13); |
244 | } |
245 | { |
246 | // assignment operator and copy constructor |
247 | |
248 | QVarLengthArray<int> sa(10); |
249 | sa[5] = 5; |
250 | |
251 | QVarLengthArray<int> sa2(10); |
252 | sa2[5] = 6; |
253 | sa2 = sa; |
254 | QCOMPARE(sa2[5], 5); |
255 | |
256 | QVarLengthArray<int> sa3(sa); |
257 | QCOMPARE(sa3[5], 5); |
258 | } |
259 | } |
260 | |
261 | void tst_QVarLengthArray::appendCausingRealloc() |
262 | { |
263 | // This is a regression test for an old bug where creating a |
264 | // QVarLengthArray of the same size as the prealloc size would make |
265 | // the next call to append(const T&) corrupt the memory. |
266 | QVarLengthArray<float, 1> d(1); |
267 | for (int i=0; i<30; i++) |
268 | d.append(t: i); |
269 | } |
270 | |
271 | void tst_QVarLengthArray::appendIsStronglyExceptionSafe() |
272 | { |
273 | #ifdef QT_NO_EXCEPTIONS |
274 | QSKIP("This test requires exception support enabled in the compiler." ); |
275 | #else |
276 | static bool throwOnCopyNow = false; |
277 | static bool throwOnMoveNow = false; |
278 | struct Thrower { |
279 | Thrower() = default; |
280 | Thrower(const Thrower &) |
281 | { |
282 | if (throwOnCopyNow) |
283 | throw 1; |
284 | } |
285 | Thrower &operator=(const Thrower &) = default; |
286 | Thrower(Thrower &&) |
287 | { |
288 | if (throwOnMoveNow) |
289 | throw 1; |
290 | } |
291 | Thrower &operator=(Thrower &&) = default; |
292 | ~Thrower() = default; |
293 | }; |
294 | |
295 | { |
296 | // ### TODO: QVLA isn't exception-safe when throwing during reallocation, |
297 | // ### so check with size() < capacity() for now |
298 | QVarLengthArray<Thrower, 2> vla(1); |
299 | { |
300 | Thrower t; |
301 | const QScopedValueRollback<bool> rb(throwOnCopyNow, true); |
302 | QVERIFY_EXCEPTION_THROWN(vla.push_back(t), int); |
303 | QCOMPARE(vla.size(), 1); |
304 | } |
305 | { |
306 | const QScopedValueRollback<bool> rb(throwOnMoveNow, true); |
307 | QVERIFY_EXCEPTION_THROWN(vla.push_back({}), int); |
308 | QCOMPARE(vla.size(), 1); |
309 | } |
310 | } |
311 | #endif |
312 | } |
313 | |
314 | void tst_QVarLengthArray::resize() |
315 | { |
316 | //MOVABLE |
317 | { |
318 | QVarLengthArray<QVariant,1> values(1); |
319 | QCOMPARE(values.size(), 1); |
320 | values[0] = 1; |
321 | values.resize(asize: 2); |
322 | QCOMPARE(values[1], QVariant()); |
323 | QCOMPARE(values[0], QVariant(1)); |
324 | values[1] = 2; |
325 | QCOMPARE(values[1], QVariant(2)); |
326 | QCOMPARE(values.size(), 2); |
327 | } |
328 | |
329 | //POD |
330 | { |
331 | QVarLengthArray<int,1> values(1); |
332 | QCOMPARE(values.size(), 1); |
333 | values[0] = 1; |
334 | values.resize(asize: 2); |
335 | QCOMPARE(values[0], 1); |
336 | values[1] = 2; |
337 | QCOMPARE(values[1], 2); |
338 | QCOMPARE(values.size(), 2); |
339 | } |
340 | |
341 | //COMPLEX |
342 | { |
343 | QVarLengthArray<QVarLengthArray<QString, 15>,1> values(1); |
344 | QCOMPARE(values.size(), 1); |
345 | values[0].resize(asize: 10); |
346 | values.resize(asize: 2); |
347 | QCOMPARE(values[1].size(), 0); |
348 | QCOMPARE(values[0].size(), 10); |
349 | values[1].resize(asize: 20); |
350 | QCOMPARE(values[1].size(), 20); |
351 | QCOMPARE(values.size(), 2); |
352 | } |
353 | } |
354 | |
355 | struct MyBase |
356 | { |
357 | MyBase() |
358 | : data(this) |
359 | , isCopy(false) |
360 | { |
361 | ++liveCount; |
362 | } |
363 | |
364 | MyBase(MyBase const &) |
365 | : data(this) |
366 | , isCopy(true) |
367 | { |
368 | ++copyCount; |
369 | ++liveCount; |
370 | } |
371 | |
372 | MyBase & operator=(MyBase const &) |
373 | { |
374 | if (!isCopy) { |
375 | isCopy = true; |
376 | ++copyCount; |
377 | } else { |
378 | ++errorCount; |
379 | } |
380 | if (!data) { |
381 | --movedCount; |
382 | ++liveCount; |
383 | } |
384 | data = this; |
385 | |
386 | return *this; |
387 | } |
388 | |
389 | ~MyBase() |
390 | { |
391 | if (isCopy) { |
392 | if (!copyCount || !data) |
393 | ++errorCount; |
394 | else |
395 | --copyCount; |
396 | } |
397 | |
398 | if (data) { |
399 | if (!liveCount) |
400 | ++errorCount; |
401 | else |
402 | --liveCount; |
403 | } else |
404 | --movedCount; |
405 | } |
406 | |
407 | bool wasConstructedAt(const MyBase *that) const |
408 | { |
409 | return that == data; |
410 | } |
411 | |
412 | bool hasMoved() const { return !wasConstructedAt(that: this); } |
413 | |
414 | protected: |
415 | MyBase(const MyBase *data, bool isCopy) |
416 | : data(data), isCopy(isCopy) {} |
417 | |
418 | const MyBase *data; |
419 | bool isCopy; |
420 | |
421 | public: |
422 | static int errorCount; |
423 | static int liveCount; |
424 | static int copyCount; |
425 | static int movedCount; |
426 | }; |
427 | |
428 | int MyBase::errorCount = 0; |
429 | int MyBase::liveCount = 0; |
430 | int MyBase::copyCount = 0; |
431 | int MyBase::movedCount = 0; |
432 | |
433 | struct MyPrimitive |
434 | : MyBase |
435 | { |
436 | MyPrimitive() |
437 | { |
438 | ++errorCount; |
439 | } |
440 | |
441 | ~MyPrimitive() |
442 | { |
443 | ++errorCount; |
444 | } |
445 | |
446 | MyPrimitive(MyPrimitive const &other) |
447 | : MyBase(other) |
448 | { |
449 | ++errorCount; |
450 | } |
451 | }; |
452 | |
453 | struct MyMovable |
454 | : MyBase |
455 | { |
456 | MyMovable(char input = 'j') : MyBase(), i(input) {} |
457 | |
458 | MyMovable(MyMovable const &other) : MyBase(other), i(other.i) {} |
459 | |
460 | MyMovable(MyMovable &&other) : MyBase(other.data, other.isCopy), i(other.i) |
461 | { |
462 | ++movedCount; |
463 | other.isCopy = false; |
464 | other.data = nullptr; |
465 | } |
466 | |
467 | MyMovable & operator=(const MyMovable &other) |
468 | { |
469 | MyBase::operator=(other); |
470 | i = other.i; |
471 | return *this; |
472 | } |
473 | |
474 | MyMovable & operator=(MyMovable &&other) |
475 | { |
476 | if (isCopy) |
477 | --copyCount; |
478 | ++movedCount; |
479 | if (other.data) |
480 | --liveCount; |
481 | isCopy = other.isCopy; |
482 | data = other.data; |
483 | other.isCopy = false; |
484 | other.data = nullptr; |
485 | |
486 | return *this; |
487 | } |
488 | |
489 | bool operator==(const MyMovable &other) const |
490 | { |
491 | return i == other.i; |
492 | } |
493 | char i; |
494 | }; |
495 | |
496 | struct MyComplex |
497 | : MyBase |
498 | { |
499 | MyComplex(char input = 'j') : i(input) {} |
500 | bool operator==(const MyComplex &other) const |
501 | { |
502 | return i == other.i; |
503 | } |
504 | char i; |
505 | }; |
506 | |
507 | QT_BEGIN_NAMESPACE |
508 | |
509 | Q_DECLARE_TYPEINFO(MyPrimitive, Q_PRIMITIVE_TYPE); |
510 | Q_DECLARE_TYPEINFO(MyMovable, Q_MOVABLE_TYPE); |
511 | Q_DECLARE_TYPEINFO(MyComplex, Q_COMPLEX_TYPE); |
512 | |
513 | QT_END_NAMESPACE |
514 | |
515 | bool reallocTestProceed = true; |
516 | |
517 | template <class T, int PreAlloc> |
518 | int countMoved(QVarLengthArray<T, PreAlloc> const &c) |
519 | { |
520 | int result = 0; |
521 | for (int i = 0; i < c.size(); ++i) |
522 | if (c[i].hasMoved()) |
523 | ++result; |
524 | |
525 | return result; |
526 | } |
527 | |
528 | template <class T> |
529 | void reallocTest() |
530 | { |
531 | reallocTestProceed = false; |
532 | |
533 | typedef QVarLengthArray<T, 16> Container; |
534 | enum { |
535 | isStatic = QTypeInfo<T>::isStatic, |
536 | isComplex = QTypeInfo<T>::isComplex, |
537 | |
538 | isPrimitive = !isComplex && !isStatic, |
539 | isMovable = !isStatic |
540 | }; |
541 | |
542 | // Constructors |
543 | Container a; |
544 | QCOMPARE( MyBase::liveCount, 0 ); |
545 | QCOMPARE( MyBase::copyCount, 0 ); |
546 | |
547 | QVERIFY( a.capacity() >= 16 ); |
548 | QCOMPARE( a.size(), 0 ); |
549 | |
550 | Container b_real(8); |
551 | Container const &b = b_real; |
552 | QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 8 ); |
553 | QCOMPARE( MyBase::copyCount, 0 ); |
554 | |
555 | QVERIFY( b.capacity() >= 16 ); |
556 | QCOMPARE( b.size(), 8 ); |
557 | |
558 | // Assignment |
559 | a = b; |
560 | QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 16 ); |
561 | QCOMPARE( MyBase::copyCount, isComplex ? 8 : 0 ); |
562 | QVERIFY( a.capacity() >= 16 ); |
563 | QCOMPARE( a.size(), 8 ); |
564 | |
565 | QVERIFY( b.capacity() >= 16 ); |
566 | QCOMPARE( b.size(), 8 ); |
567 | |
568 | // append |
569 | a.append(b.data(), b.size()); |
570 | QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 24 ); |
571 | QCOMPARE( MyBase::copyCount, isComplex ? 16 : 0 ); |
572 | |
573 | QVERIFY( a.capacity() >= 16 ); |
574 | QCOMPARE( a.size(), 16 ); |
575 | |
576 | QVERIFY( b.capacity() >= 16 ); |
577 | QCOMPARE( b.size(), 8 ); |
578 | |
579 | // removeLast |
580 | a.removeLast(); |
581 | QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 23 ); |
582 | QCOMPARE( MyBase::copyCount, isComplex ? 15 : 0 ); |
583 | |
584 | QVERIFY( a.capacity() >= 16 ); |
585 | QCOMPARE( a.size(), 15 ); |
586 | |
587 | QVERIFY( b.capacity() >= 16 ); |
588 | QCOMPARE( b.size(), 8 ); |
589 | |
590 | // Movable types |
591 | const int capacity = a.capacity(); |
592 | if (!isPrimitive) |
593 | QCOMPARE( countMoved(a), 0 ); |
594 | |
595 | // Reserve, no re-allocation |
596 | a.reserve(capacity); |
597 | if (!isPrimitive) |
598 | QCOMPARE( countMoved(a), 0 ); |
599 | QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 23 ); |
600 | QCOMPARE( MyBase::copyCount, isComplex ? 15 : 0 ); |
601 | |
602 | QCOMPARE( a.capacity(), capacity ); |
603 | QCOMPARE( a.size(), 15 ); |
604 | |
605 | QVERIFY( b.capacity() >= 16 ); |
606 | QCOMPARE( b.size(), 8 ); |
607 | |
608 | // Reserve, force re-allocation |
609 | a.reserve(capacity * 2); |
610 | if (!isPrimitive) |
611 | QCOMPARE( countMoved(a), isMovable ? 15 : 0 ); |
612 | QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 23 ); |
613 | QCOMPARE( MyBase::copyCount, isComplex ? 15 : 0 ); |
614 | |
615 | QVERIFY( a.capacity() >= capacity * 2 ); |
616 | QCOMPARE( a.size(), 15 ); |
617 | |
618 | QVERIFY( b.capacity() >= 16 ); |
619 | QCOMPARE( b.size(), 8 ); |
620 | |
621 | // resize, grow |
622 | a.resize(40); |
623 | if (!isPrimitive) |
624 | QCOMPARE( countMoved(a), isMovable ? 15 : 0 ); |
625 | QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 48 ); |
626 | QCOMPARE( MyBase::copyCount, isComplex ? 15 : 0 ); |
627 | |
628 | QVERIFY( a.capacity() >= a.size() ); |
629 | QCOMPARE( a.size(), 40 ); |
630 | |
631 | QVERIFY( b.capacity() >= 16 ); |
632 | QCOMPARE( b.size(), 8 ); |
633 | |
634 | // Copy constructor, allocate |
635 | { |
636 | Container c(a); |
637 | if (!isPrimitive) |
638 | QCOMPARE( countMoved(c), 0 ); |
639 | QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 88 ); |
640 | QCOMPARE( MyBase::copyCount, isComplex ? 55 : 0 ); |
641 | |
642 | QVERIFY( a.capacity() >= a.size() ); |
643 | QCOMPARE( a.size(), 40 ); |
644 | |
645 | QVERIFY( b.capacity() >= 16 ); |
646 | QCOMPARE( b.size(), 8 ); |
647 | |
648 | QVERIFY( c.capacity() >= 40 ); |
649 | QCOMPARE( c.size(), 40 ); |
650 | } |
651 | |
652 | // resize, shrink |
653 | a.resize(10); |
654 | if (!isPrimitive) |
655 | QCOMPARE( countMoved(a), isMovable ? 10 : 0 ); |
656 | QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 18 ); |
657 | QCOMPARE( MyBase::copyCount, isComplex ? 10 : 0 ); |
658 | |
659 | QVERIFY( a.capacity() >= a.size() ); |
660 | QCOMPARE( a.size(), 10 ); |
661 | |
662 | QVERIFY( b.capacity() >= 16 ); |
663 | QCOMPARE( b.size(), 8 ); |
664 | |
665 | // Copy constructor, don't allocate |
666 | { |
667 | Container c(a); |
668 | if (!isPrimitive) |
669 | QCOMPARE( countMoved(c), 0 ); |
670 | QCOMPARE( MyBase::liveCount, isPrimitive ? 0 : 28 ); |
671 | QCOMPARE( MyBase::copyCount, isComplex ? 20 : 0 ); |
672 | |
673 | QVERIFY( a.capacity() >= a.size() ); |
674 | QCOMPARE( a.size(), 10 ); |
675 | |
676 | QVERIFY( b.capacity() >= 16 ); |
677 | QCOMPARE( b.size(), 8 ); |
678 | |
679 | QVERIFY( c.capacity() >= 16 ); |
680 | QCOMPARE( c.size(), 10 ); |
681 | } |
682 | |
683 | a.clear(); |
684 | QCOMPARE( a.size(), 0 ); |
685 | |
686 | b_real.clear(); |
687 | QCOMPARE( b.size(), 0 ); |
688 | |
689 | QCOMPARE(MyBase::errorCount, 0); |
690 | QCOMPARE(MyBase::liveCount, 0); |
691 | |
692 | // All done |
693 | reallocTestProceed = true; |
694 | } |
695 | |
696 | void tst_QVarLengthArray::realloc() |
697 | { |
698 | reallocTest<MyBase>(); |
699 | QVERIFY(reallocTestProceed); |
700 | |
701 | reallocTest<MyPrimitive>(); |
702 | QVERIFY(reallocTestProceed); |
703 | |
704 | reallocTest<MyMovable>(); |
705 | QVERIFY(reallocTestProceed); |
706 | |
707 | reallocTest<MyComplex>(); |
708 | QVERIFY(reallocTestProceed); |
709 | } |
710 | |
711 | void tst_QVarLengthArray::reverseIterators() |
712 | { |
713 | QVarLengthArray<int> v; |
714 | v << 1 << 2 << 3 << 4; |
715 | QVarLengthArray<int> vr = v; |
716 | std::reverse(first: vr.begin(), last: vr.end()); |
717 | const QVarLengthArray<int> &cvr = vr; |
718 | QVERIFY(std::equal(v.begin(), v.end(), vr.rbegin())); |
719 | QVERIFY(std::equal(v.begin(), v.end(), vr.crbegin())); |
720 | QVERIFY(std::equal(v.begin(), v.end(), cvr.rbegin())); |
721 | QVERIFY(std::equal(vr.rbegin(), vr.rend(), v.begin())); |
722 | QVERIFY(std::equal(vr.crbegin(), vr.crend(), v.begin())); |
723 | QVERIFY(std::equal(cvr.rbegin(), cvr.rend(), v.begin())); |
724 | } |
725 | |
726 | void tst_QVarLengthArray::count() |
727 | { |
728 | // tests size(), count() and length(), since they're the same thing |
729 | { |
730 | const QVarLengthArray<int> list; |
731 | QCOMPARE(list.length(), 0); |
732 | QCOMPARE(list.count(), 0); |
733 | QCOMPARE(list.size(), 0); |
734 | } |
735 | |
736 | { |
737 | QVarLengthArray<int> list; |
738 | list.append(t: 0); |
739 | QCOMPARE(list.length(), 1); |
740 | QCOMPARE(list.count(), 1); |
741 | QCOMPARE(list.size(), 1); |
742 | } |
743 | |
744 | { |
745 | QVarLengthArray<int> list; |
746 | list.append(t: 0); |
747 | list.append(t: 1); |
748 | QCOMPARE(list.length(), 2); |
749 | QCOMPARE(list.count(), 2); |
750 | QCOMPARE(list.size(), 2); |
751 | } |
752 | |
753 | { |
754 | QVarLengthArray<int> list; |
755 | list.append(t: 0); |
756 | list.append(t: 0); |
757 | list.append(t: 0); |
758 | QCOMPARE(list.length(), 3); |
759 | QCOMPARE(list.count(), 3); |
760 | QCOMPARE(list.size(), 3); |
761 | } |
762 | |
763 | // test removals too |
764 | { |
765 | QVarLengthArray<int> list; |
766 | list.append(t: 0); |
767 | list.append(t: 0); |
768 | list.append(t: 0); |
769 | QCOMPARE(list.length(), 3); |
770 | QCOMPARE(list.count(), 3); |
771 | QCOMPARE(list.size(), 3); |
772 | list.removeLast(); |
773 | QCOMPARE(list.length(), 2); |
774 | QCOMPARE(list.count(), 2); |
775 | QCOMPARE(list.size(), 2); |
776 | list.removeLast(); |
777 | QCOMPARE(list.length(), 1); |
778 | QCOMPARE(list.count(), 1); |
779 | QCOMPARE(list.size(), 1); |
780 | list.removeLast(); |
781 | QCOMPARE(list.length(), 0); |
782 | QCOMPARE(list.count(), 0); |
783 | QCOMPARE(list.size(), 0); |
784 | } |
785 | } |
786 | |
787 | void tst_QVarLengthArray::cpp17ctad() |
788 | { |
789 | #ifdef __cpp_deduction_guides |
790 | #define QVERIFY_IS_VLA_OF(obj, Type) \ |
791 | QVERIFY2((std::is_same<decltype(obj), QVarLengthArray<Type>>::value), \ |
792 | QMetaType::typeName(qMetaTypeId<decltype(obj)::value_type>())) |
793 | #define CHECK(Type, One, Two, Three) \ |
794 | do { \ |
795 | const Type v[] = {One, Two, Three}; \ |
796 | QVarLengthArray v1 = {One, Two, Three}; \ |
797 | QVERIFY_IS_VLA_OF(v1, Type); \ |
798 | QVarLengthArray v2(v1.begin(), v1.end()); \ |
799 | QVERIFY_IS_VLA_OF(v2, Type); \ |
800 | QVarLengthArray v3(std::begin(v), std::end(v)); \ |
801 | QVERIFY_IS_VLA_OF(v3, Type); \ |
802 | } while (false) \ |
803 | /*end*/ |
804 | CHECK(int, 1, 2, 3); |
805 | CHECK(double, 1.0, 2.0, 3.0); |
806 | CHECK(QString, QStringLiteral("one" ), QStringLiteral("two" ), QStringLiteral("three" )); |
807 | #undef QVERIFY_IS_VLA_OF |
808 | #undef CHECK |
809 | #else |
810 | QSKIP("This test requires C++17 Constructor Template Argument Deduction support enabled in the compiler." ); |
811 | #endif |
812 | |
813 | } |
814 | |
815 | void tst_QVarLengthArray::first() |
816 | { |
817 | // append some items, make sure it stays sane |
818 | QVarLengthArray<int> list; |
819 | list.append(t: 27); |
820 | QCOMPARE(list.first(), 27); |
821 | list.append(t: 4); |
822 | QCOMPARE(list.first(), 27); |
823 | list.append(t: 1987); |
824 | QCOMPARE(list.first(), 27); |
825 | QCOMPARE(list.length(), 3); |
826 | |
827 | // remove some, make sure it stays sane |
828 | list.removeLast(); |
829 | QCOMPARE(list.first(), 27); |
830 | QCOMPARE(list.length(), 2); |
831 | |
832 | list.removeLast(); |
833 | QCOMPARE(list.first(), 27); |
834 | QCOMPARE(list.length(), 1); |
835 | } |
836 | |
837 | void tst_QVarLengthArray::last() |
838 | { |
839 | // append some items, make sure it stays sane |
840 | QVarLengthArray<int> list; |
841 | list.append(t: 27); |
842 | QCOMPARE(list.last(), 27); |
843 | list.append(t: 4); |
844 | QCOMPARE(list.last(), 4); |
845 | list.append(t: 1987); |
846 | QCOMPARE(list.last(), 1987); |
847 | QCOMPARE(list.length(), 3); |
848 | |
849 | // remove some, make sure it stays sane |
850 | list.removeLast(); |
851 | QCOMPARE(list.last(), 4); |
852 | QCOMPARE(list.length(), 2); |
853 | |
854 | list.removeLast(); |
855 | QCOMPARE(list.last(), 27); |
856 | QCOMPARE(list.length(), 1); |
857 | } |
858 | |
859 | void tst_QVarLengthArray::squeeze() |
860 | { |
861 | QVarLengthArray<int> list; |
862 | int sizeOnStack = list.capacity(); |
863 | int sizeOnHeap = sizeOnStack * 2; |
864 | list.resize(asize: 0); |
865 | QCOMPARE(list.capacity(), sizeOnStack); |
866 | list.resize(asize: sizeOnHeap); |
867 | QCOMPARE(list.capacity(), sizeOnHeap); |
868 | list.resize(asize: sizeOnStack); |
869 | QCOMPARE(list.capacity(), sizeOnHeap); |
870 | list.resize(asize: 0); |
871 | QCOMPARE(list.capacity(), sizeOnHeap); |
872 | list.squeeze(); |
873 | QCOMPARE(list.capacity(), sizeOnStack); |
874 | list.resize(asize: sizeOnStack); |
875 | list.squeeze(); |
876 | QCOMPARE(list.capacity(), sizeOnStack); |
877 | list.resize(asize: sizeOnHeap); |
878 | list.squeeze(); |
879 | QCOMPARE(list.capacity(), sizeOnHeap); |
880 | } |
881 | |
882 | void tst_QVarLengthArray::operators() |
883 | { |
884 | QVarLengthArray<QString> myvla; |
885 | myvla << "A" << "B" << "C" ; |
886 | QVarLengthArray<QString> myvlatwo; |
887 | myvlatwo << "D" << "E" << "F" ; |
888 | QVarLengthArray<QString> combined; |
889 | combined << "A" << "B" << "C" << "D" << "E" << "F" ; |
890 | |
891 | // != |
892 | QVERIFY(myvla != myvlatwo); |
893 | |
894 | // +=: not provided, emulate |
895 | //myvla += myvlatwo; |
896 | Q_FOREACH (const QString &s, myvlatwo) |
897 | myvla.push_back(t: s); |
898 | QCOMPARE(myvla, combined); |
899 | |
900 | // == |
901 | QVERIFY(myvla == combined); |
902 | |
903 | // <, >, <=, >= |
904 | QVERIFY(!(myvla < combined)); |
905 | QVERIFY(!(myvla > combined)); |
906 | QVERIFY( myvla <= combined); |
907 | QVERIFY( myvla >= combined); |
908 | combined.push_back(t: "G" ); |
909 | QVERIFY( myvla < combined); |
910 | QVERIFY(!(myvla > combined)); |
911 | QVERIFY( myvla <= combined); |
912 | QVERIFY(!(myvla >= combined)); |
913 | QVERIFY(combined > myvla); |
914 | QVERIFY(combined >= myvla); |
915 | |
916 | // [] |
917 | QCOMPARE(myvla[0], QLatin1String("A" )); |
918 | QCOMPARE(myvla[1], QLatin1String("B" )); |
919 | QCOMPARE(myvla[2], QLatin1String("C" )); |
920 | QCOMPARE(myvla[3], QLatin1String("D" )); |
921 | QCOMPARE(myvla[4], QLatin1String("E" )); |
922 | QCOMPARE(myvla[5], QLatin1String("F" )); |
923 | } |
924 | |
925 | void tst_QVarLengthArray::indexOf() |
926 | { |
927 | QVarLengthArray<QString> myvec; |
928 | myvec << "A" << "B" << "C" << "B" << "A" ; |
929 | |
930 | QVERIFY(myvec.indexOf("B" ) == 1); |
931 | QVERIFY(myvec.indexOf("B" , 1) == 1); |
932 | QVERIFY(myvec.indexOf("B" , 2) == 3); |
933 | QVERIFY(myvec.indexOf("X" ) == -1); |
934 | QVERIFY(myvec.indexOf("X" , 2) == -1); |
935 | |
936 | // add an X |
937 | myvec << "X" ; |
938 | QVERIFY(myvec.indexOf("X" ) == 5); |
939 | QVERIFY(myvec.indexOf("X" , 5) == 5); |
940 | QVERIFY(myvec.indexOf("X" , 6) == -1); |
941 | |
942 | // remove first A |
943 | myvec.remove(i: 0); |
944 | QVERIFY(myvec.indexOf("A" ) == 3); |
945 | QVERIFY(myvec.indexOf("A" , 3) == 3); |
946 | QVERIFY(myvec.indexOf("A" , 4) == -1); |
947 | } |
948 | |
949 | void tst_QVarLengthArray::lastIndexOf() |
950 | { |
951 | QVarLengthArray<QString> myvec; |
952 | myvec << "A" << "B" << "C" << "B" << "A" ; |
953 | |
954 | QVERIFY(myvec.lastIndexOf("B" ) == 3); |
955 | QVERIFY(myvec.lastIndexOf("B" , 2) == 1); |
956 | QVERIFY(myvec.lastIndexOf("X" ) == -1); |
957 | QVERIFY(myvec.lastIndexOf("X" , 2) == -1); |
958 | |
959 | // add an X |
960 | myvec << "X" ; |
961 | QVERIFY(myvec.lastIndexOf("X" ) == 5); |
962 | QVERIFY(myvec.lastIndexOf("X" , 5) == 5); |
963 | QVERIFY(myvec.lastIndexOf("X" , 3) == -1); |
964 | |
965 | // remove first A |
966 | myvec.remove(i: 0); |
967 | QVERIFY(myvec.lastIndexOf("A" ) == 3); |
968 | QVERIFY(myvec.lastIndexOf("A" , 3) == 3); |
969 | QVERIFY(myvec.lastIndexOf("A" , 2) == -1); |
970 | } |
971 | |
972 | void tst_QVarLengthArray::contains() |
973 | { |
974 | QVarLengthArray<QString> myvec; |
975 | myvec << "aaa" << "bbb" << "ccc" ; |
976 | |
977 | QVERIFY(myvec.contains(QLatin1String("aaa" ))); |
978 | QVERIFY(myvec.contains(QLatin1String("bbb" ))); |
979 | QVERIFY(myvec.contains(QLatin1String("ccc" ))); |
980 | QVERIFY(!myvec.contains(QLatin1String("I don't exist" ))); |
981 | |
982 | // add it and make sure it does :) |
983 | myvec.append(t: QLatin1String("I don't exist" )); |
984 | QVERIFY(myvec.contains(QLatin1String("I don't exist" ))); |
985 | } |
986 | |
987 | void tst_QVarLengthArray::clear() |
988 | { |
989 | QVarLengthArray<QString, 5> myvec; |
990 | |
991 | for (int i = 0; i < 10; ++i) |
992 | myvec << "aaa" ; |
993 | |
994 | QCOMPARE(myvec.size(), 10); |
995 | QVERIFY(myvec.capacity() >= myvec.size()); |
996 | const int oldCapacity = myvec.capacity(); |
997 | myvec.clear(); |
998 | QCOMPARE(myvec.size(), 0); |
999 | QCOMPARE(myvec.capacity(), oldCapacity); |
1000 | } |
1001 | |
1002 | void tst_QVarLengthArray::initializeListInt() |
1003 | { |
1004 | initializeList<int>(); |
1005 | } |
1006 | |
1007 | void tst_QVarLengthArray::initializeListMovable() |
1008 | { |
1009 | const int instancesCount = MyMovable::liveCount; |
1010 | initializeList<MyMovable>(); |
1011 | QCOMPARE(MyMovable::liveCount, instancesCount); |
1012 | } |
1013 | |
1014 | void tst_QVarLengthArray::initializeListComplex() |
1015 | { |
1016 | const int instancesCount = MyComplex::liveCount; |
1017 | initializeList<MyComplex>(); |
1018 | QCOMPARE(MyComplex::liveCount, instancesCount); |
1019 | } |
1020 | |
1021 | template<typename T> |
1022 | void tst_QVarLengthArray::initializeList() |
1023 | { |
1024 | T val1(110); |
1025 | T val2(105); |
1026 | T val3(101); |
1027 | T val4(114); |
1028 | |
1029 | // QVarLengthArray(std::initializer_list<>) |
1030 | QVarLengthArray<T> v1 {val1, val2, val3}; |
1031 | QCOMPARE(v1, QVarLengthArray<T>() << val1 << val2 << val3); |
1032 | QCOMPARE(v1, (QVarLengthArray<T> {val1, val2, val3})); |
1033 | |
1034 | QVarLengthArray<QVarLengthArray<T>, 4> v2{ v1, {val4}, QVarLengthArray<T>(), {val1, val2, val3} }; |
1035 | QVarLengthArray<QVarLengthArray<T>, 4> v3; |
1036 | v3 << v1 << (QVarLengthArray<T>() << val4) << QVarLengthArray<T>() << v1; |
1037 | QCOMPARE(v3, v2); |
1038 | |
1039 | QVarLengthArray<T> v4({}); |
1040 | QCOMPARE(v4.size(), 0); |
1041 | |
1042 | // operator=(std::initializer_list<>) |
1043 | |
1044 | QVarLengthArray<T> v5({val2, val1}); |
1045 | v1 = { val1, val2 }; // make array smaller |
1046 | v4 = { val1, val2 }; // make array bigger |
1047 | v5 = { val1, val2 }; // same size |
1048 | QCOMPARE(v1, QVarLengthArray<T>() << val1 << val2); |
1049 | QCOMPARE(v4, v1); |
1050 | QCOMPARE(v5, v1); |
1051 | |
1052 | QVarLengthArray<T, 1> v6 = { val1 }; |
1053 | v6 = { val1, val2 }; // force allocation on heap |
1054 | QCOMPARE(v6.size(), 2); |
1055 | QCOMPARE(v6.first(), val1); |
1056 | QCOMPARE(v6.last(), val2); |
1057 | |
1058 | v6 = {}; // assign empty |
1059 | QCOMPARE(v6.size(), 0); |
1060 | } |
1061 | |
1062 | void tst_QVarLengthArray::insertMove() |
1063 | { |
1064 | MyBase::errorCount = 0; |
1065 | QCOMPARE(MyBase::liveCount, 0); |
1066 | QCOMPARE(MyBase::copyCount, 0); |
1067 | |
1068 | { |
1069 | QVarLengthArray<MyMovable, 6> vec; |
1070 | MyMovable m1; |
1071 | MyMovable m2; |
1072 | MyMovable m3; |
1073 | MyMovable m4; |
1074 | MyMovable m5; |
1075 | MyMovable m6; |
1076 | QCOMPARE(MyBase::copyCount, 0); |
1077 | QCOMPARE(MyBase::liveCount, 6); |
1078 | |
1079 | vec.append(t: std::move(m3)); |
1080 | QVERIFY(m3.wasConstructedAt(nullptr)); |
1081 | QVERIFY(vec.at(0).wasConstructedAt(&m3)); |
1082 | QCOMPARE(MyBase::errorCount, 0); |
1083 | QCOMPARE(MyBase::liveCount, 6); |
1084 | QCOMPARE(MyBase::movedCount, 1); |
1085 | |
1086 | vec.push_back(t: std::move(m4)); |
1087 | QVERIFY(m4.wasConstructedAt(nullptr)); |
1088 | QVERIFY(vec.at(0).wasConstructedAt(&m3)); |
1089 | QVERIFY(vec.at(1).wasConstructedAt(&m4)); |
1090 | QCOMPARE(MyBase::errorCount, 0); |
1091 | QCOMPARE(MyBase::liveCount, 6); |
1092 | QCOMPARE(MyBase::movedCount, 2); |
1093 | |
1094 | vec.prepend(t: std::move(m1)); |
1095 | QVERIFY(m1.wasConstructedAt(nullptr)); |
1096 | QVERIFY(vec.at(0).wasConstructedAt(&m1)); |
1097 | QVERIFY(vec.at(1).wasConstructedAt(&m3)); |
1098 | QVERIFY(vec.at(2).wasConstructedAt(&m4)); |
1099 | QCOMPARE(MyBase::errorCount, 0); |
1100 | QCOMPARE(MyBase::liveCount, 6); |
1101 | QCOMPARE(MyBase::movedCount, 3); |
1102 | |
1103 | vec.insert(i: 1, t: std::move(m2)); |
1104 | QVERIFY(m2.wasConstructedAt(nullptr)); |
1105 | QVERIFY(vec.at(0).wasConstructedAt(&m1)); |
1106 | QVERIFY(vec.at(1).wasConstructedAt(&m2)); |
1107 | QVERIFY(vec.at(2).wasConstructedAt(&m3)); |
1108 | QVERIFY(vec.at(3).wasConstructedAt(&m4)); |
1109 | QCOMPARE(MyBase::errorCount, 0); |
1110 | QCOMPARE(MyBase::liveCount, 6); |
1111 | QCOMPARE(MyBase::movedCount, 4); |
1112 | |
1113 | vec += std::move(m5); |
1114 | QVERIFY(m5.wasConstructedAt(nullptr)); |
1115 | QVERIFY(vec.at(0).wasConstructedAt(&m1)); |
1116 | QVERIFY(vec.at(1).wasConstructedAt(&m2)); |
1117 | QVERIFY(vec.at(2).wasConstructedAt(&m3)); |
1118 | QVERIFY(vec.at(3).wasConstructedAt(&m4)); |
1119 | QVERIFY(vec.at(4).wasConstructedAt(&m5)); |
1120 | QCOMPARE(MyBase::errorCount, 0); |
1121 | QCOMPARE(MyBase::liveCount, 6); |
1122 | QCOMPARE(MyBase::movedCount, 5); |
1123 | |
1124 | vec << std::move(m6); |
1125 | QVERIFY(m6.wasConstructedAt(nullptr)); |
1126 | QVERIFY(vec.at(0).wasConstructedAt(&m1)); |
1127 | QVERIFY(vec.at(1).wasConstructedAt(&m2)); |
1128 | QVERIFY(vec.at(2).wasConstructedAt(&m3)); |
1129 | QVERIFY(vec.at(3).wasConstructedAt(&m4)); |
1130 | QVERIFY(vec.at(4).wasConstructedAt(&m5)); |
1131 | QVERIFY(vec.at(5).wasConstructedAt(&m6)); |
1132 | |
1133 | QCOMPARE(MyBase::copyCount, 0); |
1134 | QCOMPARE(MyBase::liveCount, 6); |
1135 | QCOMPARE(MyBase::errorCount, 0); |
1136 | QCOMPARE(MyBase::movedCount, 6); |
1137 | } |
1138 | QCOMPARE(MyBase::liveCount, 0); |
1139 | QCOMPARE(MyBase::errorCount, 0); |
1140 | QCOMPARE(MyBase::movedCount, 0); |
1141 | } |
1142 | |
1143 | void tst_QVarLengthArray::nonCopyable() |
1144 | { |
1145 | QVarLengthArray<std::unique_ptr<int>> vec; |
1146 | std::unique_ptr<int> val1(new int(1)); |
1147 | std::unique_ptr<int> val2(new int(2)); |
1148 | std::unique_ptr<int> val3(new int(3)); |
1149 | std::unique_ptr<int> val4(new int(4)); |
1150 | std::unique_ptr<int> val5(new int(5)); |
1151 | std::unique_ptr<int> val6(new int(6)); |
1152 | int *const ptr1 = val1.get(); |
1153 | int *const ptr2 = val2.get(); |
1154 | int *const ptr3 = val3.get(); |
1155 | int *const ptr4 = val4.get(); |
1156 | int *const ptr5 = val5.get(); |
1157 | int *const ptr6 = val6.get(); |
1158 | |
1159 | vec.append(t: std::move(val3)); |
1160 | QVERIFY(!val3); |
1161 | QVERIFY(ptr3 == vec.at(0).get()); |
1162 | vec.append(t: std::move(val4)); |
1163 | QVERIFY(!val4); |
1164 | QVERIFY(ptr3 == vec.at(0).get()); |
1165 | QVERIFY(ptr4 == vec.at(1).get()); |
1166 | vec.prepend(t: std::move(val1)); |
1167 | QVERIFY(!val1); |
1168 | QVERIFY(ptr1 == vec.at(0).get()); |
1169 | QVERIFY(ptr3 == vec.at(1).get()); |
1170 | QVERIFY(ptr4 == vec.at(2).get()); |
1171 | vec.insert(i: 1, t: std::move(val2)); |
1172 | QVERIFY(!val2); |
1173 | QVERIFY(ptr1 == vec.at(0).get()); |
1174 | QVERIFY(ptr2 == vec.at(1).get()); |
1175 | QVERIFY(ptr3 == vec.at(2).get()); |
1176 | QVERIFY(ptr4 == vec.at(3).get()); |
1177 | vec += std::move(val5); |
1178 | QVERIFY(!val5); |
1179 | QVERIFY(ptr1 == vec.at(0).get()); |
1180 | QVERIFY(ptr2 == vec.at(1).get()); |
1181 | QVERIFY(ptr3 == vec.at(2).get()); |
1182 | QVERIFY(ptr4 == vec.at(3).get()); |
1183 | QVERIFY(ptr5 == vec.at(4).get()); |
1184 | vec << std::move(val6); |
1185 | QVERIFY(!val6); |
1186 | QVERIFY(ptr1 == vec.at(0).get()); |
1187 | QVERIFY(ptr2 == vec.at(1).get()); |
1188 | QVERIFY(ptr3 == vec.at(2).get()); |
1189 | QVERIFY(ptr4 == vec.at(3).get()); |
1190 | QVERIFY(ptr5 == vec.at(4).get()); |
1191 | QVERIFY(ptr6 == vec.at(5).get()); |
1192 | } |
1193 | |
1194 | void tst_QVarLengthArray::implicitDefaultCtor() |
1195 | { |
1196 | QVarLengthArray<int> def = {}; |
1197 | QCOMPARE(def.size(), 0); |
1198 | } |
1199 | |
1200 | QTEST_APPLESS_MAIN(tst_QVarLengthArray) |
1201 | #include "tst_qvarlengtharray.moc" |
1202 | |