1/****************************************************************************
2**
3** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt3D module 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 <QObject>
30#include <QtTest/QtTest>
31
32#include <Qt3DCore/private/qcircularbuffer_p.h>
33
34using namespace Qt3DCore;
35
36class tst_QCircularBuffer : public QObject
37{
38 Q_OBJECT
39private Q_SLOTS:
40 void construction();
41 void destruction();
42
43 void append();
44 void at();
45 void capacity();
46 void clear();
47 void contains();
48 void count();
49 void data();
50 void dataOneTwo();
51 void endsWith();
52 void erase();
53 void fill();
54 void first();
55 void fromList();
56 void fromVector();
57 void indexOf();
58 void insert();
59 void insertIterator();
60 void isEmpty();
61 void isFull();
62 void isLinearised();
63 void last();
64 void lastIndexOf();
65 void linearise();
66 void prepend();
67 void sharable();
68
69 void removeStaticLinearised();
70 void removeStaticNonLinearised();
71 void removeMovableLinearised();
72 void removeMovableNonLinearisedUpper();
73 void removeMovableNonLinearisedLower();
74
75 void replace();
76 void resize();
77
78 void setCapacityStatic();
79 void setCapacityMovable();
80
81 void size();
82 void sizeAvailable();
83 void startsWith();
84 void toList();
85 void toVector();
86 void value();
87
88 void operatorEquality();
89 void operatorInequality();
90 void operatorPlus();
91 void operatorPlusEquals();
92 void operatorStream();
93
94 void const_iterator();
95 void iterator();
96
97 void testAppendFifo();
98};
99
100class MyComplexType
101{
102public:
103 MyComplexType(int xx = 0)
104 : x(xx),
105 magicCheck(ms_magic)
106 {
107 ++ms_activeCount;
108 }
109
110 MyComplexType(const MyComplexType &other)
111 : x(other.x),
112 magicCheck(other.magicCheck)
113 {
114 ++ms_activeCount;
115 }
116
117 ~MyComplexType()
118 {
119 // Check that the constructor was actually called
120 QVERIFY(ms_magic == magicCheck);
121 --ms_activeCount;
122 }
123
124 MyComplexType &operator=(const MyComplexType &other)
125 {
126 if (this == &other)
127 return *this;
128 x = other.x;
129 magicCheck = other.magicCheck;
130 return *this;
131 }
132
133 int x;
134 int magicCheck;
135
136 static const int ms_magic = 0xfefefefe;
137 static int ms_activeCount;
138};
139
140int MyComplexType::ms_activeCount = 0;
141
142void tst_QCircularBuffer::construction()
143{
144 // Create an empty circular buffer
145 QCircularBuffer<int> circ1;
146 QVERIFY(circ1.capacity() == 0);
147 QVERIFY(circ1.size() == 0);
148
149 // Create a circular buffer with capacity for 10 items
150 QCircularBuffer<int> circ2(10);
151 QVERIFY(circ2.capacity() == 10);
152
153 // Create a circular buffer with capacity for 3 items, all of which
154 // are initialised to a specific value
155 QCircularBuffer<int> circ3(3, 69);
156 QVERIFY(circ3.capacity() == 3);
157 QVERIFY(circ3.size() == 3);
158 QVERIFY(circ3.at(0) == 69);
159 QVERIFY(circ3.at(1) == 69);
160 QVERIFY(circ3.at(2) == 69);
161
162 // Create a circular buffer with capacity for 5 items. Pre-populate the
163 // first 2 items to a known value.
164 QCircularBuffer<int> circ4(5, 2, 10);
165 QVERIFY(circ4.capacity() == 5);
166 QVERIFY(circ4.size() == 2);
167 QVERIFY(circ4.at(0) == 10);
168 QVERIFY(circ4.at(1) == 10);
169 QVERIFY(circ4.refCount().loadRelaxed() == 1);
170
171 // Copy construct from circ4. Both circ4 and circ5 should now have a
172 // refCount() of 2 since we are using implicit sharing.
173 QCircularBuffer<int> circ5(circ4);
174 QVERIFY(circ4.refCount().loadRelaxed() == 2);
175 QVERIFY(circ5.refCount().loadRelaxed() == 2);
176 QVERIFY(circ5.capacity() == 5);
177 QVERIFY(circ5.size() == 2);
178 QVERIFY(circ5.at(0) == 10);
179 QVERIFY(circ5.at(1) == 10);
180}
181
182void tst_QCircularBuffer::destruction()
183{
184 // Make sure that we only call the dtor for items that
185 // have actually been constructed. There was a bug where we
186 // were accidentally calling the dtor for all items in the
187 // memory block (d->capacity items) rather than constructed
188 // items (d->size items). The complex dtor of QVector showed
189 // this up nicely with a crash. So now we test for this, but
190 // in a non-crashy manner.
191
192 // Reset the count of active (constructed items)
193 MyComplexType::ms_activeCount = 0;
194
195 // Populate a circular buffer and remove an item. The check
196 // in the dtor makes sure that the item was constructed
197 QCircularBuffer<MyComplexType> *cir = new QCircularBuffer<MyComplexType>(8);
198 cir->append(val: MyComplexType(1));
199 cir->append(val: MyComplexType(2));
200 cir->append(val: MyComplexType(3));
201 cir->remove(i: 0);
202 Q_UNUSED(cir)
203
204 // Check that the dtor was called 2 times fewer than the constructor.
205 // At this stage will still have 2 items in the circular buffer.
206 QVERIFY(MyComplexType::ms_activeCount == 2);
207
208 // Destroy the circular buffer and check that the active count
209 // is 0. (Same number of calls to dtor as have been made to the constructors)
210 delete cir;
211 cir = nullptr;
212 QVERIFY(MyComplexType::ms_activeCount == 0);
213}
214
215void tst_QCircularBuffer::append()
216{
217 // Create a circular buffer with capacity for 3 items
218 QCircularBuffer<int> circ(3);
219
220 // Append some items
221 circ.append(val: 1);
222 circ.append(val: 2);
223 circ.append(val: 3);
224
225 // The buffer should now contain the items 1, 2, 3 and be full
226 QVERIFY(circ.at(0) == 1);
227 QVERIFY(circ.at(1) == 2);
228 QVERIFY(circ.at(2) == 3);
229 QVERIFY(circ.isFull() == true);
230
231 // Although the buffer is full we can still append items to it.
232 // The earliest items will be overwritten
233 circ.append(val: 4);
234 circ.append(val: 5);
235
236 // The buffer should now contain the items 3, 4, 5 and still be full
237 QVERIFY(circ.at(0) == 3);
238 QVERIFY(circ.at(1) == 4);
239 QVERIFY(circ.at(2) == 5);
240 QVERIFY(circ.isFull() == true);
241
242 // Try appending beyond when the buffer becomes non-linearised
243 QCircularBuffer<int> circ2(10);
244 for (int i = 0; i < 15; ++i)
245 circ2.append(val: i + 1);
246 for (int i = 0; i < circ2.size(); ++i)
247 QVERIFY(circ2.at(i) == 6 + i);
248}
249
250void tst_QCircularBuffer::at()
251{
252 QCircularBuffer<int> circ(3, 10);
253 QVERIFY(circ.at(0) == 10);
254 QVERIFY(circ.at(1) == 10);
255 QVERIFY(circ.at(2) == 10);
256
257 circ.append(val: 20);
258 QVERIFY(circ.at(2) == 20);
259}
260
261void tst_QCircularBuffer::capacity()
262{
263 QCircularBuffer<int> circ(10);
264 QVERIFY(circ.capacity() == 10);
265}
266
267void tst_QCircularBuffer::clear()
268{
269 QCircularBuffer<int> circ(3, 10);
270 QVERIFY(circ.size() == 3);
271 QVERIFY(circ.capacity() == 3);
272
273 circ.clear();
274 QVERIFY(circ.size() == 0);
275 QVERIFY(circ.capacity() == 3);
276 QVERIFY(circ.refCount().loadRelaxed() == 1);
277}
278
279void tst_QCircularBuffer::contains()
280{
281 // Try simple test with a linearised buffer
282 QCircularBuffer<int> circ(5);
283 circ.append(val: 1);
284 circ.append(val: 2);
285 circ.append(val: 3);
286 circ.append(val: 4);
287 QVERIFY(circ.isLinearised() == true);
288 QVERIFY(circ.contains(2) == true);
289 QVERIFY(circ.contains(5) == false);
290
291 // Now append some more items to make the buffer non-linearised and
292 // test again.
293 circ.append(val: 5);
294 circ.append(val: 6);
295 circ.append(val: 7);
296 QVERIFY(circ.isLinearised() == false);
297 QVERIFY(circ.contains(6) == true);
298 QVERIFY(circ.contains(7) == true);
299 QVERIFY(circ.contains(8) == false);
300}
301
302void tst_QCircularBuffer::count()
303{
304 // Test both versions of count() with a linearised buffer
305 QCircularBuffer<int> circ(5);
306 circ.append(val: 1);
307 circ.append(val: 2);
308 circ.append(val: 3);
309 circ.append(val: 4);
310 circ.append(val: 4);
311
312 QVERIFY(circ.isLinearised() == true);
313 QVERIFY(circ.count() == 5);
314 QVERIFY(circ.count(4) == 2);
315
316 // Now with an non-linearised buffer
317 circ.append(val: 4);
318 circ.append(val: 4);
319 QVERIFY(circ.isLinearised() == false);
320 QVERIFY(circ.count() == 5);
321 QVERIFY(circ.count(4) == 4);
322}
323
324void tst_QCircularBuffer::data()
325{
326 //
327 // data() and constData() tests
328 //
329
330 // Test with a simple linearised buffer first
331 QCircularBuffer<int> circ(5);
332 circ.append(val: 1);
333 circ.append(val: 2);
334 circ.append(val: 3);
335 circ.append(val: 4);
336 circ.append(val: 5);
337
338 QCircularBuffer<int>::array_range range = circ.data();
339 int *p = range.first;
340 QVERIFY(range.second == 5);
341 for (int i = 0; i < range.second; ++i)
342 QVERIFY(p[ i ] == i + 1);
343
344 // Now with an non-linearised one. Note that the non-const version will
345 // linearise the buffer.
346 circ.append(val: 6);
347 circ.append(val: 7);
348 QVERIFY(circ.isLinearised() == false);
349 range = circ.data();
350 p = range.first;
351 QVERIFY(range.second == 5);
352 for (int i = 0; i < range.second; ++i)
353 QVERIFY(p[ i ] == i + 3);
354 QVERIFY(circ.isLinearised() == true);
355
356 // Let's repeat the exercise with the const version of the data function
357 QCircularBuffer<int> circ2(5);
358 circ2.append(val: 1);
359 circ2.append(val: 2);
360 circ2.append(val: 3);
361 circ2.append(val: 4);
362 circ2.append(val: 5);
363
364 QCircularBuffer<int>::const_array_range range2 = const_cast<const QCircularBuffer<int> *>(&circ2)->data();
365 const int *p2 = range2.first;
366 for (int i = 0; i < range2.second; ++i)
367 QVERIFY(p2[ i ] == i + 1);
368
369 // We should get a null pointer for a non-linearised buffer
370 circ2.append(val: 6);
371 circ2.append(val: 7);
372 QVERIFY(circ2.isLinearised() == false);
373 range2 = const_cast<const QCircularBuffer<int> *>(&circ2)->data();
374 QVERIFY(range2.first == 0);
375 QVERIFY(range2.second == 0);
376
377 // Let's repeat the exercise with the constData function
378 QCircularBuffer<int> circ3(5);
379 circ3.append(val: 1);
380 circ3.append(val: 2);
381 circ3.append(val: 3);
382 circ3.append(val: 4);
383 circ3.append(val: 5);
384
385 QCircularBuffer<int>::const_array_range range3 = circ3.constData();
386 const int *p3 = range3.first;
387 for (int i = 0; i < range3.second; ++i)
388 QVERIFY(p3[ i ] == i + 1);
389
390 // We should get a null pointer for a non-linearised buffer
391 circ3.append(val: 6);
392 circ3.append(val: 7);
393 QVERIFY(circ3.isLinearised() == false);
394 range3 = circ3.constData();
395 QVERIFY(range3.first == 0);
396 QVERIFY(range3.second == 0);
397}
398
399void tst_QCircularBuffer::dataOneTwo()
400{
401 // Start off with a linearised buffer
402 QCircularBuffer<int> circ(5);
403 circ.append(val: 1);
404 circ.append(val: 2);
405 circ.append(val: 3);
406 circ.append(val: 4);
407 circ.append(val: 5);
408
409 QCircularBuffer<int>::array_range range = circ.dataOne();
410 int *p = range.first;
411 QVERIFY(range.second == 5);
412 for (int i = 0; i < range.second; ++i)
413 QVERIFY(p[ i ] == i + 1);
414
415 // Test the const version too
416 QCircularBuffer<int>::const_array_range constRange = const_cast< const QCircularBuffer<int> *>(&circ)->dataOne();
417 const int *constp = constRange.first;
418 QVERIFY(constRange.second == 5);
419 for (int i = 0; i < constRange.second; ++i)
420 QVERIFY(constp[ i ] == i + 1);
421
422 // And the constDataOne() function
423 constRange = circ.constDataOne();
424 constp = constRange.first;
425 QVERIFY(constRange.second == 5);
426 for (int i = 0; i < constRange.second; ++i)
427 QVERIFY(constp[ i ] == i + 1);
428
429 // dataTwo should return a null array when the buffer is linearised
430 QCircularBuffer<int>::array_range rangeb = circ.dataTwo();
431 QVERIFY(rangeb.first == 0);
432 QVERIFY(rangeb.second == 0);
433
434 // Test the const version too
435 QCircularBuffer<int>::const_array_range constRangeb = const_cast< const QCircularBuffer<int> *>(&circ)->dataTwo();
436 QVERIFY(constRangeb.first == 0);
437 QVERIFY(constRangeb.second == 0);
438
439 // And the constDataTwo() function
440 constRangeb = circ.constDataTwo();
441 QVERIFY(constRangeb.first == 0);
442 QVERIFY(constRangeb.second == 0);
443
444 // Now make the buffer non-linearised by adding more items
445 circ.append(val: 6);
446 circ.append(val: 7);
447 QVERIFY(circ.isLinearised() == false);
448
449 // dataOne() should return the first contiguous part of the array
450 range = circ.dataOne();
451 p = range.first;
452 QVERIFY(range.second == 3);
453 for (int i = 0; i < range.second; ++i)
454 QVERIFY(p[ i ] == i + 3);
455 QVERIFY(circ.isLinearised() == false);
456
457 // Test the const version too
458 constRange = const_cast< const QCircularBuffer<int> *>(&circ)->dataOne();
459 constp = constRange.first;
460 QVERIFY(constRange.second == 3);
461 for (int i = 0; i < constRange.second; ++i)
462 QVERIFY(constp[ i ] == i + 3);
463 QVERIFY(circ.isLinearised() == false);
464
465 // And the constDataOne() function
466 constRange = circ.constDataOne();
467 constp = constRange.first;
468 QVERIFY(constRange.second == 3);
469 for (int i = 0; i < constRange.second; ++i)
470 QVERIFY(constp[ i ] == i + 3);
471 QVERIFY(circ.isLinearised() == false);
472
473 // dataTwo should return the second contiguous part of the array
474 rangeb = circ.dataTwo();
475 QVERIFY(rangeb.second == 2);
476 int *pb = rangeb.first;
477 for (int i = 0; i < rangeb.second; ++i)
478 QVERIFY(pb[ i ] == i + 6);
479 QVERIFY(circ.isLinearised() == false);
480
481 // Test the const version too
482 constRangeb = const_cast< const QCircularBuffer<int> *>(&circ)->dataTwo();
483 QVERIFY(constRangeb.second == 2);
484 const int *constpb = constRangeb.first;
485 for (int i = 0; i < constRangeb.second; ++i)
486 QVERIFY(constpb[ i ] == i + 6);
487 QVERIFY(circ.isLinearised() == false);
488
489 // And finally, the constDataTwo() function.
490 constRangeb = circ.constDataTwo();
491 QVERIFY(constRangeb.second == 2);
492 constpb = constRangeb.first;
493 for (int i = 0; i < constRangeb.second; ++i)
494 QVERIFY(constpb[ i ] == i + 6);
495 QVERIFY(circ.isLinearised() == false);
496}
497
498void tst_QCircularBuffer::endsWith()
499{
500 // Test with a linearised buffer
501 QCircularBuffer<int> circ(5);
502 circ.append(val: 1);
503 circ.append(val: 2);
504 circ.append(val: 3);
505 circ.append(val: 4);
506 circ.append(val: 5);
507 QVERIFY(circ.endsWith(5) == true);
508 QVERIFY(circ.endsWith(3) == false);
509
510 // Now with a non-linearised buffer
511 circ.append(val: 6);
512 circ.append(val: 7);
513 QVERIFY(circ.endsWith(7) == true);
514 QVERIFY(circ.endsWith(3) == false);
515
516 // Now with an empty buffer
517 QCircularBuffer<int> circ2(1);
518 QVERIFY(!circ2.endsWith(1));
519 circ2.append(val: 1);
520 QVERIFY(circ2.endsWith(1));
521 circ2.erase(pos: circ2.begin());
522 QVERIFY(!circ2.endsWith(1));
523}
524
525void tst_QCircularBuffer::erase()
526{
527 QCircularBuffer<int> circ(10);
528 for (int i = 0; i < circ.capacity(); ++i)
529 circ.append(val: i + 1);
530
531 QCircularBuffer<int>::iterator pos = circ.begin() + 2;
532 QCircularBuffer<int>::iterator it = circ.erase(pos);
533
534 QVERIFY(circ.size() == circ.capacity() - 1);
535 for (int i = 0; i < circ.size(); ++i) {
536 if (i < 2)
537 QVERIFY(circ.at(i) == i + 1);
538 else
539 QVERIFY(circ.at(i) == i + 2);
540 }
541
542 QVERIFY(*it == 4);
543
544 QCircularBuffer<int>::iterator start = circ.begin() + 2;
545 QCircularBuffer<int>::iterator end = circ.end();
546 it = circ.erase(b: start, e: end);
547 QVERIFY(circ.size() == 2);
548 QVERIFY(circ.at(0) == 1);
549 QVERIFY(circ.at(1) == 2);
550 QVERIFY(it == circ.end());
551}
552
553void tst_QCircularBuffer::fill()
554{
555 QCircularBuffer<int> circ(5, 0);
556 circ.fill(val: 2);
557 QVERIFY(circ.capacity() == 5);
558 QVERIFY(circ.size() == 5);
559 for (int i = 0; i < 5; ++i)
560 QVERIFY(circ.at(i) == 2);
561
562 // Fill the first 3 entries with value 7
563 circ.fill(val: 7, number: 3);
564 QVERIFY(circ.capacity() == 5);
565 QVERIFY(circ.size() == 3);
566 for (int i = 0; i < 3; ++i)
567 QVERIFY(circ.at(i) == 7);
568
569 // We abuse the data pointer to check that values beyond the valid array
570 // have been reset when we resized down.
571 QCircularBuffer<int>::array_range range = circ.data();
572 QVERIFY(range.second == 3);
573 QVERIFY(range.first[ 3 ] == 0);
574 QVERIFY(range.first[ 4 ] == 0);
575}
576
577void tst_QCircularBuffer::first()
578{
579 QCircularBuffer<int> circ(3);
580 circ.append(val: 1);
581 circ.append(val: 2);
582 circ.append(val: 3);
583 QVERIFY(circ.at(0) == 1);
584 QVERIFY(circ.first() == 1);
585
586 circ.append(val: 4);
587 circ.append(val: 5);
588 QVERIFY(circ.first() == 3);
589}
590
591void tst_QCircularBuffer::fromList()
592{
593 QList<int> list = (QList<int>() << 1 << 2 << 3 << 4 << 5);
594 QCircularBuffer<int> circ = QCircularBuffer<int>::fromList(list);
595 QVERIFY(circ.capacity() == list.size());
596 QVERIFY(circ.size() == list.size());
597 QVERIFY(circ.isLinearised() == true);
598 for (int i = 0; i < circ.size(); ++i)
599 QVERIFY(circ.at(i) == list.at(i));
600}
601
602void tst_QCircularBuffer::fromVector()
603{
604 QVector<int> vector = (QVector<int>() << 1 << 2 << 3 << 4 << 5);
605 QCircularBuffer<int> circ = QCircularBuffer<int>::fromVector(vector);
606 QVERIFY(circ.capacity() == vector.size());
607 QVERIFY(circ.size() == vector.size());
608 QVERIFY(circ.isLinearised() == true);
609 for (int i = 0; i < circ.size(); ++i)
610 QVERIFY(circ.at(i) == vector.at(i));
611}
612
613void tst_QCircularBuffer::indexOf()
614{
615 QCircularBuffer<int> circ(5);
616 circ.append(val: 1);
617 circ.append(val: 2);
618 circ.append(val: 3);
619 circ.append(val: 2);
620 circ.append(val: 5);
621
622 QVERIFY(circ.indexOf(3) == 2);
623 QVERIFY(circ.indexOf(2) == 1);
624 QVERIFY(circ.indexOf(2, 2) == 3);
625
626 circ.append(val: 6);
627 circ.append(val: 6);
628 QVERIFY(circ.indexOf(2) == 1);
629 QVERIFY(circ.indexOf(6) == 3);
630 QVERIFY(circ.indexOf(6, 4) == 4);
631}
632
633void tst_QCircularBuffer::insert()
634{
635 // Try a simple insert in the upper part of the buffer
636 QCircularBuffer<MyComplexType> circ(8);
637 circ.append(val: 1);
638 circ.append(val: 2);
639 circ.append(val: 3);
640 circ.append(val: 4);
641 circ.append(val: 5);
642 circ.append(val: 6);
643
644 QVERIFY(circ.capacity() == 8);
645 QVERIFY(circ.size() == 6);
646
647 circ.insert(i: 4, number: 1, val: 0);
648 QVERIFY(circ.capacity() == 8);
649 QVERIFY(circ.size() == 7);
650 QVERIFY(circ.at(0).x == 1);
651 QVERIFY(circ.at(1).x == 2);
652 QVERIFY(circ.at(2).x == 3);
653 QVERIFY(circ.at(3).x == 4);
654 QVERIFY(circ.at(4).x == 0);
655 QVERIFY(circ.at(5).x == 5);
656 QVERIFY(circ.at(6).x == 6);
657
658 // Try a multiple insert in the upper part of the buffer
659 QCircularBuffer<MyComplexType> circ2(8);
660 circ2.append(val: 1);
661 circ2.append(val: 2);
662 circ2.append(val: 3);
663 circ2.append(val: 4);
664 circ2.append(val: 5);
665 circ2.append(val: 6);
666
667 QVERIFY(circ2.capacity() == 8);
668 QVERIFY(circ2.size() == 6);
669
670 circ2.insert(i: 4, number: 7, val: 0);
671 QVERIFY(circ2.capacity() == 8);
672 QVERIFY(circ2.size() == 8);
673 QVERIFY(circ2.at(0).x == 0);
674 QVERIFY(circ2.at(1).x == 0);
675 QVERIFY(circ2.at(2).x == 0);
676 QVERIFY(circ2.at(3).x == 0);
677 QVERIFY(circ2.at(4).x == 0);
678 QVERIFY(circ2.at(5).x == 0);
679 QVERIFY(circ2.at(6).x == 5);
680 QVERIFY(circ2.at(7).x == 6);
681
682 // Try a simple insert in the upper part of the buffer using a movable type.
683 // This tests the case where the part of the buffer to be moved up does not
684 // wrap around before or after the move.
685 QCircularBuffer<int> circ3(8);
686 circ3.append(val: 1);
687 circ3.append(val: 2);
688 circ3.append(val: 3);
689 circ3.append(val: 4);
690 circ3.append(val: 5);
691 circ3.append(val: 6);
692
693 circ3.insert(i: 4, number: 1, val: 0);
694 QVERIFY(circ3.capacity() == 8);
695 QVERIFY(circ3.size() == 7);
696 QVERIFY(circ3.at(0) == 1);
697 QVERIFY(circ3.at(1) == 2);
698 QVERIFY(circ3.at(2) == 3);
699 QVERIFY(circ3.at(3) == 4);
700 QVERIFY(circ3.at(4) == 0);
701 QVERIFY(circ3.at(5) == 5);
702 QVERIFY(circ3.at(6) == 6);
703
704 // Do the same again but this time such that the destination buffer wraps around.
705 QCircularBuffer<int> circ4(8);
706 circ4.append(val: 1);
707 circ4.append(val: 2);
708 circ4.append(val: 3);
709 circ4.append(val: 4);
710 circ4.append(val: 5);
711 circ4.append(val: 6);
712
713 circ4.insert(i: 4, number: 3, val: 0);
714 QVERIFY(circ4.capacity() == 8);
715 QVERIFY(circ4.size() == 8);
716 QVERIFY(circ4.at(0) == 2);
717 QVERIFY(circ4.at(1) == 3);
718 QVERIFY(circ4.at(2) == 4);
719 QVERIFY(circ4.at(3) == 0);
720 QVERIFY(circ4.at(4) == 0);
721 QVERIFY(circ4.at(5) == 0);
722 QVERIFY(circ4.at(6) == 5);
723 QVERIFY(circ4.at(7) == 6);
724
725 // And now when the src buffer wraps
726 QCircularBuffer<int> circ5(8);
727 circ5.append(val: 1);
728 circ5.append(val: 2);
729 circ5.append(val: 3);
730 circ5.append(val: 4);
731 circ5.append(val: 5);
732 circ5.append(val: 6);
733 circ5.append(val: 7);
734 circ5.append(val: 8);
735 circ5.append(val: 9);
736 circ5.append(val: 10);
737
738 circ5.insert(i: 4, number: 3, val: 0);
739 QVERIFY(circ5.capacity() == 8);
740 QVERIFY(circ5.size() == 8);
741 QVERIFY(circ5.at(0) == 6);
742 QVERIFY(circ5.at(1) == 0);
743 QVERIFY(circ5.at(2) == 0);
744 QVERIFY(circ5.at(3) == 0);
745 QVERIFY(circ5.at(4) == 7);
746 QVERIFY(circ5.at(5) == 8);
747 QVERIFY(circ5.at(6) == 9);
748 QVERIFY(circ5.at(7) == 10);
749
750 // Finally when both src and dst buffers wrap
751 QCircularBuffer<int> circ6(10);
752 circ6.append(val: 1);
753 circ6.append(val: 2);
754 circ6.append(val: 3);
755 circ6.append(val: 4);
756 circ6.append(val: 5);
757 circ6.append(val: 6);
758 circ6.append(val: 7);
759 circ6.append(val: 8);
760 circ6.append(val: 9);
761 circ6.append(val: 10);
762 circ6.append(val: 11);
763 circ6.append(val: 12);
764
765 circ6.insert(i: 5, number: 2, val: 0);
766 QVERIFY(circ6.capacity() == 10);
767 QVERIFY(circ6.size() == 10);
768 QVERIFY(circ6.at(0) == 5);
769 QVERIFY(circ6.at(1) == 6);
770 QVERIFY(circ6.at(2) == 7);
771 QVERIFY(circ6.at(3) == 0);
772 QVERIFY(circ6.at(4) == 0);
773 QVERIFY(circ6.at(5) == 8);
774 QVERIFY(circ6.at(6) == 9);
775 QVERIFY(circ6.at(7) == 10);
776 QVERIFY(circ6.at(8) == 11);
777 QVERIFY(circ6.at(9) == 12);
778
779
780 // Try a simple insert in the lower part of the buffer
781 QCircularBuffer<MyComplexType> circ7(8);
782 circ7.append(val: 1);
783 circ7.append(val: 2);
784 circ7.append(val: 3);
785 circ7.append(val: 4);
786 circ7.append(val: 5);
787 circ7.append(val: 6);
788
789 QVERIFY(circ7.capacity() == 8);
790 QVERIFY(circ7.size() == 6);
791
792 circ7.insert(i: 1, number: 1, val: 0);
793 QVERIFY(circ7.capacity() == 8);
794 QVERIFY(circ7.size() == 7);
795 QVERIFY(circ7.at(0).x == 1);
796 QVERIFY(circ7.at(1).x == 0);
797 QVERIFY(circ7.at(2).x == 2);
798 QVERIFY(circ7.at(3).x == 3);
799 QVERIFY(circ7.at(4).x == 4);
800 QVERIFY(circ7.at(5).x == 5);
801 QVERIFY(circ7.at(6).x == 6);
802
803 // Try a multiple insert in the lower part of the buffer
804 QCircularBuffer<MyComplexType> circ8(8);
805 circ8.append(val: 1);
806 circ8.append(val: 2);
807 circ8.append(val: 3);
808 circ8.append(val: 4);
809 circ8.append(val: 5);
810 circ8.append(val: 6);
811
812 QVERIFY(circ8.capacity() == 8);
813 QVERIFY(circ8.size() == 6);
814
815 circ8.insert(i: 1, number: 4, val: 0);
816 QVERIFY(circ8.capacity() == 8);
817 QVERIFY(circ8.size() == 8);
818 QVERIFY(circ8.at(0).x == 0);
819 QVERIFY(circ8.at(1).x == 0);
820 QVERIFY(circ8.at(2).x == 0);
821 QVERIFY(circ8.at(3).x == 2);
822 QVERIFY(circ8.at(4).x == 3);
823 QVERIFY(circ8.at(5).x == 4);
824 QVERIFY(circ8.at(6).x == 5);
825 QVERIFY(circ8.at(7).x == 6);
826
827 // Try a simple insert in the lower part of the buffer using a movable type.
828 // This tests the case where the part of the buffer to be moved up does not
829 // wrap around before or after the move.
830 QCircularBuffer<int> circ9(10);
831 circ9.append(val: 1);
832 circ9.append(val: 2);
833 circ9.append(val: 3);
834 circ9.append(val: 4);
835 circ9.append(val: 5);
836 circ9.append(val: 6);
837 circ9.append(val: 7);
838 circ9.append(val: 8);
839 circ9.append(val: 9);
840
841 circ9.insert(i: 3, number: 2, val: 0);
842 QVERIFY(circ9.capacity() == 10);
843 QVERIFY(circ9.size() == 10);
844 QVERIFY(circ9.at(0) == 2);
845 QVERIFY(circ9.at(1) == 3);
846 QVERIFY(circ9.at(2) == 0);
847 QVERIFY(circ9.at(3) == 0);
848 QVERIFY(circ9.at(4) == 4);
849 QVERIFY(circ9.at(5) == 5);
850 QVERIFY(circ9.at(6) == 6);
851 QVERIFY(circ9.at(7) == 7);
852 QVERIFY(circ9.at(8) == 8);
853 QVERIFY(circ9.at(9) == 9);
854
855 // And now when the src buffer wraps
856 QCircularBuffer<int> circ10(10);
857 circ10.append(val: 3);
858 circ10.append(val: 4);
859 circ10.append(val: 5);
860 circ10.append(val: 6);
861 circ10.append(val: 7);
862 circ10.append(val: 8);
863 circ10.append(val: 9);
864 circ10.append(val: 10);
865 circ10.prepend(val: 2);
866 circ10.prepend(val: 1);
867
868 // Verify that the input buffer is as expected
869 QVERIFY(circ10.capacity() == 10);
870 QVERIFY(circ10.size() == 10);
871 QCircularBuffer<int>::const_array_range p2 = circ10.constDataTwo();
872 QVERIFY(p2.second == 8);
873 QVERIFY(p2.first[ 0 ] == 3);
874 QVERIFY(p2.first[ 1 ] == 4);
875 QVERIFY(p2.first[ 7 ] == 10);
876 QCircularBuffer<int>::const_array_range p = circ10.constDataOne();
877 QVERIFY(p.second == 2);
878 QVERIFY(p.first[ 0 ] == 1);
879 QVERIFY(p.first[ 1 ] == 2);
880
881 circ10.insert(i: 3, number: 1, val: 0);
882 QVERIFY(circ10.capacity() == 10);
883 QVERIFY(circ10.size() == 10);
884 QVERIFY(circ10.at(0) == 2);
885 QVERIFY(circ10.at(1) == 3);
886 QVERIFY(circ10.at(2) == 0);
887 QVERIFY(circ10.at(3) == 4);
888 QVERIFY(circ10.at(4) == 5);
889 QVERIFY(circ10.at(5) == 6);
890 QVERIFY(circ10.at(6) == 7);
891 QVERIFY(circ10.at(7) == 8);
892 QVERIFY(circ10.at(8) == 9);
893 QVERIFY(circ10.at(9) == 10);
894
895 // Finally when both src and dst buffers wrap
896 QCircularBuffer<int> circ11(13);
897 circ11.append(val: 4);
898 circ11.append(val: 5);
899 circ11.append(val: 6);
900 circ11.append(val: 7);
901 circ11.append(val: 8);
902 circ11.append(val: 9);
903 circ11.append(val: 10);
904 circ11.append(val: 11);
905 circ11.append(val: 12);
906 circ11.append(val: 13);
907 circ11.prepend(val: 3);
908 circ11.prepend(val: 2);
909 circ11.prepend(val: 1);
910
911 // Verify that the input buffer is as expected
912 QVERIFY(circ11.capacity() == 13);
913 QVERIFY(circ11.size() == 13);
914 p2 = circ11.constDataTwo();
915 QVERIFY(p2.second == 10);
916 QVERIFY(p2.first[ 0 ] == 4);
917 QVERIFY(p2.first[ 1 ] == 5);
918 QVERIFY(p2.first[ 9 ] == 13);
919 p = circ11.constDataOne();
920 QVERIFY(p.second == 3);
921 QVERIFY(p.first[ 0 ] == 1);
922 QVERIFY(p.first[ 1 ] == 2);
923 QVERIFY(p.first[ 2 ] == 3);
924
925 circ11.insert(i: 5, number: 1, val: 0);
926 QVERIFY(circ11.capacity() == 13);
927 QVERIFY(circ11.size() == 13);
928 QVERIFY(circ11.at(0) == 2);
929 QVERIFY(circ11.at(1) == 3);
930 QVERIFY(circ11.at(2) == 4);
931 QVERIFY(circ11.at(3) == 5);
932 QVERIFY(circ11.at(4) == 0);
933 QVERIFY(circ11.at(5) == 6);
934 QVERIFY(circ11.at(6) == 7);
935 QVERIFY(circ11.at(7) == 8);
936 QVERIFY(circ11.at(8) == 9);
937 QVERIFY(circ11.at(9) == 10);
938 QVERIFY(circ11.at(10) == 11);
939 QVERIFY(circ11.at(11) == 12);
940 QVERIFY(circ11.at(12) == 13);
941
942 // Try inserting at the end of the buffer. Should work just like append()
943 QCircularBuffer<int> circ12(10);
944 for (int i = 0; i < 5; ++i)
945 circ12.append(val: i + 1);
946 for (int i = 5; i < 10; ++i)
947 circ12.insert(i: circ12.size(), val: (i + 1) * 10);
948 for (int i = 0; i < circ12.size(); ++i) {
949 if (i < 5)
950 QVERIFY(circ12.at(i) == i + 1);
951 else
952 QVERIFY(circ12.at(i) == (i + 1) * 10);
953 }
954
955 // Try inserting at the end of the buffer with non-movable type. Should work just like append()
956 QCircularBuffer<MyComplexType> circ13(10);
957 for (int i = 0; i < 5; ++i)
958 circ13.append(val: i + 1);
959 for (int i = 5; i < 10; ++i)
960 circ13.insert(i: circ13.size(), val: (i + 1) * 10);
961 for (int i = 0; i < circ13.size(); ++i) {
962 if (i < 5)
963 QVERIFY(circ13.at(i).x == i + 1);
964 else
965 QVERIFY(circ13.at(i).x == (i + 1) * 10);
966 }
967
968 // Insert multiple items at end of buffer
969 QCircularBuffer<int> circ14(10);
970 for (int i = 0; i < 5; ++i)
971 circ14.append(val: i + 1);
972 circ14.insert(i: circ14.size(), number: 7, val: 100);
973 for (int i = 0; i < circ14.size(); ++i) {
974 if (i < 3)
975 QVERIFY(circ14.at(i) == i + 3);
976 else
977 QVERIFY(circ14.at(i) == 100);
978 }
979
980 // Insert multiple items at end of buffer of non-movable type
981 QCircularBuffer<MyComplexType> circ15(10);
982 for (int i = 0; i < 5; ++i)
983 circ15.append(val: i + 1);
984 circ15.insert(i: circ15.size(), number: 7, val: 100);
985 for (int i = 0; i < circ15.size(); ++i) {
986 if (i < 3)
987 QVERIFY(circ15.at(i).x == i + 3);
988 else
989 QVERIFY(circ15.at(i).x == 100);
990 }
991
992 // Try inserting at the start of the buffer. Should work just like prepend()
993 QCircularBuffer<int> circ16(10);
994 for (int i = 0; i < 5; ++i)
995 circ16.append(val: 10);
996 for (int i = 5; i < 10; ++i)
997 circ16.insert(i: 0, val: 20);
998 for (int i = 0; i < circ16.size(); ++i) {
999 if (i < 5)
1000 QVERIFY(circ16.at(i) == 20);
1001 else
1002 QVERIFY(circ16.at(i) == 10);
1003 }
1004
1005 // Try inserting at the start of the buffer with non-movable type. Should work just like prepend()
1006 QCircularBuffer<MyComplexType> circ17(10);
1007 for (int i = 0; i < 5; ++i)
1008 circ17.append(val: 10);
1009 for (int i = 5; i < 10; ++i)
1010 circ17.insert(i: 0, val: 20);
1011 for (int i = 0; i < circ17.size(); ++i) {
1012 if (i < 5)
1013 QVERIFY(circ17.at(i).x == 20);
1014 else
1015 QVERIFY(circ17.at(i).x == 10);
1016 }
1017
1018 // Try inserting multiple items at the start of the buffer. Should work just like prepend()
1019 QCircularBuffer<int> circ18(10);
1020 for (int i = 0; i < 5; ++i)
1021 circ18.append(val: 10);
1022 circ18.insert(i: 0, number: 5, val: 20);
1023 for (int i = 0; i < circ18.size(); ++i) {
1024 if (i < 5)
1025 QVERIFY(circ18.at(i) == 20);
1026 else
1027 QVERIFY(circ18.at(i) == 10);
1028 }
1029
1030 // Try inserting multiple items at the start of the buffer. Should work just like prepend()
1031 QCircularBuffer<MyComplexType> circ19(10);
1032 for (int i = 0; i < 5; ++i)
1033 circ19.append(val: 10);
1034 circ19.insert(i: 0, number: 5, val: 20);
1035 for (int i = 0; i < circ19.size(); ++i) {
1036 if (i < 5)
1037 QVERIFY(circ19.at(i).x == 20);
1038 else
1039 QVERIFY(circ19.at(i).x == 10);
1040 }
1041}
1042
1043void tst_QCircularBuffer::insertIterator()
1044{
1045 // Test the overload of insert that take an iterator as opposed to an index
1046 QCircularBuffer<int> circ(10);
1047 for (int i = 0; i < 5; ++i)
1048 circ.append(val: i + 1);
1049
1050 QCircularBuffer<int>::iterator it = circ.begin() + 2;
1051 QCircularBuffer<int>::iterator it2 = circ.insert(before: it, number: 3, val: 10);
1052 for (int i = 0; i < circ.size(); ++i) {
1053 if (i < 2)
1054 QVERIFY(circ.at(i) == i + 1);
1055 else if (i > 4)
1056 QVERIFY(circ.at(i) == i - 2);
1057 else
1058 QVERIFY(circ.at(i) == 10);
1059 }
1060
1061 for (int i = 0; i < 3; ++i) {
1062 QVERIFY(*it2 == 10);
1063 ++it2;
1064 }
1065}
1066
1067void tst_QCircularBuffer::isEmpty()
1068{
1069 QCircularBuffer<int> circ(3);
1070 QVERIFY(circ.isEmpty() == true);
1071 circ.append(val: 1);
1072 circ.append(val: 2);
1073 QVERIFY(circ.isEmpty() == false);
1074 circ.clear();
1075 QVERIFY(circ.isEmpty() == true);
1076}
1077
1078void tst_QCircularBuffer::isFull()
1079{
1080 QCircularBuffer<int> circ(3);
1081 QVERIFY(circ.isFull() == false);
1082 circ.append(val: 1);
1083 QVERIFY(circ.isFull() == false);
1084 circ.append(val: 2);
1085 QVERIFY(circ.isFull() == false);
1086 circ.append(val: 3);
1087 QVERIFY(circ.isFull() == true);
1088 circ.clear();
1089 QVERIFY(circ.isFull() == false);
1090}
1091
1092void tst_QCircularBuffer::isLinearised()
1093{
1094 QCircularBuffer<int> circ(3);
1095 QVERIFY(circ.isLinearised() == true);
1096 circ.append(val: 1);
1097 QVERIFY(circ.isLinearised() == true);
1098 circ.append(val: 2);
1099 QVERIFY(circ.isLinearised() == true);
1100 circ.append(val: 3);
1101 QVERIFY(circ.isLinearised() == true);
1102 circ.append(val: 4);
1103 QVERIFY(circ.isLinearised() == false);
1104 circ.clear();
1105 QVERIFY(circ.isLinearised() == true);
1106}
1107
1108void tst_QCircularBuffer::last()
1109{
1110 QCircularBuffer<int> circ(3);
1111 circ.append(val: 1);
1112 circ.append(val: 2);
1113 circ.append(val: 3);
1114 QVERIFY(circ.at(2) == 3);
1115 QVERIFY(circ.last() == 3);
1116
1117 circ.append(val: 4);
1118 circ.append(val: 5);
1119 QVERIFY(circ.last() == 5);
1120}
1121
1122void tst_QCircularBuffer::lastIndexOf()
1123{
1124 QCircularBuffer<int> circ(5);
1125 circ.append(val: 1);
1126 circ.append(val: 2);
1127 circ.append(val: 3);
1128 circ.append(val: 2);
1129 circ.append(val: 5);
1130
1131 QVERIFY(circ.lastIndexOf(3) == 2);
1132 QVERIFY(circ.lastIndexOf(2) == 3);
1133 QVERIFY(circ.lastIndexOf(2, 2) == 1);
1134
1135 circ.append(val: 6);
1136 QVERIFY(circ.lastIndexOf(2) == 2);
1137 QVERIFY(circ.lastIndexOf(6) == 4);
1138 QVERIFY(circ.lastIndexOf(2, 1) == 0);
1139}
1140
1141void tst_QCircularBuffer::linearise()
1142{
1143 // Start with a linearised buffer
1144 QCircularBuffer<int> circ(5);
1145 circ.append(val: 1);
1146 circ.append(val: 2);
1147 circ.append(val: 3);
1148 circ.append(val: 4);
1149 circ.append(val: 5);
1150 QVERIFY(circ.isLinearised() == true);
1151
1152 // Add more items to make it non-linearised
1153 circ.append(val: 6);
1154 circ.append(val: 7);
1155 QVERIFY(circ.isLinearised() == false);
1156 QVERIFY(circ.at(0) == 3);
1157 QVERIFY(circ.at(1) == 4);
1158 QVERIFY(circ.at(2) == 5);
1159 QVERIFY(circ.at(3) == 6);
1160 QVERIFY(circ.at(4) == 7);
1161
1162 // Now try to linearise it again
1163 circ.linearise();
1164 QVERIFY(circ.isLinearised() == true);
1165 QVERIFY(circ.at(0) == 3);
1166 QVERIFY(circ.at(1) == 4);
1167 QVERIFY(circ.at(2) == 5);
1168 QVERIFY(circ.at(3) == 6);
1169 QVERIFY(circ.at(4) == 7);
1170}
1171
1172void tst_QCircularBuffer::prepend()
1173{
1174 // Create a circular buffer with capacity for 3 items
1175 QCircularBuffer<int> circ(3);
1176
1177 // Prepend some items
1178 circ.prepend(val: 1);
1179 circ.prepend(val: 2);
1180 circ.prepend(val: 3);
1181
1182 // The buffer should now contain the items 1, 2, 3 and be full
1183 QVERIFY(circ.at(0) == 3);
1184 QVERIFY(circ.at(1) == 2);
1185 QVERIFY(circ.at(2) == 1);
1186 QVERIFY(circ.isFull() == true);
1187
1188 // Although the buffer is full we can still prepend items to it.
1189 // The latest items will be overwritten
1190 circ.prepend(val: 4);
1191 circ.prepend(val: 5);
1192
1193 // The buffer should now contain the items 3, 4, 5 and still be full
1194 QVERIFY(circ.at(0) == 5);
1195 QVERIFY(circ.at(1) == 4);
1196 QVERIFY(circ.at(2) == 3);
1197 QVERIFY(circ.isFull() == true);
1198}
1199
1200void tst_QCircularBuffer::sharable()
1201{
1202 QCircularBuffer<int> circ(3);
1203
1204 circ.push_back(t: 1);
1205 circ.push_back(t: 2);
1206 circ.push_back(t: 3);
1207
1208 {
1209 // take a reference to internal data and remember the current value:
1210 int &oldValueRef = circ.first();
1211 const int oldValue = oldValueRef;
1212
1213 // make a copy of the container:
1214 const QCircularBuffer<int> c2 = circ;
1215
1216 // modify copied-from container:
1217 oldValueRef = -1;
1218
1219 // check that the copied-to container didn't change
1220 QEXPECT_FAIL("", "QCircularBuffer doesn't implement non-sharable state", Continue);
1221 QCOMPARE(c2.first(), oldValue);
1222 }
1223}
1224
1225void tst_QCircularBuffer::removeStaticLinearised()
1226{
1227 // Try some simple removes on a linearised buffer with a non-movable type
1228 QCircularBuffer<MyComplexType> circ(6);
1229 circ.append(val: 1);
1230 circ.append(val: 2);
1231 circ.append(val: 3);
1232 circ.append(val: 4);
1233 circ.append(val: 5);
1234 circ.append(val: 6);
1235
1236 QVERIFY(circ.capacity() == 6);
1237 QVERIFY(circ.size() == 6);
1238
1239 circ.remove(i: 4, number: 2);
1240 QVERIFY(circ.capacity() == 6);
1241 QVERIFY(circ.size() == 4);
1242 QVERIFY(circ.at(0).x == 1);
1243 QVERIFY(circ.at(1).x == 2);
1244 QVERIFY(circ.at(2).x == 3);
1245 QVERIFY(circ.at(3).x == 4);
1246
1247 // Restore the original
1248 circ.append(val: 5);
1249 circ.append(val: 6);
1250
1251 // Now try removing in the upper part of the buffer but not all the
1252 // way to the end of it
1253 circ.remove(i: 3, number: 1);
1254 QVERIFY(circ.capacity() == 6);
1255 QVERIFY(circ.size() == 5);
1256 QVERIFY(circ.at(0).x == 1);
1257 QVERIFY(circ.at(1).x == 2);
1258 QVERIFY(circ.at(2).x == 3);
1259 QVERIFY(circ.at(3).x == 5);
1260 QVERIFY(circ.at(4).x == 6);
1261
1262 // Restore the original
1263 circ.clear();
1264 circ.append(val: 1);
1265 circ.append(val: 2);
1266 circ.append(val: 3);
1267 circ.append(val: 4);
1268 circ.append(val: 5);
1269 circ.append(val: 6);
1270
1271 // Now try to remove some points from the lower half
1272 circ.remove(i: 1, number: 2);
1273 QVERIFY(circ.capacity() == 6);
1274 QVERIFY(circ.size() == 4);
1275 QVERIFY(circ.at(0).x == 1);
1276 QVERIFY(circ.at(1).x == 4);
1277 QVERIFY(circ.at(2).x == 5);
1278 QVERIFY(circ.at(3).x == 6);
1279
1280 // Now try repeatedly removing the first item of a partially full buffer
1281 QCircularBuffer<MyComplexType> circ2(20);
1282 for (int i = 0; i < 15; ++i)
1283 circ2.append(val: i);
1284
1285 QVERIFY(circ2.size() == 15);
1286 for (int i = 0; i < 15; ++i)
1287 QVERIFY(circ2.at(i).x == i);
1288
1289 for (int i = 0; i < 10; ++i) {
1290 MyComplexType value = circ2.first();
1291 QVERIFY(value.x == i);
1292 circ2.remove(i: 0);
1293 }
1294}
1295
1296void tst_QCircularBuffer::removeStaticNonLinearised()
1297{
1298 // Try the same type of tests with a non-linearised buffer.
1299
1300 // First remove from upper part of the buffer
1301 QCircularBuffer<MyComplexType> circ(10);
1302 for (int i = 0; i < 15; ++i)
1303 circ.append(val: i + 1);
1304
1305 QVERIFY(circ.capacity() == 10);
1306 QVERIFY(circ.size() == 10);
1307 QVERIFY(circ.isLinearised() == false);
1308 circ.remove(i: 8, number: 2);
1309 QVERIFY(circ.capacity() == 10);
1310 QVERIFY(circ.size() == 8);
1311 QVERIFY(circ.at(0).x == 6);
1312 QVERIFY(circ.at(1).x == 7);
1313 QVERIFY(circ.at(2).x == 8);
1314 QVERIFY(circ.at(3).x == 9);
1315 QVERIFY(circ.at(4).x == 10);
1316 QVERIFY(circ.at(5).x == 11);
1317 QVERIFY(circ.at(6).x == 12);
1318 QVERIFY(circ.at(7).x == 13);
1319
1320 // Restore the original
1321 circ.append(val: 14);
1322 circ.append(val: 15);
1323
1324 // Remove some points from the lower half
1325 circ.remove(i: 1, number: 4);
1326 QVERIFY(circ.capacity() == 10);
1327 QVERIFY(circ.size() == 6);
1328 QVERIFY(circ.at(0).x == 6);
1329 QVERIFY(circ.at(1).x == 11);
1330 QVERIFY(circ.at(2).x == 12);
1331 QVERIFY(circ.at(3).x == 13);
1332 QVERIFY(circ.at(4).x == 14);
1333 QVERIFY(circ.at(5).x == 15);
1334
1335 // Remove all the way to the end
1336 QCircularBuffer<MyComplexType> circ2(6);
1337 for (int i = 0; i < 8; ++i)
1338 circ2.append(val: i + 1);
1339 circ2.remove(i: 2, number: 4);
1340 QVERIFY(circ2.capacity() == 6);
1341 QVERIFY(circ2.size() == 2);
1342 QVERIFY(circ2.at(0).x == 3);
1343 QVERIFY(circ2.at(1).x == 4);
1344
1345 // Try another couple of cases to be thorough
1346 QCircularBuffer<MyComplexType> circ3(6);
1347 for (int i = 0; i < 8; ++i)
1348 circ3.append(val: i + 1);
1349 circ3.remove(i: 3, number: 2);
1350 QVERIFY(circ3.capacity() == 6);
1351 QVERIFY(circ3.size() == 4);
1352 QVERIFY(circ3.at(0).x == 3);
1353 QVERIFY(circ3.at(1).x == 4);
1354 QVERIFY(circ3.at(2).x == 5);
1355 QVERIFY(circ3.at(3).x == 8);
1356
1357 QCircularBuffer<MyComplexType> circ4(6);
1358 for (int i = 0; i < 8; ++i)
1359 circ4.append(val: i + 1);
1360 circ4.remove(i: 1, number: 2);
1361 QVERIFY(circ4.capacity() == 6);
1362 QVERIFY(circ4.size() == 4);
1363 QVERIFY(circ4.at(0).x == 3);
1364 QVERIFY(circ4.at(1).x == 6);
1365 QVERIFY(circ4.at(2).x == 7);
1366 QVERIFY(circ4.at(3).x == 8);
1367}
1368
1369void tst_QCircularBuffer::removeMovableLinearised()
1370{
1371 // Try to do some removes on linearised buffers of a non-movable type
1372
1373 // Remove from the lower half of the buffer
1374 QCircularBuffer<int> circ(6);
1375 for (int i = 0; i < 6; ++i)
1376 circ.append(val: i + 1);
1377 circ.remove(i: 1, number: 2);
1378 QVERIFY(circ.capacity() == 6);
1379 QVERIFY(circ.size() == 4);
1380 QVERIFY(circ.at(0) == 1);
1381 QVERIFY(circ.at(1) == 4);
1382 QVERIFY(circ.at(2) == 5);
1383 QVERIFY(circ.at(3) == 6);
1384
1385 // Remove form the upper half of the buffer
1386 QCircularBuffer<int> circ2(6);
1387 for (int i = 0; i < 6; ++i)
1388 circ2.append(val: i + 1);
1389 circ2.remove(i: 3, number: 2);
1390 QVERIFY(circ2.capacity() == 6);
1391 QVERIFY(circ2.size() == 4);
1392 QVERIFY(circ2.at(0) == 1);
1393 QVERIFY(circ2.at(1) == 2);
1394 QVERIFY(circ2.at(2) == 3);
1395 QVERIFY(circ2.at(3) == 6);
1396}
1397
1398void tst_QCircularBuffer::removeMovableNonLinearisedUpper()
1399{
1400 // Src region wraps and the dst region does not wrap
1401 QCircularBuffer<int> circ(20);
1402 for (int i = 0; i < 23; ++i)
1403 circ.append(val: i + 1);
1404 circ.remove(i: 11, number: 5);
1405 QVERIFY(circ.size() == 15);
1406 for (int i = 0; i < 11; ++i)
1407 QVERIFY(circ.at(i) == i + 4);
1408 QVERIFY(circ.at(11) == 20);
1409 QVERIFY(circ.at(12) == 21);
1410 QVERIFY(circ.at(13) == 22);
1411 QVERIFY(circ.at(14) == 23);
1412
1413 // Src region does not wrap and the dst region wraps
1414 QCircularBuffer<int> circ2(10);
1415 for (int i = 1; i <= 13; i++)
1416 circ2.append(val: i);
1417 circ2.remove(i: 5, number: 2);
1418 QVERIFY(circ2.capacity() == 10);
1419 QVERIFY(circ2.size() == 8);
1420 QVERIFY(circ2.at(0) == 4);
1421 QVERIFY(circ2.at(1) == 5);
1422 QVERIFY(circ2.at(2) == 6);
1423 QVERIFY(circ2.at(3) == 7);
1424 QVERIFY(circ2.at(4) == 8);
1425 QVERIFY(circ2.at(5) == 11);
1426 QVERIFY(circ2.at(6) == 12);
1427 QVERIFY(circ2.at(7) == 13);
1428
1429 // Src and dst regions wrap
1430 QCircularBuffer<int> circ3(10);
1431 for (int i = 1; i <= 13; i++)
1432 circ3.append(val: i);
1433 circ3.remove(i: 5, number: 1);
1434 QVERIFY(circ3.capacity() == 10);
1435 QVERIFY(circ3.size() == 9);
1436 QVERIFY(circ3.at(0) == 4);
1437 QVERIFY(circ3.at(1) == 5);
1438 QVERIFY(circ3.at(2) == 6);
1439 QVERIFY(circ3.at(3) == 7);
1440 QVERIFY(circ3.at(4) == 8);
1441 QVERIFY(circ3.at(5) == 10);
1442 QVERIFY(circ3.at(6) == 11);
1443 QVERIFY(circ3.at(7) == 12);
1444 QVERIFY(circ3.at(8) == 13);
1445
1446 // Neither the src nor dst regions wrap
1447 QCircularBuffer<int> circ4(20);
1448 for (int i = 0; i < 26; ++i)
1449 circ4.append(val: i + 1);
1450 circ4.remove(i: 15, number: 3);
1451 QVERIFY(circ4.size() == 17);
1452 for (int i = 0; i < 15; ++i)
1453 QVERIFY(circ4.at(i) == i + 7);
1454 QVERIFY(circ4.at(15) == 25);
1455 QVERIFY(circ4.at(16) == 26);
1456}
1457
1458void tst_QCircularBuffer::removeMovableNonLinearisedLower()
1459{
1460 // Src region wraps and the dst region does not wrap.
1461 // This case also tests zeroing the free'd region when it is disjoint.
1462 QCircularBuffer<int> circ(20);
1463 for (int i = 0; i < 36; ++i)
1464 circ.append(val: i + 1);
1465 circ.remove(i: 6, number: 7);
1466 QVERIFY(circ.size() == 13);
1467 for (int i = 0; i < 6; ++i)
1468 QVERIFY(circ.at(i) == i + 17);
1469 for (int i = 6; i < circ.size(); ++i)
1470 QVERIFY(circ.at(i) == i + 24);
1471
1472 // Src region does not wrap and the dst region wraps
1473 // This case also tests zeroing the free'd region when it is contiguous.
1474 QCircularBuffer<int> circ2(20);
1475 for (int i = 0; i < 36; ++i)
1476 circ2.append(val: i + 1);
1477 circ2.remove(i: 4, number: 3);
1478 QVERIFY(circ2.size() == 17);
1479 for (int i = 0; i < 4; ++i)
1480 QVERIFY(circ2.at(i) == i + 17);
1481 for (int i = 4; i < circ2.size(); ++i)
1482 QVERIFY(circ2.at(i) == i + 20);
1483
1484 // Src and dst regions wrap
1485 QCircularBuffer<int> circ3(20);
1486 for (int i = 0; i < 36; ++i)
1487 circ3.append(val: i + 1);
1488 circ3.remove(i: 6, number: 3);
1489 QVERIFY(circ3.size() == 17);
1490 for (int i = 0; i < 6; ++i)
1491 QVERIFY(circ3.at(i) == i + 17);
1492 for (int i = 6; i < circ3.size(); ++i)
1493 QVERIFY(circ3.at(i) == i + 20);
1494
1495 // Neither the src nor dst regions wrap
1496 QCircularBuffer<int> circ4(20);
1497 for (int i = 0; i < 36; ++i)
1498 circ4.append(val: i + 1);
1499 circ4.remove(i: 2, number: 1);
1500 QVERIFY(circ4.size() == 19);
1501 for (int i = 0; i < 2; ++i)
1502 QVERIFY(circ4.at(i) == i + 17);
1503 for (int i = 2; i < circ4.size(); ++i)
1504 QVERIFY(circ4.at(i) == i + 18);
1505}
1506
1507void tst_QCircularBuffer::replace()
1508{
1509 QCircularBuffer<int> circ(5, 7);
1510 for (int i = 0; i < 5; ++i)
1511 QVERIFY(circ.at(i) == 7);
1512
1513 circ.replace(i: 2, val: 100);
1514 for (int i = 0; i < 5; ++i) {
1515 if (i != 2)
1516 QVERIFY(circ.at(i) == 7);
1517 else
1518 QVERIFY(circ.at(2) == 100);
1519 }
1520}
1521
1522void tst_QCircularBuffer::resize()
1523{
1524 QCircularBuffer<int> circ(10);
1525 for (int i = 0; i < circ.capacity(); ++i)
1526 circ.append(val: i + 1);
1527 QVERIFY(circ.capacity() == 10);
1528 QVERIFY(circ.size() == 10);
1529
1530 circ.resize(newSize: 6);
1531 QVERIFY(circ.capacity() == 10);
1532 QVERIFY(circ.size() == 6);
1533 for (int i = 0; i < circ.size(); ++i)
1534 QVERIFY(circ.at(i) == i + 1);
1535
1536 circ.resize(newSize: 9);
1537 QVERIFY(circ.capacity() == 10);
1538 QVERIFY(circ.size() == 9);
1539 for (int i = 0; i < circ.size(); ++i) {
1540 if (i < 6)
1541 QVERIFY(circ.at(i) == i + 1);
1542 else
1543 QVERIFY(circ.at(i) == 0);
1544 }
1545}
1546
1547void tst_QCircularBuffer::setCapacityStatic()
1548{
1549 // New capacity < old capacity & src region wraps
1550 QCircularBuffer<MyComplexType> circ(20);
1551 for (int i = 0; i < 36; ++i)
1552 circ.append(val: i + 1);
1553 circ.setCapacity(10);
1554 QVERIFY(circ.capacity() == 10);
1555 QVERIFY(circ.size() == 10);
1556 for (int i = 0; i < circ.size(); ++i)
1557 QVERIFY(circ.at(i).x == i + 17);
1558
1559 // New capacity < old capacity & src region does not wrap
1560 QCircularBuffer<MyComplexType> circ2(20);
1561 for (int i = 0; i < 36; ++i)
1562 circ2.append(val: i + 1);
1563 circ2.setCapacity(3);
1564 QVERIFY(circ2.capacity() == 3);
1565 QVERIFY(circ2.size() == 3);
1566 for (int i = 0; i < circ2.size(); ++i)
1567 QVERIFY(circ2.at(i).x == i + 17);
1568
1569 // New capacity > old capacity
1570 QCircularBuffer<MyComplexType> circ3(20);
1571 for (int i = 0; i < 36; ++i)
1572 circ3.append(val: i + 1);
1573 circ3.setCapacity(25);
1574 QVERIFY(circ3.capacity() == 25);
1575 QVERIFY(circ3.size() == 20);
1576 for (int i = 0; i < circ3.size(); ++i)
1577 QVERIFY(circ3.at(i).x == i + 17);
1578}
1579
1580void tst_QCircularBuffer::setCapacityMovable()
1581{
1582 // New capacity < old capacity & src region wraps
1583 QCircularBuffer<int> circ(20);
1584 for (int i = 0; i < 36; ++i)
1585 circ.append(val: i + 1);
1586 circ.setCapacity(10);
1587 QVERIFY(circ.capacity() == 10);
1588 QVERIFY(circ.size() == 10);
1589 for (int i = 0; i < circ.size(); ++i)
1590 QVERIFY(circ.at(i) == i + 17);
1591
1592 // New capacity < old capacity & src region does not wrap
1593 QCircularBuffer<int> circ2(20);
1594 for (int i = 0; i < 36; ++i)
1595 circ2.append(val: i + 1);
1596 circ2.setCapacity(3);
1597 QVERIFY(circ2.capacity() == 3);
1598 QVERIFY(circ2.size() == 3);
1599 for (int i = 0; i < circ2.size(); ++i)
1600 QVERIFY(circ2.at(i) == i + 17);
1601
1602 // New capacity > old capacity
1603 QCircularBuffer<int> circ3(20);
1604 for (int i = 0; i < 36; ++i)
1605 circ3.append(val: i + 1);
1606 circ3.setCapacity(25);
1607 QVERIFY(circ3.capacity() == 25);
1608 QVERIFY(circ3.size() == 20);
1609 for (int i = 0; i < circ3.size(); ++i)
1610 QVERIFY(circ3.at(i) == i + 17);
1611
1612 // We also need to test with a linearised buffer of a movable type
1613 QCircularBuffer<int> circ4(20);
1614 for (int i = 0; i < 15; ++i)
1615 circ4.append(val: i + 1);
1616 circ4.setCapacity(10);
1617 QVERIFY(circ4.capacity() == 10);
1618 QVERIFY(circ4.size() == 10);
1619 for (int i = 0; i < circ4.size(); ++i)
1620 QVERIFY(circ4.at(i) == i + 1);
1621}
1622
1623void tst_QCircularBuffer::size()
1624{
1625 QCircularBuffer<int> circ(3);
1626 QVERIFY(circ.capacity() == 3);
1627 QVERIFY(circ.isEmpty() == true);
1628 QVERIFY(circ.size() == 0);
1629 circ.append(val: 1);
1630 QVERIFY(circ.size() == 1);
1631 circ.append(val: 2);
1632 circ.append(val: 3);
1633 QVERIFY(circ.isFull() == true);
1634 QVERIFY(circ.size() == 3);
1635 QVERIFY(circ.size() == circ.capacity());
1636}
1637
1638void tst_QCircularBuffer::sizeAvailable()
1639{
1640 QCircularBuffer<int> circ(10);
1641 QVERIFY(circ.capacity() == 10);
1642 QVERIFY(circ.size() == 0);
1643 QVERIFY(circ.sizeAvailable() == 10);
1644
1645 for (int i = 0; i < 15; ++i) {
1646 circ.append(val: i + 1);
1647 QVERIFY(circ.size() == qMin(i + 1, circ.capacity()));
1648 QVERIFY(circ.sizeAvailable() == qMax(0, circ.capacity() - i - 1));
1649 }
1650}
1651
1652void tst_QCircularBuffer::startsWith()
1653{
1654 // Test with a linearised buffer
1655 QCircularBuffer<int> circ(5);
1656 circ.append(val: 1);
1657 circ.append(val: 2);
1658 circ.append(val: 3);
1659 circ.append(val: 4);
1660 circ.append(val: 5);
1661 QVERIFY(circ.startsWith(1) == true);
1662 QVERIFY(circ.endsWith(3) == false);
1663
1664 // Now with a non-linearised buffer
1665 circ.append(val: 6);
1666 circ.append(val: 7);
1667 QVERIFY(circ.startsWith(3) == true);
1668 QVERIFY(circ.startsWith(1) == false);
1669}
1670
1671void tst_QCircularBuffer::toList()
1672{
1673 QCircularBuffer<int> circ(10);
1674 for (int i = 0; i < circ.capacity(); ++i)
1675 circ.append(val: i + 1);
1676 QList<int> list = circ.toList();
1677 QVERIFY(list.size() == circ.size());
1678 for (int i = 0; i < list.size(); ++i)
1679 QVERIFY(list.at(i) == circ.at(i));
1680}
1681
1682void tst_QCircularBuffer::toVector()
1683{
1684 QCircularBuffer<int> circ(10);
1685 for (int i = 0; i < circ.capacity(); ++i)
1686 circ.append(val: i + 1);
1687 QVector<int> vector = circ.toVector();
1688 QVERIFY(vector.size() == circ.size());
1689 for (int i = 0; i < vector.size(); ++i)
1690 QVERIFY(vector.at(i) == circ.at(i));
1691}
1692
1693void tst_QCircularBuffer::value()
1694{
1695 QCircularBuffer<int> circ(3);
1696 circ.append(val: 1);
1697 circ.append(val: 2);
1698 circ.append(val: 3);
1699 QVERIFY(circ.value(0) == 1);
1700 QVERIFY(circ.value(1) == 2);
1701 QVERIFY(circ.value(2) == 3);
1702 QVERIFY(circ.value(3) == 0); // Out of range, so default value
1703 QVERIFY(circ.value(3, 7) == 7); // Out of range, so specified default value
1704}
1705
1706void tst_QCircularBuffer::operatorEquality()
1707{
1708 QCircularBuffer<int> circ1(10);
1709 QCircularBuffer<int> circ2(10);
1710 for (int i = 0; i < 10; i++) {
1711 circ1.append(val: i);
1712 circ2.append(val: i);
1713 }
1714
1715 QVERIFY(circ1 == circ2);
1716
1717 // This test for equality should be fast as it should find
1718 // that the internal d-pointers are the same and so be able
1719 // to skip the element by element comparison
1720 QCircularBuffer<int> circ3(circ1);
1721 QVERIFY(circ1 == circ3);
1722}
1723
1724void tst_QCircularBuffer::operatorInequality()
1725{
1726 QCircularBuffer<int> circ1(10);
1727 QCircularBuffer<int> circ2(11);
1728 for (int i = 0; i < 10; i++) {
1729 circ1.append(val: i);
1730 circ2.append(val: i);
1731 }
1732 circ2.append(val: 11);
1733
1734 QVERIFY(circ1 != circ2);
1735
1736 QCircularBuffer<int> circ3(10);
1737 QCircularBuffer<int> circ4(10);
1738 for (int i = 0; i < 10; i++) {
1739 circ3.append(val: i);
1740 if (i == 4)
1741 circ4.append(val: 100);
1742 else
1743 circ4.append(val: i);
1744 }
1745
1746 QVERIFY(circ3 != circ4);
1747}
1748
1749void tst_QCircularBuffer::operatorPlus()
1750{
1751 QCircularBuffer<int> circ1(20);
1752 for (int i = 0; i < 10; ++i)
1753 circ1.append(val: i + 1);
1754
1755 QCircularBuffer<int> circ2(5);
1756 for (int i = 0; i < circ2.capacity(); ++i)
1757 circ2.append(val: i + 11);
1758
1759 QCircularBuffer<int> circ3 = circ1 + circ2;
1760 QVERIFY(circ3.capacity() == circ1.size() + circ2.size());
1761 QVERIFY(circ3.size() == circ1.size() + circ2.size());
1762 for (int i = 0; i < circ3.size(); ++i) {
1763 if (i < circ1.size())
1764 QVERIFY(circ3.at(i) == circ1.at(i));
1765 else
1766 QVERIFY(circ3.at(i) == circ2.at(i - circ1.size()));
1767 }
1768}
1769
1770void tst_QCircularBuffer::operatorPlusEquals()
1771{
1772 QCircularBuffer<int> circ(100);
1773 for (int i = 0; i < 10; ++i)
1774 circ.append(val: i + 1);
1775
1776 // Add individual elements
1777 for (int i = 0; i < 10; ++i) {
1778 circ += i + 11;
1779 QVERIFY(circ.size() == i + 11);
1780 QVERIFY(circ.last() == i + 11);
1781 }
1782
1783 // Add in an existing QCircularBuffer
1784 QCircularBuffer<int> circ2(10);
1785 for (int i = 0; i < 10; ++i)
1786 circ2.append(val: i + 21);
1787 circ += circ2;
1788 QVERIFY(circ.size() == 30);
1789 for (int i = 20; i < 30; ++i)
1790 QVERIFY(circ.at(i) == i + 1);
1791
1792 // Add in a list
1793 QList<int> list;
1794 for (int i = 0; i < 10; ++i)
1795 list.append(t: i + 31);
1796 circ += list;
1797 QVERIFY(circ.size() == 40);
1798 for (int i = 30; i < 40; ++i)
1799 QVERIFY(circ.at(i) == i + 1);
1800
1801 // Add in a vector
1802 QVector<int> vector;
1803 for (int i = 0; i < 10; ++i)
1804 vector.append(t: i + 41);
1805 circ += vector;
1806 QVERIFY(circ.size() == 50);
1807 for (int i = 40; i < 50; ++i)
1808 QVERIFY(circ.at(i) == i + 1);
1809}
1810
1811void tst_QCircularBuffer::operatorStream()
1812{
1813 QCircularBuffer<int> circ(100);
1814 for (int i = 0; i < 10; ++i)
1815 circ.append(val: i + 1);
1816
1817 // Add individual elements
1818 for (int i = 0; i < 10; ++i) {
1819 circ << i + 11;
1820 QVERIFY(circ.size() == i + 11);
1821 QVERIFY(circ.last() == i + 11);
1822 }
1823
1824 // Add in an existing QCircularBuffer
1825 QCircularBuffer<int> circ2(10);
1826 for (int i = 0; i < 10; ++i)
1827 circ2.append(val: i + 21);
1828 circ << circ2;
1829 QVERIFY(circ.size() == 30);
1830 for (int i = 20; i < 30; ++i)
1831 QVERIFY(circ.at(i) == i + 1);
1832
1833 // Add in a list
1834 QList<int> list;
1835 for (int i = 0; i < 10; ++i)
1836 list.append(t: i + 31);
1837 circ << list;
1838 QVERIFY(circ.size() == 40);
1839 for (int i = 30; i < 40; ++i)
1840 QVERIFY(circ.at(i) == i + 1);
1841
1842 // Add in a vector
1843 QVector<int> vector;
1844 for (int i = 0; i < 10; ++i)
1845 vector.append(t: i + 41);
1846 circ << vector;
1847 QVERIFY(circ.size() == 50);
1848 for (int i = 40; i < 50; ++i)
1849 QVERIFY(circ.at(i) == i + 1);
1850}
1851
1852void tst_QCircularBuffer::const_iterator()
1853{
1854 // Test basic iteration over a linearised buffer.
1855 // This tests operators !=, prefix ++, and *
1856 QCircularBuffer<int> circ(10);
1857 for (int i = 0; i < circ.capacity(); ++i)
1858 circ.append(val: i + 1);
1859
1860 QCircularBuffer<int>::const_iterator it = circ.constBegin();
1861 int i = 0;
1862 while (it != circ.constEnd()) {
1863 QVERIFY(*it == circ.at(i++));
1864 ++it;
1865 }
1866 QVERIFY(i == circ.size());
1867
1868 // Test basic iteration over a non-linearised buffer.
1869 // This tests operators !=, prefix ++, and *
1870 QCircularBuffer<int> circ2(10);
1871 for (int i = 0; i < 14; ++i)
1872 circ2.append(val: i + 1);
1873
1874 QCircularBuffer<int>::const_iterator it2 = circ2.constBegin();
1875 i = 0;
1876 while (it2 != circ2.constEnd()) {
1877 QVERIFY(*it2 == circ2.at(i++));
1878 ++it2;
1879 }
1880 QVERIFY(i == circ2.size());
1881
1882 // Reverse iteration
1883 while (it2 != circ2.constBegin()) {
1884 --it2;
1885 QVERIFY(*it2 == circ2.at(--i));
1886 }
1887 QVERIFY(i == 0);
1888
1889 // Operator ==
1890 it = circ2.constBegin();
1891 it2 = circ2.constBegin();
1892 QVERIFY(it == it2);
1893
1894 // Operator [int]
1895 for (int i = 0; i < circ2.size(); ++i)
1896 QVERIFY(it[ i ] == circ2.at(i));
1897
1898 // Postfix operator ++
1899 QCircularBuffer<int>::const_iterator it3 = it2++;
1900 QVERIFY(it3 == it);
1901 QVERIFY(*it2 == circ2.at(1));
1902
1903 // Comparison operators
1904 QVERIFY(it < it2);
1905 QVERIFY(it <= it2);
1906 QVERIFY(it <= it3);
1907 QVERIFY(it2 > it);
1908 QVERIFY(it2 >= it);
1909 QVERIFY(it3 >= it);
1910
1911 // Postfix operator --
1912 it3 = it2--;
1913 QVERIFY(*it3 == circ2.at(1));
1914 QVERIFY(it2 == it);
1915
1916 // Operator += and -=
1917 it2 += 1;
1918 QVERIFY(it2 == it3);
1919 it2 -= 1;
1920 QVERIFY(it2 == it);
1921
1922 // Operator + (int) and operator - (int)
1923 QCircularBuffer<int>::const_iterator it4 = it + (circ2.size() - 1);
1924 QVERIFY(*it4 == circ2.last());
1925 QCircularBuffer<int>::const_iterator it5 = it4 - (circ2.size() - 1);
1926 QVERIFY(*it5 == circ2.first());
1927
1928 // Operator - (const_iterator)
1929 QVERIFY(it4 - it5 == circ2.size() - 1);
1930
1931 // Operator ->
1932 QCircularBuffer<MyComplexType> circ3(10);
1933 for (int i = 0; i < circ3.capacity(); ++i)
1934 circ3.append(val: i + 1);
1935 QCircularBuffer<MyComplexType>::const_iterator it6 = circ3.constBegin();
1936 for (int i = 0; i < circ2.capacity(); ++i)
1937 {
1938 QVERIFY(it6->x == circ3.at(i).x);
1939 ++it6;
1940 }
1941}
1942
1943void tst_QCircularBuffer::iterator()
1944{
1945 // Test basic iteration over a linearised buffer.
1946 // This tests operators !=, prefix ++, and *
1947 QCircularBuffer<int> circ(10);
1948 for (int i = 0; i < circ.capacity(); ++i)
1949 circ.append(val: i + 1);
1950
1951 QCircularBuffer<int>::iterator it = circ.begin();
1952 int i = 0;
1953 while (it != circ.end()) {
1954 QVERIFY(*it == circ.at(i++));
1955 ++it;
1956 }
1957 QVERIFY(i == circ.size());
1958
1959 // Test basic iteration over a non-linearised buffer.
1960 // This tests operators !=, prefix ++, and *
1961 QCircularBuffer<int> circ2(10);
1962 for (int i = 0; i < 14; ++i)
1963 circ2.append(val: i + 1);
1964
1965 QCircularBuffer<int>::iterator it2 = circ2.begin();
1966 i = 0;
1967 while (it2 != circ2.end()) {
1968 QVERIFY(*it2 == circ2.at(i++));
1969 ++it2;
1970 }
1971 QVERIFY(i == circ2.size());
1972
1973 // Reverse iteration
1974 while (it2 != circ2.begin()) {
1975 --it2;
1976 QVERIFY(*it2 == circ2.at(--i));
1977 }
1978 QVERIFY(i == 0);
1979
1980 // Operator ==
1981 it = circ2.begin();
1982 it2 = circ2.begin();
1983 QVERIFY(it == it2);
1984
1985 // Operator [int]
1986 for (int i = 0; i < circ2.size(); ++i)
1987 QVERIFY(it[ i ] == circ2.at(i));
1988
1989 // Postfix operator ++
1990 QCircularBuffer<int>::iterator it3 = it2++;
1991 QVERIFY(it3 == it);
1992 QVERIFY(*it2 == circ2.at(1));
1993
1994 // Comparison operators
1995 QVERIFY(it < it2);
1996 QVERIFY(it <= it2);
1997 QVERIFY(it <= it3);
1998 QVERIFY(it2 > it);
1999 QVERIFY(it2 >= it);
2000 QVERIFY(it3 >= it);
2001
2002 // Postfix operator --
2003 it3 = it2--;
2004 QVERIFY(*it3 == circ2.at(1));
2005 QVERIFY(it2 == it);
2006
2007 // Operator += and -=
2008 it2 += 1;
2009 QVERIFY(it2 == it3);
2010 it2 -= 1;
2011 QVERIFY(it2 == it);
2012
2013 // Operator + (int) and operator - (int)
2014 QCircularBuffer<int>::iterator it4 = it + (circ2.size() - 1);
2015 QVERIFY(*it4 == circ2.last());
2016 QCircularBuffer<int>::iterator it5 = it4 - (circ2.size() - 1);
2017 QVERIFY(*it5 == circ2.first());
2018
2019 // Operator - (const_iterator)
2020 QVERIFY(it4 - it5 == circ2.size() - 1);
2021
2022 // Operator ->
2023 QCircularBuffer<MyComplexType> circ3(10);
2024 for (int i = 0; i < circ3.capacity(); ++i)
2025 circ3.append(val: i + 1);
2026 QCircularBuffer<MyComplexType>::iterator it6 = circ3.begin();
2027 for (int i = 0; i < circ2.capacity(); ++i) {
2028 QVERIFY(it6->x == circ3.at(i).x);
2029 ++it6;
2030 }
2031}
2032
2033void tst_QCircularBuffer::testAppendFifo()
2034{
2035 QCircularBuffer< float > c;
2036 c.setCapacity(5);
2037 c += QVector<float>(4, 0.0f);
2038 c.setCapacity(7);
2039 c += QVector<float>(4, 0.0f);
2040 c.remove(i: 0, number: 2);
2041}
2042
2043QTEST_APPLESS_MAIN(tst_QCircularBuffer)
2044#include "tst_qcircularbuffer.moc"
2045

source code of qt3d/tests/auto/core/qcircularbuffer/tst_qcircularbuffer.cpp