Blender V4.3
BLI_vector_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
6#include "BLI_vector.hh"
7#include "testing/testing.h"
8#include <forward_list>
9
10#include "BLI_strict_flags.h" /* Keep last. */
11
12namespace blender::tests {
13
14TEST(vector, DefaultConstructor)
15{
16 Vector<int> vec;
17 EXPECT_EQ(vec.size(), 0);
18}
19
20TEST(vector, SizeConstructor)
21{
22 Vector<int> vec(3);
23 EXPECT_EQ(vec.size(), 3);
24}
25
30TEST(vector, TrivialTypeSizeConstructor)
31{
32 Vector<char, 1> *vec = new Vector<char, 1>(1);
33 char *ptr = &(*vec)[0];
34 vec->~Vector();
35
36 const char magic = 42;
37 *ptr = magic;
39
40 new (vec) Vector<char, 1>(1);
41 EXPECT_EQ((*vec)[0], magic);
43 delete vec;
44}
45
46TEST(vector, SizeValueConstructor)
47{
48 Vector<int> vec(4, 10);
49 EXPECT_EQ(vec.size(), 4);
50 EXPECT_EQ(vec[0], 10);
51 EXPECT_EQ(vec[1], 10);
52 EXPECT_EQ(vec[2], 10);
53 EXPECT_EQ(vec[3], 10);
54}
55
56TEST(vector, InitializerListConstructor)
57{
58 Vector<int> vec = {1, 3, 4, 6};
59 EXPECT_EQ(vec.size(), 4);
60 EXPECT_EQ(vec[0], 1);
61 EXPECT_EQ(vec[1], 3);
62 EXPECT_EQ(vec[2], 4);
63 EXPECT_EQ(vec[3], 6);
64}
65
66TEST(vector, ConvertingConstructor)
67{
68 std::array<float, 5> values = {5.4f, 7.3f, -8.1f, 5.0f, 0.0f};
69 Vector<int> vec = values;
70 EXPECT_EQ(vec.size(), 5);
71 EXPECT_EQ(vec[0], 5);
72 EXPECT_EQ(vec[1], 7);
73 EXPECT_EQ(vec[2], -8);
74 EXPECT_EQ(vec[3], 5);
75 EXPECT_EQ(vec[4], 0);
76}
77
82
83// TEST(vector, ListBaseConstructor)
84// {
85// TestListValue *value1 = new TestListValue{nullptr, nullptr, 4};
86// TestListValue *value2 = new TestListValue{nullptr, nullptr, 5};
87// TestListValue *value3 = new TestListValue{nullptr, nullptr, 6};
88
89// ListBase list = {nullptr, nullptr};
90// BLI_addtail(&list, value1);
91// BLI_addtail(&list, value2);
92// BLI_addtail(&list, value3);
93// Vector<TestListValue *> vec(list);
94
95// EXPECT_EQ(vec.size(), 3);
96// EXPECT_EQ(vec[0]->value, 4);
97// EXPECT_EQ(vec[1]->value, 5);
98// EXPECT_EQ(vec[2]->value, 6);
99
100// delete value1;
101// delete value2;
102// delete value3;
103// }
104
105TEST(vector, IteratorConstructor)
106{
107 std::forward_list<int> list;
108 list.push_front(3);
109 list.push_front(1);
110 list.push_front(5);
111
112 Vector<int> vec = Vector<int>(list.begin(), list.end());
113 EXPECT_EQ(vec.size(), 3);
114 EXPECT_EQ(vec[0], 5);
115 EXPECT_EQ(vec[1], 1);
116 EXPECT_EQ(vec[2], 3);
117}
118
119TEST(vector, CopyConstructor)
120{
121 Vector<int> vec1 = {1, 2, 3};
122 Vector<int> vec2(vec1);
123 EXPECT_EQ(vec2.size(), 3);
124 EXPECT_EQ(vec2[0], 1);
125 EXPECT_EQ(vec2[1], 2);
126 EXPECT_EQ(vec2[2], 3);
127
128 vec1[1] = 5;
129 EXPECT_EQ(vec1[1], 5);
130 EXPECT_EQ(vec2[1], 2);
131}
132
133TEST(vector, CopyConstructor2)
134{
135 Vector<int, 2> vec1 = {1, 2, 3, 4};
136 Vector<int, 3> vec2(vec1);
137
138 EXPECT_EQ(vec1.size(), 4);
139 EXPECT_EQ(vec2.size(), 4);
140 EXPECT_NE(vec1.data(), vec2.data());
141 EXPECT_EQ(vec2[0], 1);
142 EXPECT_EQ(vec2[1], 2);
143 EXPECT_EQ(vec2[2], 3);
144 EXPECT_EQ(vec2[3], 4);
145}
146
147TEST(vector, CopyConstructor3)
148{
149 Vector<int, 20> vec1 = {1, 2, 3, 4};
150 Vector<int, 1> vec2(vec1);
151
152 EXPECT_EQ(vec1.size(), 4);
153 EXPECT_EQ(vec2.size(), 4);
154 EXPECT_NE(vec1.data(), vec2.data());
155 EXPECT_EQ(vec2[2], 3);
156}
157
158TEST(vector, CopyConstructor4)
159{
160 Vector<int, 5> vec1 = {1, 2, 3, 4};
161 Vector<int, 6> vec2(vec1);
162
163 EXPECT_EQ(vec1.size(), 4);
164 EXPECT_EQ(vec2.size(), 4);
165 EXPECT_NE(vec1.data(), vec2.data());
166 EXPECT_EQ(vec2[3], 4);
167}
168
169TEST(vector, MoveConstructor)
170{
171 Vector<int> vec1 = {1, 2, 3, 4};
172 Vector<int> vec2(std::move(vec1));
173
174 EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */
175 EXPECT_EQ(vec2.size(), 4);
176 EXPECT_EQ(vec2[0], 1);
177 EXPECT_EQ(vec2[1], 2);
178 EXPECT_EQ(vec2[2], 3);
179 EXPECT_EQ(vec2[3], 4);
180}
181
182TEST(vector, MoveConstructor2)
183{
184 Vector<int, 2> vec1 = {1, 2, 3, 4};
185 Vector<int, 3> vec2(std::move(vec1));
186
187 EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */
188 EXPECT_EQ(vec2.size(), 4);
189 EXPECT_EQ(vec2[0], 1);
190 EXPECT_EQ(vec2[1], 2);
191 EXPECT_EQ(vec2[2], 3);
192 EXPECT_EQ(vec2[3], 4);
193}
194
195TEST(vector, MoveConstructor3)
196{
197 Vector<int, 20> vec1 = {1, 2, 3, 4};
198 Vector<int, 1> vec2(std::move(vec1));
199
200 EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */
201 EXPECT_EQ(vec2.size(), 4);
202 EXPECT_EQ(vec2[2], 3);
203}
204
205TEST(vector, MoveConstructor4)
206{
207 Vector<int, 5> vec1 = {1, 2, 3, 4};
208 Vector<int, 6> vec2(std::move(vec1));
209
210 EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */
211 EXPECT_EQ(vec2.size(), 4);
212 EXPECT_EQ(vec2[3], 4);
213}
214
215TEST(vector, MoveAssignment)
216{
217 Vector<int> vec = {1, 2};
218 EXPECT_EQ(vec.size(), 2);
219 EXPECT_EQ(vec[0], 1);
220 EXPECT_EQ(vec[1], 2);
221
222 vec = Vector<int>({5});
223 EXPECT_EQ(vec.size(), 1);
224 EXPECT_EQ(vec[0], 5);
225}
226
227TEST(vector, CopyAssignment)
228{
229 Vector<int> vec1 = {1, 2, 3};
230 Vector<int> vec2 = {4, 5};
231 EXPECT_EQ(vec1.size(), 3);
232 EXPECT_EQ(vec2.size(), 2);
233
234 vec2 = vec1;
235 EXPECT_EQ(vec2.size(), 3);
236
237 vec1[0] = 7;
238 EXPECT_EQ(vec1[0], 7);
239 EXPECT_EQ(vec2[0], 1);
240}
241
242TEST(vector, Append)
243{
244 Vector<int> vec;
245 vec.append(3);
246 vec.append(6);
247 vec.append(7);
248 EXPECT_EQ(vec.size(), 3);
249 EXPECT_EQ(vec[0], 3);
250 EXPECT_EQ(vec[1], 6);
251 EXPECT_EQ(vec[2], 7);
252}
253
254TEST(vector, AppendAs)
255{
257 vec.append_as("hello", 2);
258 vec.append_as("world", 3);
259 EXPECT_EQ(vec[0], "he");
260 EXPECT_EQ(vec[1], "wor");
261}
262
263TEST(vector, AppendAndGetIndex)
264{
265 Vector<int> vec;
269 vec.append(10);
270 int value = 10;
271 EXPECT_EQ(vec.append_and_get_index(value), 4);
272}
273
274TEST(vector, AppendNonDuplicates)
275{
276 Vector<int> vec;
278 EXPECT_EQ(vec.size(), 1);
280 EXPECT_EQ(vec.size(), 2);
282 EXPECT_EQ(vec.size(), 2);
283}
284
285TEST(vector, ExtendNonDuplicates)
286{
287 Vector<int> vec;
288 vec.extend_non_duplicates({1, 2});
289 EXPECT_EQ(vec.size(), 2);
290 vec.extend_non_duplicates({3, 4});
291 EXPECT_EQ(vec.size(), 4);
292 vec.extend_non_duplicates({0, 1, 2, 3});
293 EXPECT_EQ(vec.size(), 5);
294}
295
296TEST(vector, ExtendIterator)
297{
298 Vector<int> vec = {3, 4, 5};
299 std::forward_list<int> list = {8, 9};
300 vec.extend(list.begin(), list.end());
301 EXPECT_EQ(vec.size(), 5);
302 EXPECT_EQ_ARRAY(vec.data(), Span({3, 4, 5, 8, 9}).data(), 5);
303}
304
305TEST(vector, Iterator)
306{
307 Vector<int> vec({1, 4, 9, 16});
308 int i = 1;
309 for (int value : vec) {
310 EXPECT_EQ(value, i * i);
311 i++;
312 }
313}
314
315TEST(vector, BecomeLarge)
316{
317 Vector<int, 4> vec;
318 for (int i = 0; i < 100; i++) {
319 vec.append(i * 5);
320 }
321 EXPECT_EQ(vec.size(), 100);
322 for (int i = 0; i < 100; i++) {
323 EXPECT_EQ(vec[i], int(i * 5));
324 }
325}
326
328{
329 return Vector<int>({3, 5, 1});
330}
331
332TEST(vector, ReturnByValue)
333{
335 EXPECT_EQ(vec.size(), 3);
336 EXPECT_EQ(vec[0], 3);
337 EXPECT_EQ(vec[1], 5);
338 EXPECT_EQ(vec[2], 1);
339}
340
341TEST(vector, VectorOfVectors_Append)
342{
344 EXPECT_EQ(vec.size(), 0);
345
346 Vector<int> v({1, 2});
347 vec.append(v);
348 vec.append({7, 8});
349 EXPECT_EQ(vec.size(), 2);
350 EXPECT_EQ(vec[0][0], 1);
351 EXPECT_EQ(vec[0][1], 2);
352 EXPECT_EQ(vec[1][0], 7);
353 EXPECT_EQ(vec[1][1], 8);
354}
355
356TEST(vector, RemoveLast)
357{
358 Vector<int> vec = {5, 6};
359 EXPECT_EQ(vec.size(), 2);
360 vec.remove_last();
361 EXPECT_EQ(vec.size(), 1);
362 vec.remove_last();
363 EXPECT_EQ(vec.size(), 0);
364}
365
366TEST(vector, IsEmpty)
367{
368 Vector<int> vec;
369 EXPECT_TRUE(vec.is_empty());
370 vec.append(1);
371 EXPECT_FALSE(vec.is_empty());
372 vec.remove_last();
373 EXPECT_TRUE(vec.is_empty());
374}
375
376TEST(vector, RemoveReorder)
377{
378 Vector<int> vec = {4, 5, 6, 7};
379 vec.remove_and_reorder(1);
380 EXPECT_EQ(vec[0], 4);
381 EXPECT_EQ(vec[1], 7);
382 EXPECT_EQ(vec[2], 6);
383 vec.remove_and_reorder(2);
384 EXPECT_EQ(vec[0], 4);
385 EXPECT_EQ(vec[1], 7);
386 vec.remove_and_reorder(0);
387 EXPECT_EQ(vec[0], 7);
388 vec.remove_and_reorder(0);
389 EXPECT_TRUE(vec.is_empty());
390}
391
392TEST(vector, RemoveFirstOccurrenceAndReorder)
393{
394 Vector<int> vec = {4, 5, 6, 7};
396 EXPECT_EQ(vec[0], 4);
397 EXPECT_EQ(vec[1], 7);
398 EXPECT_EQ(vec[2], 6);
400 EXPECT_EQ(vec[0], 4);
401 EXPECT_EQ(vec[1], 7);
403 EXPECT_EQ(vec[0], 7);
405 EXPECT_EQ(vec.size(), 0);
406}
407
408TEST(vector, Remove)
409{
410 Vector<int> vec = {1, 2, 3, 4, 5, 6};
411 vec.remove(3);
412 EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({1, 2, 3, 5, 6}).begin()));
413 vec.remove(0);
414 EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 3, 5, 6}).begin()));
415 vec.remove(3);
416 EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 3, 5}).begin()));
417 vec.remove(1);
418 EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 5}).begin()));
419 vec.remove(1);
420 EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2}).begin()));
421 vec.remove(0);
422 EXPECT_EQ(vec.begin(), vec.end());
423}
424
425TEST(vector, RemoveIf)
426{
427 Vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8};
428 const int64_t removed = vec.remove_if([](const int x) { return x % 2 == 0; });
429 EXPECT_EQ(vec.size() + removed, 8);
430 const Vector<int> expected_vec = {1, 3, 5, 7};
431 EXPECT_EQ(vec.size(), expected_vec.size());
432 EXPECT_EQ_ARRAY(vec.data(), expected_vec.data(), size_t(vec.size()));
433}
434
435TEST(vector, RemoveIfNonTrivialDestructible)
436{
438 for ([[maybe_unused]] const int64_t i : IndexRange(10)) {
439 /* This test relies on leak detection to run after tests. */
441 }
442 vec.remove_if([&](const auto & /*value*/) { return true; });
443 EXPECT_TRUE(vec.is_empty());
444}
445
446TEST(vector, ExtendSmallVector)
447{
448 Vector<int> a = {2, 3, 4};
449 Vector<int> b = {11, 12};
450 b.extend(a);
451 EXPECT_EQ(b.size(), 5);
452 EXPECT_EQ(b[0], 11);
453 EXPECT_EQ(b[1], 12);
454 EXPECT_EQ(b[2], 2);
455 EXPECT_EQ(b[3], 3);
456 EXPECT_EQ(b[4], 4);
457}
458
459TEST(vector, ExtendArray)
460{
461 int array[] = {3, 4, 5, 6};
462
463 Vector<int> a;
464 a.extend(array, 2);
465
466 EXPECT_EQ(a.size(), 2);
467 EXPECT_EQ(a[0], 3);
468 EXPECT_EQ(a[1], 4);
469}
470
472{
473 Vector<int> a{3, 5, 7};
474 EXPECT_EQ(a.last(), 7);
475 EXPECT_EQ(a.last(0), 7);
476 EXPECT_EQ(a.last(1), 5);
477 EXPECT_EQ(a.last(2), 3);
478}
479
480TEST(vector, AppendNTimes)
481{
482 Vector<int> a;
483 a.append_n_times(5, 3);
484 a.append_n_times(2, 2);
485 EXPECT_EQ(a.size(), 5);
486 EXPECT_EQ(a[0], 5);
487 EXPECT_EQ(a[1], 5);
488 EXPECT_EQ(a[2], 5);
489 EXPECT_EQ(a[3], 2);
490 EXPECT_EQ(a[4], 2);
491}
492
493TEST(vector, UniquePtrValue)
494{
496 vec.append(std::make_unique<int>());
497 vec.append(std::make_unique<int>());
498 vec.append(std::make_unique<int>());
499 vec.append(std::make_unique<int>());
500 EXPECT_EQ(vec.size(), 4);
501
502 std::unique_ptr<int> &a = vec.last();
503 std::unique_ptr<int> b = vec.pop_last();
504 vec.remove_and_reorder(0);
505 vec.remove(0);
506 EXPECT_EQ(vec.size(), 1);
507 EXPECT_EQ(vec.append_and_get_index(std::make_unique<int>(4)), 1);
508
509 UNUSED_VARS(a, b);
510}
511
513 public:
515 bool copy_constructed = false;
516 bool move_constructed = false;
517 bool copy_assigned = false;
518 bool move_assigned = false;
519
521
523
525
527 {
528 if (this == &other) {
529 return *this;
530 }
531
532 copy_assigned = true;
533 return *this;
534 }
535
537 {
538 if (this == &other) {
539 return *this;
540 }
541
542 move_assigned = true;
543 return *this;
544 }
545};
546
547TEST(vector, SizeConstructorCallsDefaultConstructor)
548{
550 EXPECT_TRUE(vec[0].default_constructed);
551 EXPECT_TRUE(vec[1].default_constructed);
552 EXPECT_TRUE(vec[2].default_constructed);
553}
554
555TEST(vector, SizeValueConstructorCallsCopyConstructor)
556{
558 EXPECT_TRUE(vec[0].copy_constructed);
559 EXPECT_TRUE(vec[1].copy_constructed);
560 EXPECT_TRUE(vec[2].copy_constructed);
561}
562
563TEST(vector, AppendCallsCopyConstructor)
564{
566 TypeConstructMock value;
567 vec.append(value);
568 EXPECT_TRUE(vec[0].copy_constructed);
569}
570
571TEST(vector, AppendCallsMoveConstructor)
572{
575 EXPECT_TRUE(vec[0].move_constructed);
576}
577
578TEST(vector, SmallVectorCopyCallsCopyConstructor)
579{
582 EXPECT_TRUE(dst[0].copy_constructed);
583 EXPECT_TRUE(dst[1].copy_constructed);
584}
585
586TEST(vector, LargeVectorCopyCallsCopyConstructor)
587{
590 EXPECT_TRUE(dst[0].copy_constructed);
591 EXPECT_TRUE(dst[1].copy_constructed);
592}
593
594TEST(vector, SmallVectorMoveCallsMoveConstructor)
595{
597 Vector<TypeConstructMock, 2> dst(std::move(src));
598 EXPECT_TRUE(dst[0].move_constructed);
599 EXPECT_TRUE(dst[1].move_constructed);
600}
601
602TEST(vector, LargeVectorMoveCallsNoConstructor)
603{
605 Vector<TypeConstructMock, 2> dst(std::move(src));
606
607 EXPECT_TRUE(dst[0].default_constructed);
608 EXPECT_FALSE(dst[0].move_constructed);
609 EXPECT_FALSE(dst[0].copy_constructed);
610}
611
612TEST(vector, Resize)
613{
614 std::string long_string = "012345678901234567890123456789";
616 EXPECT_EQ(vec.size(), 0);
617 vec.resize(2);
618 EXPECT_EQ(vec.size(), 2);
619 EXPECT_EQ(vec[0], "");
620 EXPECT_EQ(vec[1], "");
621 vec.resize(5, long_string);
622 EXPECT_EQ(vec.size(), 5);
623 EXPECT_EQ(vec[0], "");
624 EXPECT_EQ(vec[1], "");
625 EXPECT_EQ(vec[2], long_string);
626 EXPECT_EQ(vec[3], long_string);
627 EXPECT_EQ(vec[4], long_string);
628 vec.resize(1);
629 EXPECT_EQ(vec.size(), 1);
630 EXPECT_EQ(vec[0], "");
631}
632
633TEST(vector, FirstIndexOf)
634{
635 Vector<int> vec = {2, 3, 5, 7, 5, 9};
636 EXPECT_EQ(vec.first_index_of(2), 0);
637 EXPECT_EQ(vec.first_index_of(5), 2);
638 EXPECT_EQ(vec.first_index_of(9), 5);
639}
640
641TEST(vector, FirstIndexTryOf)
642{
643 Vector<int> vec = {2, 3, 5, 7, 5, 9};
644 EXPECT_EQ(vec.first_index_of_try(2), 0);
645 EXPECT_EQ(vec.first_index_of_try(4), -1);
646 EXPECT_EQ(vec.first_index_of_try(5), 2);
647 EXPECT_EQ(vec.first_index_of_try(9), 5);
648 EXPECT_EQ(vec.first_index_of_try(1), -1);
649}
650
651TEST(vector, OveralignedValues)
652{
654 for (int i = 0; i < 100; i++) {
655 vec.append({});
656 EXPECT_EQ(uintptr_t(&vec.last()) % 512, 0);
657 }
658}
659
660TEST(vector, ConstructVoidPointerVector)
661{
662 int a;
663 float b;
664 double c;
665 Vector<void *> vec = {&a, &b, &c};
666 EXPECT_EQ(vec.size(), 3);
667}
668
670{
671 Vector<int> vec(5);
672 vec.fill(3);
673 EXPECT_EQ(vec.size(), 5u);
674 EXPECT_EQ(vec[0], 3);
675 EXPECT_EQ(vec[1], 3);
676 EXPECT_EQ(vec[2], 3);
677 EXPECT_EQ(vec[3], 3);
678 EXPECT_EQ(vec[4], 3);
679}
680
681TEST(vector, InsertAtBeginning)
682{
683 Vector<int> vec = {1, 2, 3};
684 vec.insert(0, {6, 7});
685 EXPECT_EQ(vec.size(), 5);
686 EXPECT_EQ_ARRAY(vec.data(), Span({6, 7, 1, 2, 3}).data(), 5);
687}
688
689TEST(vector, InsertAtEnd)
690{
691 Vector<int> vec = {1, 2, 3};
692 vec.insert(3, {6, 7});
693 EXPECT_EQ(vec.size(), 5);
694 EXPECT_EQ_ARRAY(vec.data(), Span({1, 2, 3, 6, 7}).data(), 5);
695}
696
697TEST(vector, InsertInMiddle)
698{
699 Vector<int> vec = {1, 2, 3};
700 vec.insert(1, {6, 7});
701 EXPECT_EQ(vec.size(), 5);
702 EXPECT_EQ_ARRAY(vec.data(), Span({1, 6, 7, 2, 3}).data(), 5);
703}
704
705TEST(vector, InsertAtIterator)
706{
707 Vector<std::string> vec = {"1", "2", "3"};
708 Vector<std::string> other_vec = {"hello", "world"};
709 vec.insert(vec.begin() + 1, other_vec.begin(), other_vec.end());
710 EXPECT_EQ(vec.size(), 5);
711 EXPECT_EQ_ARRAY(vec.data(), Span<std::string>({"1", "hello", "world", "2", "3"}).data(), 5);
712}
713
714TEST(vector, InsertMoveOnlyType)
715{
717 vec.append(std::make_unique<int>(1));
718 vec.append(std::make_unique<int>(2));
719 vec.insert(1, std::make_unique<int>(30));
720 EXPECT_EQ(vec.size(), 3);
721 EXPECT_EQ(*vec[0], 1);
722 EXPECT_EQ(*vec[1], 30);
723 EXPECT_EQ(*vec[2], 2);
724}
725
726TEST(vector, Prepend)
727{
728 Vector<int> vec = {1, 2, 3};
729 vec.prepend({7, 8});
730 EXPECT_EQ(vec.size(), 5);
731 EXPECT_EQ_ARRAY(vec.data(), Span({7, 8, 1, 2, 3}).data(), 5);
732}
733
734TEST(vector, PrependString)
735{
736 std::string s = "test";
738 vec.prepend(s);
739 vec.prepend(std::move(s));
740 EXPECT_EQ(vec.size(), 2);
741 EXPECT_EQ(vec[0], "test");
742 EXPECT_EQ(vec[1], "test");
743}
744
745TEST(vector, ReverseIterator)
746{
747 Vector<int> vec = {4, 5, 6, 7};
748 Vector<int> reversed_vec;
749 for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
750 reversed_vec.append(*it);
751 }
752 EXPECT_EQ(reversed_vec.size(), 4);
753 EXPECT_EQ_ARRAY(reversed_vec.data(), Span({7, 6, 5, 4}).data(), 4);
754}
755
756TEST(vector, SizeValueConstructorExceptions)
757{
758 ExceptionThrower value;
759 value.throw_during_copy = true;
760 EXPECT_ANY_THROW({ Vector<ExceptionThrower> vec(5, value); });
761}
762
763TEST(vector, SpanConstructorExceptions)
764{
765 std::array<ExceptionThrower, 5> values;
766 values[3].throw_during_copy = true;
767 EXPECT_ANY_THROW({ Vector<ExceptionThrower> vec(values); });
768}
769
770TEST(vector, MoveConstructorExceptions)
771{
773 vec[2].throw_during_move = true;
774 EXPECT_ANY_THROW({ Vector<ExceptionThrower> moved_vector{std::move(vec)}; });
775}
776
777TEST(vector, AppendExceptions)
778{
780 ExceptionThrower *ptr1 = &vec.last();
781 ExceptionThrower value;
782 value.throw_during_copy = true;
783 EXPECT_ANY_THROW({ vec.append(value); });
784 EXPECT_EQ(vec.size(), 2);
785 ExceptionThrower *ptr2 = &vec.last();
786 EXPECT_EQ(ptr1, ptr2);
787}
788
789TEST(vector, ExtendExceptions)
790{
792 std::array<ExceptionThrower, 10> values;
793 values[6].throw_during_copy = true;
794 EXPECT_ANY_THROW({ vec.extend(values); });
795 EXPECT_EQ(vec.size(), 5);
796}
797
798TEST(vector, Insert1Exceptions)
799{
801 std::array<ExceptionThrower, 5> values;
802 values[3].throw_during_copy = true;
803 EXPECT_ANY_THROW({ vec.insert(7, values); });
804}
805
806TEST(vector, Insert2Exceptions)
807{
809 vec.reserve(100);
810 vec[8].throw_during_move = true;
811 std::array<ExceptionThrower, 5> values;
812 EXPECT_ANY_THROW({ vec.insert(3, values); });
813}
814
815TEST(vector, PopLastExceptions)
816{
818 vec.last().throw_during_move = true;
819 EXPECT_ANY_THROW({ vec.pop_last(); }); /* NOLINT: bugprone-throw-keyword-missing */
820 EXPECT_EQ(vec.size(), 10);
821}
822
823TEST(vector, RemoveAndReorderExceptions)
824{
826 vec.last().throw_during_move = true;
827 EXPECT_ANY_THROW({ vec.remove_and_reorder(3); });
828 EXPECT_EQ(vec.size(), 10);
829}
830
831TEST(vector, RemoveExceptions)
832{
834 vec[8].throw_during_move = true;
835 EXPECT_ANY_THROW({ vec.remove(2); });
836 EXPECT_EQ(vec.size(), 10);
837}
838
839TEST(vector, RemoveChunk)
840{
841 Vector<int> vec = {2, 3, 4, 5, 6, 7, 8};
842 EXPECT_EQ(vec.size(), 7);
843 vec.remove(2, 4);
844 EXPECT_EQ(vec.size(), 3);
845 EXPECT_EQ(vec[0], 2);
846 EXPECT_EQ(vec[1], 3);
847 EXPECT_EQ(vec[2], 8);
848 vec.remove(0, 1);
849 EXPECT_EQ(vec.size(), 2);
850 EXPECT_EQ(vec[0], 3);
851 EXPECT_EQ(vec[1], 8);
852 vec.remove(1, 1);
853 EXPECT_EQ(vec.size(), 1);
854 EXPECT_EQ(vec[0], 3);
855 vec.remove(0, 1);
856 EXPECT_EQ(vec.size(), 0);
857 vec.remove(0, 0);
858 EXPECT_EQ(vec.size(), 0);
859}
860
861TEST(vector, RemoveChunkExceptions)
862{
864 vec.remove(1, 3);
865 EXPECT_EQ(vec.size(), 7);
866 vec[5].throw_during_move = true;
867 EXPECT_ANY_THROW({ vec.remove(2, 3); });
868 EXPECT_EQ(vec.size(), 7);
869}
870
874
875TEST(vector, RecursiveStructure)
876{
877 RecursiveType my_recursive_type;
878 my_recursive_type.my_vector.append({});
879}
880
881} // namespace blender::tests
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
#define UNUSED_VARS(...)
ATTR_WARN_UNUSED_RESULT const BMVert * v
constexpr const T * data() const
Definition BLI_span.hh:216
constexpr const T * begin() const
Definition BLI_span.hh:221
int64_t size() const
std::reverse_iterator< T * > rbegin()
void remove_and_reorder(const int64_t index)
int64_t remove_if(Predicate &&predicate)
int64_t append_and_get_index(const T &value)
void prepend(const T &value)
void append(const T &value)
void insert(const int64_t insert_index, const T &value)
const T & last(const int64_t n=0) const
void remove(const int64_t index)
bool is_empty() const
void remove_first_occurrence_and_reorder(const T &value)
void resize(const int64_t new_size)
int64_t first_index_of(const T &value) const
void reserve(const int64_t min_capacity)
std::reverse_iterator< T * > rend()
void extend(Span< T > array)
void extend_non_duplicates(Span< T > array)
void append_non_duplicates(const T &value)
void fill(const T &value) const
void append_as(ForwardValue &&...value)
int64_t first_index_of_try(const T &value) const
void append_n_times(const T &value, const int64_t n)
TypeConstructMock(const TypeConstructMock &)
TypeConstructMock(TypeConstructMock &&) noexcept
TypeConstructMock & operator=(TypeConstructMock &&other) noexcept
TypeConstructMock & operator=(const TypeConstructMock &other)
local_group_size(16, 16) .push_constant(Type b
TEST(any, DefaultConstructor)
static Vector< int > return_by_value_helper()
_W64 unsigned int uintptr_t
Definition stdint.h:119
__int64 int64_t
Definition stdint.h:89
Vector< RecursiveType, 0 > my_vector
static int magic(const Tex *tex, const float texvec[3], TexResult *texres)
PointerRNA * ptr
Definition wm_files.cc:4126