1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_containers/vector.h"
16
17 #include <cstddef>
18
19 #include "gtest/gtest.h"
20
21 namespace pw {
22 namespace {
23
24 // Since pw::Vector<T, N> downcasts to a pw::Vector<T, 0>, ensure that the
25 // alignment doesn't change.
26 static_assert(alignof(Vector<std::max_align_t, 0>) ==
27 alignof(Vector<std::max_align_t, 1>));
28
29 struct CopyOnly {
CopyOnlypw::__anon11276ea20111::CopyOnly30 explicit CopyOnly(int val) : value(val) {}
31
CopyOnlypw::__anon11276ea20111::CopyOnly32 CopyOnly(const CopyOnly& other) { value = other.value; }
33
operator =pw::__anon11276ea20111::CopyOnly34 CopyOnly& operator=(const CopyOnly& other) {
35 value = other.value;
36 return *this;
37 }
38
39 CopyOnly(CopyOnly&&) = delete;
40
41 int value;
42 };
43
44 struct MoveOnly {
MoveOnlypw::__anon11276ea20111::MoveOnly45 explicit MoveOnly(int val) : value(val) {}
46
47 MoveOnly(const MoveOnly&) = delete;
48
MoveOnlypw::__anon11276ea20111::MoveOnly49 MoveOnly(MoveOnly&& other) {
50 value = other.value;
51 other.value = kDeleted;
52 }
53
54 static constexpr int kDeleted = -1138;
55
56 int value;
57 };
58
59 struct Counter {
60 static int created;
61 static int destroyed;
62 static int moved;
63
Resetpw::__anon11276ea20111::Counter64 static void Reset() { created = destroyed = moved = 0; }
65
Counterpw::__anon11276ea20111::Counter66 Counter() : value(0) { created += 1; }
67
Counterpw::__anon11276ea20111::Counter68 Counter(int val) : value(val) { created += 1; }
69
Counterpw::__anon11276ea20111::Counter70 Counter(const Counter& other) : value(other.value) { created += 1; }
71
Counterpw::__anon11276ea20111::Counter72 Counter(Counter&& other) : value(other.value) {
73 other.value = 0;
74 moved += 1;
75 }
76
~Counterpw::__anon11276ea20111::Counter77 ~Counter() { destroyed += 1; }
78
79 int value;
80 };
81
82 int Counter::created = 0;
83 int Counter::destroyed = 0;
84 int Counter::moved = 0;
85
TEST(Vector,Construct_NoArg)86 TEST(Vector, Construct_NoArg) {
87 Vector<int, 3> vector;
88 EXPECT_TRUE(vector.empty());
89 }
90
TEST(Vector,Construct_MultipleCopies)91 TEST(Vector, Construct_MultipleCopies) {
92 Vector<int, 3> vector(3, 123);
93
94 EXPECT_EQ(vector.size(), 3u);
95 EXPECT_EQ(vector[0], 123);
96 EXPECT_EQ(vector[1], 123);
97 EXPECT_EQ(vector[2], 123);
98 }
99
TEST(Vector,Construct_DefaultSize)100 TEST(Vector, Construct_DefaultSize) {
101 Vector<int, 3> vector(3);
102
103 EXPECT_EQ(vector.size(), 3u);
104 EXPECT_EQ(vector[0], 0);
105 EXPECT_EQ(vector[1], 0);
106 EXPECT_EQ(vector[2], 0);
107 }
108
TEST(Vector,Construct_Iterators)109 TEST(Vector, Construct_Iterators) {
110 std::array array{1, 2, 3, 4, 5};
111
112 Vector<int, 64> vector(array.begin(), array.end());
113
114 EXPECT_EQ(vector.size(), array.size());
115 for (size_t i = 0; i < array.size(); ++i) {
116 EXPECT_EQ(vector[i], array[i]);
117 }
118 }
119
TEST(Vector,Construct_Copy)120 TEST(Vector, Construct_Copy) {
121 CopyOnly origin(5);
122 Vector<CopyOnly, 10> origin_vector(3, origin);
123
124 Vector<CopyOnly, 100> vector(origin_vector);
125
126 EXPECT_EQ(3u, vector.size());
127
128 for (size_t i = 0; i < vector.size(); ++i) {
129 EXPECT_EQ(vector[i].value, origin.value);
130 }
131 }
132
TEST(Vector,Construct_Move)133 TEST(Vector, Construct_Move) {
134 Vector<MoveOnly, 10> origin_vector;
135
136 for (int i = 0; i < 5; ++i) {
137 origin_vector.emplace_back(421);
138 }
139
140 Vector<MoveOnly, 100> vector(std::move(origin_vector));
141
142 EXPECT_EQ(5u, vector.size());
143
144 for (size_t i = 0; i < vector.size(); ++i) {
145 EXPECT_EQ(vector[i].value, 421);
146 }
147
148 // NOLINTNEXTLINE(bugprone-use-after-move)
149 for (size_t i = 0; i < origin_vector.size(); ++i) {
150 EXPECT_EQ(origin_vector[i].value, MoveOnly::kDeleted);
151 }
152 }
153
TEST(Vector,Construct_InitializerList)154 TEST(Vector, Construct_InitializerList) {
155 Vector<int, 3> vector{100, 200};
156 EXPECT_EQ(vector.size(), 2u);
157 EXPECT_EQ(vector[0], 100);
158 EXPECT_EQ(vector[1], 200);
159 }
160
TEST(Vector,Destruct_ZeroLength)161 TEST(Vector, Destruct_ZeroLength) {
162 Counter::Reset();
163
164 { Vector<Counter, 0> destroyed; }
165 EXPECT_EQ(Counter::created, 0);
166 EXPECT_EQ(Counter::destroyed, 0);
167 }
168
TEST(Vector,Destruct_Empty)169 TEST(Vector, Destruct_Empty) {
170 Counter::Reset();
171
172 { Vector<Counter, 128> destroyed; }
173 EXPECT_EQ(Counter::created, 0);
174 EXPECT_EQ(Counter::destroyed, 0);
175 }
176
TEST(Vector,Destruct_MultpileEntries)177 TEST(Vector, Destruct_MultpileEntries) {
178 Counter value;
179 Counter::Reset();
180
181 { Vector<Counter, 128> destroyed(100, value); }
182
183 EXPECT_EQ(Counter::created, 100);
184 EXPECT_EQ(Counter::destroyed, 100);
185 }
186
TEST(Vector,Assign_Copy_SmallerToLarger)187 TEST(Vector, Assign_Copy_SmallerToLarger) {
188 CopyOnly origin(5);
189 Vector<CopyOnly, 3> origin_vector(3, origin);
190
191 Vector<CopyOnly, 2> vector;
192 vector = origin_vector;
193
194 EXPECT_EQ(2u, vector.size());
195
196 for (size_t i = 0; i < vector.size(); ++i) {
197 EXPECT_EQ(vector[i].value, origin.value);
198 }
199 }
200
TEST(Vector,Assign_DifferentMaxSize_Copy)201 TEST(Vector, Assign_DifferentMaxSize_Copy) {
202 const Vector<int, 10> origin_vector = {1, 1, 2, 3};
203
204 Vector<int, 100> vector;
205 vector = origin_vector;
206
207 ASSERT_EQ(4u, vector.size());
208 EXPECT_EQ(1, vector[0]);
209 EXPECT_EQ(1, vector[1]);
210 EXPECT_EQ(2, vector[2]);
211 EXPECT_EQ(3, vector[3]);
212 }
213
TEST(Vector,Assign_SameMaxSize_Copy)214 TEST(Vector, Assign_SameMaxSize_Copy) {
215 const Vector<int, 10> origin_vector = {1, 1, 2, 3};
216
217 Vector<int, 10> vector;
218 vector = origin_vector;
219
220 ASSERT_EQ(4u, vector.size());
221 EXPECT_EQ(1, vector[0]);
222 EXPECT_EQ(1, vector[1]);
223 EXPECT_EQ(2, vector[2]);
224 EXPECT_EQ(3, vector[3]);
225 }
226
TEST(Vector,Assign_Generic_Copy)227 TEST(Vector, Assign_Generic_Copy) {
228 const Vector<int, 10> origin_vector = {1, 1, 2, 3};
229
230 Vector<int, 10> vector;
231 Vector<int>& ref = vector;
232 ref = static_cast<const Vector<int>&>(origin_vector);
233
234 ASSERT_EQ(4u, vector.size());
235 EXPECT_EQ(1, vector[0]);
236 EXPECT_EQ(1, vector[1]);
237 EXPECT_EQ(2, vector[2]);
238 EXPECT_EQ(3, vector[3]);
239 }
240
TEST(Vector,Assign_Move)241 TEST(Vector, Assign_Move) {
242 Vector<MoveOnly, 10> origin_vector;
243
244 for (int i = 0; i < 5; ++i) {
245 origin_vector.emplace_back(421);
246 }
247
248 Vector<MoveOnly, 10> vector;
249 vector = std::move(origin_vector);
250
251 EXPECT_EQ(5u, vector.size());
252
253 for (size_t i = 0; i < vector.size(); ++i) {
254 EXPECT_EQ(vector[i].value, 421);
255 }
256
257 // NOLINTNEXTLINE(bugprone-use-after-move)
258 for (size_t i = 0; i < origin_vector.size(); ++i) {
259 EXPECT_EQ(origin_vector[i].value, MoveOnly::kDeleted);
260 }
261 }
262
TEST(Vector,Assign_InitializerList)263 TEST(Vector, Assign_InitializerList) {
264 Vector<int, 4> vector;
265 vector = {1, 3, 5, 7, 9};
266
267 EXPECT_EQ(4u, vector.size());
268
269 EXPECT_EQ(1, vector[0]);
270 EXPECT_EQ(3, vector[1]);
271 EXPECT_EQ(5, vector[2]);
272 EXPECT_EQ(7, vector[3]);
273 }
274
TEST(Vector,Access_ZeroLength)275 TEST(Vector, Access_ZeroLength) {
276 Vector<Counter, 0> vector;
277
278 EXPECT_EQ(0u, vector.size());
279 EXPECT_EQ(0u, vector.max_size());
280 EXPECT_TRUE(vector.empty());
281 EXPECT_TRUE(vector.full());
282
283 for (auto& item : vector) {
284 (void)item;
285 FAIL();
286 }
287 }
288
TEST(Vector,Access_Data_ArrayLocationIsIndependentOfMaxSize)289 TEST(Vector, Access_Data_ArrayLocationIsIndependentOfMaxSize) {
290 Vector<int, 10> vector;
291 Vector<int>& base = static_cast<Vector<int>&>(vector);
292
293 EXPECT_EQ(vector.data(), base.data());
294 EXPECT_EQ(vector.data(), (static_cast<Vector<int, 0>&>(base).data()));
295 EXPECT_EQ(vector.data(), (static_cast<Vector<int, 1>&>(base).data()));
296 }
297
TEST(Vector,Modify_Clear)298 TEST(Vector, Modify_Clear) {
299 Counter::Reset();
300
301 Vector<Counter, 100> vector;
302 vector.emplace_back();
303 vector.emplace_back();
304 vector.emplace_back();
305
306 vector.clear();
307
308 EXPECT_EQ(3, Counter::created);
309 EXPECT_EQ(3, Counter::destroyed);
310 }
311
TEST(Vector,Modify_PushBack_Copy)312 TEST(Vector, Modify_PushBack_Copy) {
313 Counter value(99);
314 Counter::Reset();
315
316 {
317 Vector<Counter, 10> vector;
318 vector.push_back(value);
319
320 EXPECT_EQ(vector.size(), 1u);
321 EXPECT_EQ(vector.front().value, 99);
322 }
323
324 EXPECT_EQ(Counter::created, 1);
325 EXPECT_EQ(Counter::destroyed, 1);
326 }
327
TEST(Vector,Modify_PushBack_Move)328 TEST(Vector, Modify_PushBack_Move) {
329 Counter::Reset();
330
331 {
332 Counter value(99);
333 Vector<Counter, 10> vector;
334 vector.push_back(std::move(value));
335
336 EXPECT_EQ(vector.size(), 1u);
337 EXPECT_EQ(vector.front().value, 99);
338 // NOLINTNEXTLINE(bugprone-use-after-move)
339 EXPECT_EQ(value.value, 0);
340 }
341
342 EXPECT_EQ(Counter::created, 1);
343 EXPECT_EQ(Counter::destroyed, 2);
344 EXPECT_EQ(Counter::moved, 1);
345 }
346
TEST(Vector,Modify_EmplaceBack)347 TEST(Vector, Modify_EmplaceBack) {
348 Counter::Reset();
349
350 {
351 Vector<Counter, 10> vector;
352 vector.emplace_back(314);
353
354 EXPECT_EQ(vector.size(), 1u);
355 EXPECT_EQ(vector.front().value, 314);
356 }
357
358 EXPECT_EQ(Counter::created, 1);
359 EXPECT_EQ(Counter::destroyed, 1);
360 }
361
TEST(Vector,Modify_Resize_Larger)362 TEST(Vector, Modify_Resize_Larger) {
363 Vector<CopyOnly, 10> vector(1, CopyOnly(123));
364 vector.resize(3, CopyOnly(123));
365
366 EXPECT_EQ(vector.size(), 3u);
367 for (auto& i : vector) {
368 EXPECT_EQ(i.value, 123);
369 }
370 }
371
TEST(Vector,Modify_Resize_LargerThanMax)372 TEST(Vector, Modify_Resize_LargerThanMax) {
373 Vector<CopyOnly, 10> vector;
374 vector.resize(1000, CopyOnly(123));
375
376 EXPECT_EQ(vector.size(), 10u);
377 for (auto& i : vector) {
378 EXPECT_EQ(i.value, 123);
379 }
380 }
381
TEST(Vector,Modify_Resize_Smaller)382 TEST(Vector, Modify_Resize_Smaller) {
383 Vector<CopyOnly, 10> vector(9, CopyOnly(123));
384 vector.resize(3, CopyOnly(123));
385
386 EXPECT_EQ(vector.size(), 3u);
387 for (auto& i : vector) {
388 EXPECT_EQ(i.value, 123);
389 }
390 }
391
TEST(Vector,Modify_PopBack)392 TEST(Vector, Modify_PopBack) {
393 Vector<Counter, 10> vector({Counter(1), Counter(2), Counter(3)});
394 Counter::Reset();
395
396 vector.pop_back();
397
398 EXPECT_EQ(vector.size(), 2u);
399 EXPECT_EQ(vector[0].value, 1);
400 EXPECT_EQ(vector[1].value, 2);
401
402 EXPECT_EQ(Counter::created, 0);
403 EXPECT_EQ(Counter::destroyed, 1);
404 }
405
TEST(Vector,Modify_Resize_Zero)406 TEST(Vector, Modify_Resize_Zero) {
407 Vector<CopyOnly, 10> vector(10, CopyOnly(123));
408 vector.resize(0, CopyOnly(123));
409
410 EXPECT_EQ(vector.size(), 0u);
411 }
412
TEST(Vector,Generic)413 TEST(Vector, Generic) {
414 Vector<int, 10> vector{1, 2, 3, 4, 5};
415
416 Vector<int>& generic_vector(vector);
417
418 EXPECT_EQ(generic_vector.size(), vector.size());
419 EXPECT_EQ(generic_vector.max_size(), vector.max_size());
420
421 int i = 0;
422 for (int value : vector) {
423 EXPECT_EQ(value, generic_vector[i]);
424 i += 1;
425 }
426
427 i = 0;
428 for (int value : generic_vector) {
429 EXPECT_EQ(vector[i], value);
430 i += 1;
431 }
432 }
433
434 // Test that Vector<T> is trivially destructible when its type is.
435 static_assert(std::is_trivially_destructible_v<Vector<int>>);
436 static_assert(std::is_trivially_destructible_v<Vector<int, 4>>);
437
438 static_assert(std::is_trivially_destructible_v<MoveOnly>);
439 static_assert(std::is_trivially_destructible_v<Vector<MoveOnly>>);
440 static_assert(std::is_trivially_destructible_v<Vector<MoveOnly, 1>>);
441
442 static_assert(std::is_trivially_destructible_v<CopyOnly>);
443 static_assert(std::is_trivially_destructible_v<Vector<CopyOnly>>);
444 static_assert(std::is_trivially_destructible_v<Vector<CopyOnly, 99>>);
445
446 static_assert(!std::is_trivially_destructible_v<Counter>);
447 static_assert(!std::is_trivially_destructible_v<Vector<Counter>>);
448 static_assert(!std::is_trivially_destructible_v<Vector<Counter, 99>>);
449
450 } // namespace
451 } // namespace pw
452