Blender V5.0
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" /* IWYU pragma: keep. 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_SPAN<int>(vec, Span({3, 4, 5, 8, 9}));
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_SPAN<int>(vec, expected_vec);
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
471TEST(vector, ExtendMoveFromSmallVector)
472{
474 {1, 2, 3, 4, 5},
475 {6, 7, 8},
476 };
478 {9, 10, 11, 12},
479 {13, 14, 15, 16},
480 };
481 const Vector<Vector<uint64_t, 0>> c = {
482 {1, 2, 3, 4, 5},
483 {6, 7, 8},
484 {9, 10, 11, 12},
485 {13, 14, 15, 16},
486 };
487
488 a.extend(std::move(b));
489
490 EXPECT_EQ(a, c);
491 EXPECT_TRUE(b.is_empty());
492}
493
494TEST(vector, ExtendMoveFromUniquePtrVector)
495{
496 Vector<int *> ptr_vec;
497
499 a.append(std::make_unique<int>(0));
500 a.append(std::make_unique<int>(1));
501 a.append(std::make_unique<int>(2));
502
503 for (std::unique_ptr<int> &i : a) {
504 ptr_vec.append(i.get());
505 }
506
508 b.append(std::make_unique<int>(7));
509 b.append(std::make_unique<int>(8));
510 b.append(std::make_unique<int>(9));
511 b.append(std::make_unique<int>(20));
512
513 for (std::unique_ptr<int> &i : b) {
514 ptr_vec.append(i.get());
515 }
516
517 ASSERT_EQ(a.size(), 3);
518 ASSERT_EQ(b.size(), 4);
519
520 a.extend(std::move(b));
521
522 std::array<int, 7> values = {0, 1, 2, 7, 8, 9, 20};
523
524 ASSERT_EQ(size_t(a.size()), values.size());
525 ASSERT_TRUE(b.is_empty());
526 ASSERT_EQ(a.size(), ptr_vec.size());
527
528 for (int64_t i = 0; i < a.size(); i++) {
529 ASSERT_EQ(*a[i], values[size_t(i)]);
530 ASSERT_EQ(a[i].get(), ptr_vec[i]);
531 }
532}
533
535{
536 Vector<int> a{3, 5, 7};
537 EXPECT_EQ(a.last(), 7);
538 EXPECT_EQ(a.last(0), 7);
539 EXPECT_EQ(a.last(1), 5);
540 EXPECT_EQ(a.last(2), 3);
541}
542
543TEST(vector, AppendNTimes)
544{
545 Vector<int> a;
546 a.append_n_times(5, 3);
547 a.append_n_times(2, 2);
548 EXPECT_EQ(a.size(), 5);
549 EXPECT_EQ(a[0], 5);
550 EXPECT_EQ(a[1], 5);
551 EXPECT_EQ(a[2], 5);
552 EXPECT_EQ(a[3], 2);
553 EXPECT_EQ(a[4], 2);
554}
555
556TEST(vector, UniquePtrValue)
557{
559 vec.append(std::make_unique<int>());
560 vec.append(std::make_unique<int>());
561 vec.append(std::make_unique<int>());
562 vec.append(std::make_unique<int>());
563 EXPECT_EQ(vec.size(), 4);
564
565 std::unique_ptr<int> &a = vec.last();
566 std::unique_ptr<int> b = vec.pop_last();
567 vec.remove_and_reorder(0);
568 vec.remove(0);
569 EXPECT_EQ(vec.size(), 1);
570 EXPECT_EQ(vec.append_and_get_index(std::make_unique<int>(4)), 1);
571
572 UNUSED_VARS(a, b);
573}
574
575class TypeConstructMock {
576 public:
577 bool default_constructed = false;
578 bool copy_constructed = false;
579 bool move_constructed = false;
580 bool copy_assigned = false;
581 bool move_assigned = false;
582
584
586
588
590 {
591 if (this == &other) {
592 return *this;
593 }
594
595 copy_assigned = true;
596 return *this;
597 }
598
600 {
601 if (this == &other) {
602 return *this;
603 }
604
605 move_assigned = true;
606 return *this;
607 }
608};
609
610TEST(vector, SizeConstructorCallsDefaultConstructor)
611{
613 EXPECT_TRUE(vec[0].default_constructed);
614 EXPECT_TRUE(vec[1].default_constructed);
615 EXPECT_TRUE(vec[2].default_constructed);
616}
617
618TEST(vector, SizeValueConstructorCallsCopyConstructor)
619{
621 EXPECT_TRUE(vec[0].copy_constructed);
622 EXPECT_TRUE(vec[1].copy_constructed);
623 EXPECT_TRUE(vec[2].copy_constructed);
624}
625
626TEST(vector, AppendCallsCopyConstructor)
627{
629 TypeConstructMock value;
630 vec.append(value);
631 EXPECT_TRUE(vec[0].copy_constructed);
632}
633
634TEST(vector, AppendCallsMoveConstructor)
635{
638 EXPECT_TRUE(vec[0].move_constructed);
639}
640
641TEST(vector, SmallVectorCopyCallsCopyConstructor)
642{
645 EXPECT_TRUE(dst[0].copy_constructed);
646 EXPECT_TRUE(dst[1].copy_constructed);
647}
648
649TEST(vector, LargeVectorCopyCallsCopyConstructor)
650{
653 EXPECT_TRUE(dst[0].copy_constructed);
654 EXPECT_TRUE(dst[1].copy_constructed);
655}
656
657TEST(vector, SmallVectorMoveCallsMoveConstructor)
658{
660 Vector<TypeConstructMock, 2> dst(std::move(src));
661 EXPECT_TRUE(dst[0].move_constructed);
662 EXPECT_TRUE(dst[1].move_constructed);
663}
664
665TEST(vector, LargeVectorMoveCallsNoConstructor)
666{
668 Vector<TypeConstructMock, 2> dst(std::move(src));
669
670 EXPECT_TRUE(dst[0].default_constructed);
671 EXPECT_FALSE(dst[0].move_constructed);
672 EXPECT_FALSE(dst[0].copy_constructed);
673}
674
675TEST(vector, Resize)
676{
677 std::string long_string = "012345678901234567890123456789";
679 EXPECT_EQ(vec.size(), 0);
680 vec.resize(2);
681 EXPECT_EQ(vec.size(), 2);
682 EXPECT_EQ(vec[0], "");
683 EXPECT_EQ(vec[1], "");
684 vec.resize(5, long_string);
685 EXPECT_EQ(vec.size(), 5);
686 EXPECT_EQ(vec[0], "");
687 EXPECT_EQ(vec[1], "");
688 EXPECT_EQ(vec[2], long_string);
689 EXPECT_EQ(vec[3], long_string);
690 EXPECT_EQ(vec[4], long_string);
691 vec.resize(1);
692 EXPECT_EQ(vec.size(), 1);
693 EXPECT_EQ(vec[0], "");
694}
695
696TEST(vector, FirstIndexOf)
697{
698 Vector<int> vec = {2, 3, 5, 7, 5, 9};
699 EXPECT_EQ(vec.first_index_of(2), 0);
700 EXPECT_EQ(vec.first_index_of(5), 2);
701 EXPECT_EQ(vec.first_index_of(9), 5);
702}
703
704TEST(vector, FirstIndexTryOf)
705{
706 Vector<int> vec = {2, 3, 5, 7, 5, 9};
707 EXPECT_EQ(vec.first_index_of_try(2), 0);
708 EXPECT_EQ(vec.first_index_of_try(4), -1);
709 EXPECT_EQ(vec.first_index_of_try(5), 2);
710 EXPECT_EQ(vec.first_index_of_try(9), 5);
711 EXPECT_EQ(vec.first_index_of_try(1), -1);
712}
713
714TEST(vector, OveralignedValues)
715{
717 for (int i = 0; i < 100; i++) {
718 vec.append({});
719 EXPECT_EQ(uintptr_t(&vec.last()) % 512, 0);
720 }
721}
722
723TEST(vector, ConstructVoidPointerVector)
724{
725 int a;
726 float b;
727 double c;
728 Vector<void *> vec = {&a, &b, &c};
729 EXPECT_EQ(vec.size(), 3);
730}
731
733{
734 Vector<int> vec(5);
735 vec.fill(3);
736 EXPECT_EQ(vec.size(), 5u);
737 EXPECT_EQ(vec[0], 3);
738 EXPECT_EQ(vec[1], 3);
739 EXPECT_EQ(vec[2], 3);
740 EXPECT_EQ(vec[3], 3);
741 EXPECT_EQ(vec[4], 3);
742}
743
744TEST(vector, InsertAtBeginning)
745{
746 Vector<int> vec = {1, 2, 3};
747 vec.insert(0, {6, 7});
748 EXPECT_EQ(vec.size(), 5);
749 EXPECT_EQ_SPAN<int>(vec, Span({6, 7, 1, 2, 3}));
750}
751
752TEST(vector, InsertAtEnd)
753{
754 Vector<int> vec = {1, 2, 3};
755 vec.insert(3, {6, 7});
756 EXPECT_EQ(vec.size(), 5);
757 EXPECT_EQ_SPAN<int>(vec, Span({1, 2, 3, 6, 7}));
758}
759
760TEST(vector, InsertInMiddle)
761{
762 Vector<int> vec = {1, 2, 3};
763 vec.insert(1, {6, 7});
764 EXPECT_EQ(vec.size(), 5);
765 EXPECT_EQ_SPAN<int>(vec, Span({1, 6, 7, 2, 3}));
766}
767
768TEST(vector, InsertAtIterator)
769{
770 Vector<std::string> vec = {"1", "2", "3"};
771 Vector<std::string> other_vec = {"hello", "world"};
772 vec.insert(vec.begin() + 1, other_vec.begin(), other_vec.end());
773 EXPECT_EQ(vec.size(), 5);
774 EXPECT_EQ_SPAN<std::string>(vec, Span<std::string>({"1", "hello", "world", "2", "3"}));
775}
776
777TEST(vector, InsertMoveOnlyType)
778{
780 vec.append(std::make_unique<int>(1));
781 vec.append(std::make_unique<int>(2));
782 vec.insert(1, std::make_unique<int>(30));
783 EXPECT_EQ(vec.size(), 3);
784 EXPECT_EQ(*vec[0], 1);
785 EXPECT_EQ(*vec[1], 30);
786 EXPECT_EQ(*vec[2], 2);
787}
788
789TEST(vector, Prepend)
790{
791 Vector<int> vec = {1, 2, 3};
792 vec.prepend({7, 8});
793 EXPECT_EQ(vec.size(), 5);
794 EXPECT_EQ_SPAN<int>(vec, Span({7, 8, 1, 2, 3}));
795}
796
797TEST(vector, PrependString)
798{
799 std::string s = "test";
801 vec.prepend(s);
802 vec.prepend(std::move(s));
803 EXPECT_EQ(vec.size(), 2);
804 EXPECT_EQ(vec[0], "test");
805 EXPECT_EQ(vec[1], "test");
806}
807
808TEST(vector, ReverseIterator)
809{
810 Vector<int> vec = {4, 5, 6, 7};
811 Vector<int> reversed_vec;
812 for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
813 reversed_vec.append(*it);
814 }
815 EXPECT_EQ(reversed_vec.size(), 4);
816 EXPECT_EQ_SPAN<int>(reversed_vec, Span({7, 6, 5, 4}));
817}
818
819TEST(vector, SizeValueConstructorExceptions)
820{
821 ExceptionThrower value;
822 value.throw_during_copy = true;
823 EXPECT_ANY_THROW({ Vector<ExceptionThrower> vec(5, value); });
824}
825
826TEST(vector, SpanConstructorExceptions)
827{
828 std::array<ExceptionThrower, 5> values;
829 values[3].throw_during_copy = true;
830 EXPECT_ANY_THROW({ Vector<ExceptionThrower> vec(values); });
831}
832
833TEST(vector, MoveConstructorExceptions)
834{
836 vec[2].throw_during_move = true;
837 EXPECT_ANY_THROW({ Vector<ExceptionThrower> moved_vector{std::move(vec)}; });
838}
839
840TEST(vector, AppendExceptions)
841{
843 ExceptionThrower *ptr1 = &vec.last();
844 ExceptionThrower value;
845 value.throw_during_copy = true;
846 EXPECT_ANY_THROW({ vec.append(value); });
847 EXPECT_EQ(vec.size(), 2);
848 ExceptionThrower *ptr2 = &vec.last();
849 EXPECT_EQ(ptr1, ptr2);
850}
851
852TEST(vector, ExtendExceptions)
853{
855 std::array<ExceptionThrower, 10> values;
856 values[6].throw_during_copy = true;
857 EXPECT_ANY_THROW({ vec.extend(values); });
858 EXPECT_EQ(vec.size(), 5);
859}
860
861TEST(vector, Insert1Exceptions)
862{
864 std::array<ExceptionThrower, 5> values;
865 values[3].throw_during_copy = true;
866 EXPECT_ANY_THROW({ vec.insert(7, values); });
867}
868
869TEST(vector, Insert2Exceptions)
870{
872 vec.reserve(100);
873 vec[8].throw_during_move = true;
874 std::array<ExceptionThrower, 5> values;
875 EXPECT_ANY_THROW({ vec.insert(3, values); });
876}
877
878TEST(vector, PopLastExceptions)
879{
881 vec.last().throw_during_move = true;
882 EXPECT_ANY_THROW({ vec.pop_last(); }); /* NOLINT: bugprone-throw-keyword-missing */
883 EXPECT_EQ(vec.size(), 10);
884}
885
886TEST(vector, RemoveAndReorderExceptions)
887{
889 vec.last().throw_during_move = true;
890 EXPECT_ANY_THROW({ vec.remove_and_reorder(3); });
891 EXPECT_EQ(vec.size(), 10);
892}
893
894TEST(vector, RemoveExceptions)
895{
897 vec[8].throw_during_move = true;
898 EXPECT_ANY_THROW({ vec.remove(2); });
899 EXPECT_EQ(vec.size(), 10);
900}
901
902TEST(vector, RemoveChunk)
903{
904 Vector<int> vec = {2, 3, 4, 5, 6, 7, 8};
905 EXPECT_EQ(vec.size(), 7);
906 vec.remove(2, 4);
907 EXPECT_EQ(vec.size(), 3);
908 EXPECT_EQ(vec[0], 2);
909 EXPECT_EQ(vec[1], 3);
910 EXPECT_EQ(vec[2], 8);
911 vec.remove(0, 1);
912 EXPECT_EQ(vec.size(), 2);
913 EXPECT_EQ(vec[0], 3);
914 EXPECT_EQ(vec[1], 8);
915 vec.remove(1, 1);
916 EXPECT_EQ(vec.size(), 1);
917 EXPECT_EQ(vec[0], 3);
918 vec.remove(0, 1);
919 EXPECT_EQ(vec.size(), 0);
920 vec.remove(0, 0);
921 EXPECT_EQ(vec.size(), 0);
922}
923
924TEST(vector, RemoveChunkExceptions)
925{
927 vec.remove(1, 3);
928 EXPECT_EQ(vec.size(), 7);
929 vec[5].throw_during_move = true;
930 EXPECT_ANY_THROW({ vec.remove(2, 3); });
931 EXPECT_EQ(vec.size(), 7);
932}
933
937
938TEST(vector, RecursiveStructure)
939{
940 RecursiveType my_recursive_type;
941 my_recursive_type.my_vector.append({});
942}
943
944TEST(vector, FromRaw)
945{
947 data.data = MEM_calloc_arrayN<int>(30, __func__);
948 data.size = 10;
949 data.capacity = 30;
950
951 data.data[0] = 5;
952
953 Vector<int> vec{data};
954 EXPECT_EQ(vec.size(), 10);
955 EXPECT_EQ(vec.capacity(), 30);
956 EXPECT_EQ(vec[0], 5);
957}
958
959TEST(vector, FromRawEmpty)
960{
962 Vector<int> vec{data};
963 EXPECT_TRUE(vec.is_empty());
964}
965
966TEST(vector, ReleaseEmptyInline)
967{
968 Vector<int> vec;
970 EXPECT_EQ(data.data, nullptr);
971}
972
973TEST(vector, ReleaseEmptyAllocated)
974{
975 Vector<int> vec;
976 vec.reserve(100);
977 const int *data_ptr = vec.data();
978 EXPECT_FALSE(vec.is_inline());
979
981 EXPECT_TRUE(vec.is_inline());
982
983 EXPECT_EQ(data.data, data_ptr);
984 EXPECT_NE(data.data, nullptr);
985 EXPECT_EQ(data.size, 0);
986 EXPECT_EQ(data.capacity, 100);
987 MEM_freeN(data.data);
988}
989
990TEST(vector, ReleaseNonEmptyInline)
991{
992 Vector<int> vec = {1, 2};
993 const int *inline_data_ptr = vec.data();
994 EXPECT_EQ(inline_data_ptr[0], 1);
995 EXPECT_TRUE(vec.is_inline());
996
998 EXPECT_TRUE(vec.is_inline());
999 EXPECT_TRUE(vec.is_empty());
1000
1001 EXPECT_NE(data.data, inline_data_ptr);
1002 EXPECT_EQ(data.size, 2);
1003 MEM_freeN(data.data);
1004}
1005
1006TEST(vector, ReleaseAllocated)
1007{
1008 Vector<int> vec(50, 3);
1009 const int *data_ptr = vec.data();
1010 EXPECT_FALSE(vec.is_inline());
1011 EXPECT_EQ(vec[0], 3);
1012
1014 EXPECT_TRUE(vec.is_inline());
1015 EXPECT_TRUE(vec.is_empty());
1016
1017 EXPECT_EQ(data.data, data_ptr);
1018 EXPECT_EQ(data.size, 50);
1019 EXPECT_EQ(data.data[0], 3);
1020 MEM_freeN(data.data);
1021}
1022
1023} // namespace blender::tests
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
#define UNUSED_VARS(...)
BMesh const char void * data
return true
ATTR_WARN_UNUSED_RESULT const BMVert * v
long long int int64_t
constexpr const T * begin() const
Definition BLI_span.hh:220
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
bool is_inline() const
void append_as(ForwardValue &&...value)
VectorData< T, Allocator > release()
int64_t capacity() const
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)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static VectorList< int > return_by_value_helper()
TEST(blf_load, load)
Definition BLF_tests.cc:34
Vector< RecursiveType, 0 > my_vector
i
Definition text_draw.cc:230
static int magic(const Tex *tex, const float texvec[3], TexResult *texres)
PointerRNA * ptr
Definition wm_files.cc:4238