blob: 94711140b10e1293928defd7807694bd8a2efef6 [file] [log] [blame]
Wyatt Hepler76293e32020-02-07 18:07:19 -08001// 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
Wyatt Heplercafad402020-04-16 15:31:04 -070017#include <cstddef>
Wyatt Hepler76293e32020-02-07 18:07:19 -080018
19#include "gtest/gtest.h"
20
21namespace pw {
22namespace {
23
Wyatt Heplercafad402020-04-16 15:31:04 -070024// Since pw::Vector<T, N> downcasts to a pw::Vector<T, 0>, ensure that the
25// alignment doesn't change.
26static_assert(alignof(Vector<std::max_align_t, 0>) ==
27 alignof(Vector<std::max_align_t, 1>));
28
Wyatt Hepler76293e32020-02-07 18:07:19 -080029struct CopyOnly {
Armando Montanez888370d2020-05-01 18:29:22 -070030 explicit CopyOnly(int val) : value(val) {}
Wyatt Hepler76293e32020-02-07 18:07:19 -080031
32 CopyOnly(const CopyOnly& other) { value = other.value; }
33
34 CopyOnly& operator=(const CopyOnly& other) {
35 value = other.value;
36 return *this;
37 }
38
39 CopyOnly(CopyOnly&&) = delete;
40
41 int value;
42};
43
44struct MoveOnly {
Armando Montanez888370d2020-05-01 18:29:22 -070045 explicit MoveOnly(int val) : value(val) {}
Wyatt Hepler76293e32020-02-07 18:07:19 -080046
47 MoveOnly(const MoveOnly&) = delete;
48
49 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
59struct Counter {
60 static int created;
61 static int destroyed;
62 static int moved;
63
64 static void Reset() { created = destroyed = moved = 0; }
65
66 Counter() : value(0) { created += 1; }
67
68 Counter(int val) : value(val) { created += 1; }
69
70 Counter(const Counter& other) : value(other.value) { created += 1; }
71
72 Counter(Counter&& other) : value(other.value) {
73 other.value = 0;
74 moved += 1;
75 }
76
77 ~Counter() { destroyed += 1; }
78
79 int value;
80};
81
82int Counter::created = 0;
83int Counter::destroyed = 0;
84int Counter::moved = 0;
85
86TEST(Vector, Construct_NoArg) {
87 Vector<int, 3> vector;
88 EXPECT_TRUE(vector.empty());
89}
90
91TEST(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
100TEST(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
109TEST(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
120TEST(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
133TEST(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 for (size_t i = 0; i < origin_vector.size(); ++i) {
149 EXPECT_EQ(origin_vector[i].value, MoveOnly::kDeleted);
150 }
151}
152
153TEST(Vector, Construct_InitializerList) {
154 Vector<int, 3> vector{100, 200};
155 EXPECT_EQ(vector.size(), 2u);
156 EXPECT_EQ(vector[0], 100);
157 EXPECT_EQ(vector[1], 200);
158}
159
160TEST(Vector, Destruct_ZeroLength) {
161 Counter::Reset();
162
163 { Vector<Counter, 0> destroyed; }
164 EXPECT_EQ(Counter::created, 0);
165 EXPECT_EQ(Counter::destroyed, 0);
166}
167
168TEST(Vector, Destruct_Empty) {
169 Counter::Reset();
170
171 { Vector<Counter, 128> destroyed; }
172 EXPECT_EQ(Counter::created, 0);
173 EXPECT_EQ(Counter::destroyed, 0);
174}
175
176TEST(Vector, Destruct_MultpileEntries) {
177 Counter value;
178 Counter::Reset();
179
180 { Vector<Counter, 128> destroyed(100, value); }
181
182 EXPECT_EQ(Counter::created, 100);
183 EXPECT_EQ(Counter::destroyed, 100);
184}
185
186TEST(Vector, Assign_Copy_SmallerToLarger) {
187 CopyOnly origin(5);
188 Vector<CopyOnly, 3> origin_vector(3, origin);
189
190 Vector<CopyOnly, 2> vector;
191 vector = origin_vector;
192
193 EXPECT_EQ(2u, vector.size());
194
195 for (size_t i = 0; i < vector.size(); ++i) {
196 EXPECT_EQ(vector[i].value, origin.value);
197 }
198}
199
200TEST(Vector, Assign_DifferentMaxSize_Copy) {
201 const Vector<int, 10> origin_vector = {1, 1, 2, 3};
202
203 Vector<int, 100> vector;
204 vector = origin_vector;
205
206 ASSERT_EQ(4u, vector.size());
207 EXPECT_EQ(1, vector[0]);
208 EXPECT_EQ(1, vector[1]);
209 EXPECT_EQ(2, vector[2]);
210 EXPECT_EQ(3, vector[3]);
211}
212
213TEST(Vector, Assign_SameMaxSize_Copy) {
214 const Vector<int, 10> origin_vector = {1, 1, 2, 3};
215
216 Vector<int, 10> vector;
217 vector = origin_vector;
218
219 ASSERT_EQ(4u, vector.size());
220 EXPECT_EQ(1, vector[0]);
221 EXPECT_EQ(1, vector[1]);
222 EXPECT_EQ(2, vector[2]);
223 EXPECT_EQ(3, vector[3]);
224}
225
226TEST(Vector, Assign_Generic_Copy) {
227 const Vector<int, 10> origin_vector = {1, 1, 2, 3};
228
229 Vector<int, 10> vector;
230 Vector<int>& ref = vector;
231 ref = static_cast<const Vector<int>&>(origin_vector);
232
233 ASSERT_EQ(4u, vector.size());
234 EXPECT_EQ(1, vector[0]);
235 EXPECT_EQ(1, vector[1]);
236 EXPECT_EQ(2, vector[2]);
237 EXPECT_EQ(3, vector[3]);
238}
239
240TEST(Vector, Assign_Move) {
241 Vector<MoveOnly, 10> origin_vector;
242
243 for (int i = 0; i < 5; ++i) {
244 origin_vector.emplace_back(421);
245 }
246
247 Vector<MoveOnly, 10> vector;
248 vector = std::move(origin_vector);
249
250 EXPECT_EQ(5u, vector.size());
251
252 for (size_t i = 0; i < vector.size(); ++i) {
253 EXPECT_EQ(vector[i].value, 421);
254 }
255
256 for (size_t i = 0; i < origin_vector.size(); ++i) {
257 EXPECT_EQ(origin_vector[i].value, MoveOnly::kDeleted);
258 }
259}
260
261TEST(Vector, Assign_InitializerList) {
262 Vector<int, 4> vector;
263 vector = {1, 3, 5, 7, 9};
264
265 EXPECT_EQ(4u, vector.size());
266
267 EXPECT_EQ(1, vector[0]);
268 EXPECT_EQ(3, vector[1]);
269 EXPECT_EQ(5, vector[2]);
270 EXPECT_EQ(7, vector[3]);
271}
272
273TEST(Vector, Access_ZeroLength) {
274 Vector<Counter, 0> vector;
275
276 EXPECT_EQ(0u, vector.size());
277 EXPECT_EQ(0u, vector.max_size());
278 EXPECT_TRUE(vector.empty());
279 EXPECT_TRUE(vector.full());
280
281 for (auto& item : vector) {
282 (void)item;
283 FAIL();
284 }
285}
286
287TEST(Vector, Access_Data_ArrayLocationIsIndependentOfMaxSize) {
288 Vector<int, 10> vector;
289 Vector<int>& base = static_cast<Vector<int>&>(vector);
290
291 EXPECT_EQ(vector.data(), base.data());
292 EXPECT_EQ(vector.data(), (static_cast<Vector<int, 0>&>(base).data()));
293 EXPECT_EQ(vector.data(), (static_cast<Vector<int, 1>&>(base).data()));
Wyatt Hepler76293e32020-02-07 18:07:19 -0800294}
295
296TEST(Vector, Modify_Clear) {
297 Counter::Reset();
298
299 Vector<Counter, 100> vector;
300 vector.emplace_back();
301 vector.emplace_back();
302 vector.emplace_back();
303
304 vector.clear();
305
306 EXPECT_EQ(3, Counter::created);
307 EXPECT_EQ(3, Counter::destroyed);
308}
309
310TEST(Vector, Modify_PushBack_Copy) {
311 Counter value(99);
312 Counter::Reset();
313
314 {
315 Vector<Counter, 10> vector;
316 vector.push_back(value);
317
318 EXPECT_EQ(vector.size(), 1u);
319 EXPECT_EQ(vector.front().value, 99);
320 }
321
322 EXPECT_EQ(Counter::created, 1);
323 EXPECT_EQ(Counter::destroyed, 1);
324}
325
326TEST(Vector, Modify_PushBack_Move) {
327 Counter::Reset();
328
329 {
330 Counter value(99);
331 Vector<Counter, 10> vector;
332 vector.push_back(std::move(value));
333
334 EXPECT_EQ(vector.size(), 1u);
335 EXPECT_EQ(vector.front().value, 99);
336 EXPECT_EQ(value.value, 0);
337 }
338
339 EXPECT_EQ(Counter::created, 1);
340 EXPECT_EQ(Counter::destroyed, 2);
341 EXPECT_EQ(Counter::moved, 1);
342}
343
344TEST(Vector, Modify_EmplaceBack) {
345 Counter::Reset();
346
347 {
348 Vector<Counter, 10> vector;
349 vector.emplace_back(314);
350
351 EXPECT_EQ(vector.size(), 1u);
352 EXPECT_EQ(vector.front().value, 314);
353 }
354
355 EXPECT_EQ(Counter::created, 1);
356 EXPECT_EQ(Counter::destroyed, 1);
357}
358
359TEST(Vector, Modify_Resize_Larger) {
360 Vector<CopyOnly, 10> vector(1, CopyOnly(123));
361 vector.resize(3, CopyOnly(123));
362
363 EXPECT_EQ(vector.size(), 3u);
364 for (auto& i : vector) {
365 EXPECT_EQ(i.value, 123);
366 }
367}
368
369TEST(Vector, Modify_Resize_LargerThanMax) {
370 Vector<CopyOnly, 10> vector;
371 vector.resize(1000, CopyOnly(123));
372
373 EXPECT_EQ(vector.size(), 10u);
374 for (auto& i : vector) {
375 EXPECT_EQ(i.value, 123);
376 }
377}
378
379TEST(Vector, Modify_Resize_Smaller) {
380 Vector<CopyOnly, 10> vector(9, CopyOnly(123));
381 vector.resize(3, CopyOnly(123));
382
383 EXPECT_EQ(vector.size(), 3u);
384 for (auto& i : vector) {
385 EXPECT_EQ(i.value, 123);
386 }
387}
388
389TEST(Vector, Modify_PopBack) {
390 Vector<Counter, 10> vector({Counter(1), Counter(2), Counter(3)});
391 Counter::Reset();
392
393 vector.pop_back();
394
395 EXPECT_EQ(vector.size(), 2u);
396 EXPECT_EQ(vector[0].value, 1);
397 EXPECT_EQ(vector[1].value, 2);
398
399 EXPECT_EQ(Counter::created, 0);
400 EXPECT_EQ(Counter::destroyed, 1);
401}
402
403TEST(Vector, Modify_Resize_Zero) {
404 Vector<CopyOnly, 10> vector(10, CopyOnly(123));
405 vector.resize(0, CopyOnly(123));
406
407 EXPECT_EQ(vector.size(), 0u);
408}
409
410TEST(Vector, Generic) {
411 Vector<int, 10> vector{1, 2, 3, 4, 5};
412
413 Vector<int>& generic_vector(vector);
414
415 EXPECT_EQ(generic_vector.size(), vector.size());
416 EXPECT_EQ(generic_vector.max_size(), vector.max_size());
417
418 int i = 0;
419 for (int value : vector) {
420 EXPECT_EQ(value, generic_vector[i]);
421 i += 1;
422 }
423
424 i = 0;
425 for (int value : generic_vector) {
426 EXPECT_EQ(vector[i], value);
427 i += 1;
428 }
429}
430
Wyatt Hepler35ddc652021-03-22 10:30:29 -0700431// Test that Vector<T> is trivially destructible when its type is.
432static_assert(std::is_trivially_destructible_v<Vector<int>>);
433static_assert(std::is_trivially_destructible_v<Vector<int, 4>>);
434
435static_assert(std::is_trivially_destructible_v<MoveOnly>);
436static_assert(std::is_trivially_destructible_v<Vector<MoveOnly>>);
437static_assert(std::is_trivially_destructible_v<Vector<MoveOnly, 1>>);
438
439static_assert(std::is_trivially_destructible_v<CopyOnly>);
440static_assert(std::is_trivially_destructible_v<Vector<CopyOnly>>);
441static_assert(std::is_trivially_destructible_v<Vector<CopyOnly, 99>>);
442
443static_assert(!std::is_trivially_destructible_v<Counter>);
444static_assert(!std::is_trivially_destructible_v<Vector<Counter>>);
445static_assert(!std::is_trivially_destructible_v<Vector<Counter, 99>>);
446
Wyatt Hepler76293e32020-02-07 18:07:19 -0800447} // namespace
448} // namespace pw