blob: 5e214d13e7f37e86ae19c5c157e406ebbf74e1c3 [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
17#include <vector>
18
19#include "gtest/gtest.h"
20
21namespace pw {
22namespace {
23
24struct CopyOnly {
25 explicit CopyOnly(int value) : value(value) {}
26
27 CopyOnly(const CopyOnly& other) { value = other.value; }
28
29 CopyOnly& operator=(const CopyOnly& other) {
30 value = other.value;
31 return *this;
32 }
33
34 CopyOnly(CopyOnly&&) = delete;
35
36 int value;
37};
38
39struct MoveOnly {
40 explicit MoveOnly(int value) : value(value) {}
41
42 MoveOnly(const MoveOnly&) = delete;
43
44 MoveOnly(MoveOnly&& other) {
45 value = other.value;
46 other.value = kDeleted;
47 }
48
49 static constexpr int kDeleted = -1138;
50
51 int value;
52};
53
54struct Counter {
55 static int created;
56 static int destroyed;
57 static int moved;
58
59 static void Reset() { created = destroyed = moved = 0; }
60
61 Counter() : value(0) { created += 1; }
62
63 Counter(int val) : value(val) { created += 1; }
64
65 Counter(const Counter& other) : value(other.value) { created += 1; }
66
67 Counter(Counter&& other) : value(other.value) {
68 other.value = 0;
69 moved += 1;
70 }
71
72 ~Counter() { destroyed += 1; }
73
74 int value;
75};
76
77int Counter::created = 0;
78int Counter::destroyed = 0;
79int Counter::moved = 0;
80
81TEST(Vector, Construct_NoArg) {
82 Vector<int, 3> vector;
83 EXPECT_TRUE(vector.empty());
84}
85
86TEST(Vector, Construct_MultipleCopies) {
87 Vector<int, 3> vector(3, 123);
88
89 EXPECT_EQ(vector.size(), 3u);
90 EXPECT_EQ(vector[0], 123);
91 EXPECT_EQ(vector[1], 123);
92 EXPECT_EQ(vector[2], 123);
93}
94
95TEST(Vector, Construct_DefaultSize) {
96 Vector<int, 3> vector(3);
97
98 EXPECT_EQ(vector.size(), 3u);
99 EXPECT_EQ(vector[0], 0);
100 EXPECT_EQ(vector[1], 0);
101 EXPECT_EQ(vector[2], 0);
102}
103
104TEST(Vector, Construct_Iterators) {
105 std::array array{1, 2, 3, 4, 5};
106
107 Vector<int, 64> vector(array.begin(), array.end());
108
109 EXPECT_EQ(vector.size(), array.size());
110 for (size_t i = 0; i < array.size(); ++i) {
111 EXPECT_EQ(vector[i], array[i]);
112 }
113}
114
115TEST(Vector, Construct_Copy) {
116 CopyOnly origin(5);
117 Vector<CopyOnly, 10> origin_vector(3, origin);
118
119 Vector<CopyOnly, 100> vector(origin_vector);
120
121 EXPECT_EQ(3u, vector.size());
122
123 for (size_t i = 0; i < vector.size(); ++i) {
124 EXPECT_EQ(vector[i].value, origin.value);
125 }
126}
127
128TEST(Vector, Construct_Move) {
129 Vector<MoveOnly, 10> origin_vector;
130
131 for (int i = 0; i < 5; ++i) {
132 origin_vector.emplace_back(421);
133 }
134
135 Vector<MoveOnly, 100> vector(std::move(origin_vector));
136
137 EXPECT_EQ(5u, vector.size());
138
139 for (size_t i = 0; i < vector.size(); ++i) {
140 EXPECT_EQ(vector[i].value, 421);
141 }
142
143 for (size_t i = 0; i < origin_vector.size(); ++i) {
144 EXPECT_EQ(origin_vector[i].value, MoveOnly::kDeleted);
145 }
146}
147
148TEST(Vector, Construct_InitializerList) {
149 Vector<int, 3> vector{100, 200};
150 EXPECT_EQ(vector.size(), 2u);
151 EXPECT_EQ(vector[0], 100);
152 EXPECT_EQ(vector[1], 200);
153}
154
155TEST(Vector, Destruct_ZeroLength) {
156 Counter::Reset();
157
158 { Vector<Counter, 0> destroyed; }
159 EXPECT_EQ(Counter::created, 0);
160 EXPECT_EQ(Counter::destroyed, 0);
161}
162
163TEST(Vector, Destruct_Empty) {
164 Counter::Reset();
165
166 { Vector<Counter, 128> destroyed; }
167 EXPECT_EQ(Counter::created, 0);
168 EXPECT_EQ(Counter::destroyed, 0);
169}
170
171TEST(Vector, Destruct_MultpileEntries) {
172 Counter value;
173 Counter::Reset();
174
175 { Vector<Counter, 128> destroyed(100, value); }
176
177 EXPECT_EQ(Counter::created, 100);
178 EXPECT_EQ(Counter::destroyed, 100);
179}
180
181TEST(Vector, Assign_Copy_SmallerToLarger) {
182 CopyOnly origin(5);
183 Vector<CopyOnly, 3> origin_vector(3, origin);
184
185 Vector<CopyOnly, 2> vector;
186 vector = origin_vector;
187
188 EXPECT_EQ(2u, vector.size());
189
190 for (size_t i = 0; i < vector.size(); ++i) {
191 EXPECT_EQ(vector[i].value, origin.value);
192 }
193}
194
195TEST(Vector, Assign_DifferentMaxSize_Copy) {
196 const Vector<int, 10> origin_vector = {1, 1, 2, 3};
197
198 Vector<int, 100> vector;
199 vector = origin_vector;
200
201 ASSERT_EQ(4u, vector.size());
202 EXPECT_EQ(1, vector[0]);
203 EXPECT_EQ(1, vector[1]);
204 EXPECT_EQ(2, vector[2]);
205 EXPECT_EQ(3, vector[3]);
206}
207
208TEST(Vector, Assign_SameMaxSize_Copy) {
209 const Vector<int, 10> origin_vector = {1, 1, 2, 3};
210
211 Vector<int, 10> vector;
212 vector = origin_vector;
213
214 ASSERT_EQ(4u, vector.size());
215 EXPECT_EQ(1, vector[0]);
216 EXPECT_EQ(1, vector[1]);
217 EXPECT_EQ(2, vector[2]);
218 EXPECT_EQ(3, vector[3]);
219}
220
221TEST(Vector, Assign_Generic_Copy) {
222 const Vector<int, 10> origin_vector = {1, 1, 2, 3};
223
224 Vector<int, 10> vector;
225 Vector<int>& ref = vector;
226 ref = static_cast<const Vector<int>&>(origin_vector);
227
228 ASSERT_EQ(4u, vector.size());
229 EXPECT_EQ(1, vector[0]);
230 EXPECT_EQ(1, vector[1]);
231 EXPECT_EQ(2, vector[2]);
232 EXPECT_EQ(3, vector[3]);
233}
234
235TEST(Vector, Assign_Move) {
236 Vector<MoveOnly, 10> origin_vector;
237
238 for (int i = 0; i < 5; ++i) {
239 origin_vector.emplace_back(421);
240 }
241
242 Vector<MoveOnly, 10> vector;
243 vector = std::move(origin_vector);
244
245 EXPECT_EQ(5u, vector.size());
246
247 for (size_t i = 0; i < vector.size(); ++i) {
248 EXPECT_EQ(vector[i].value, 421);
249 }
250
251 for (size_t i = 0; i < origin_vector.size(); ++i) {
252 EXPECT_EQ(origin_vector[i].value, MoveOnly::kDeleted);
253 }
254}
255
256TEST(Vector, Assign_InitializerList) {
257 Vector<int, 4> vector;
258 vector = {1, 3, 5, 7, 9};
259
260 EXPECT_EQ(4u, vector.size());
261
262 EXPECT_EQ(1, vector[0]);
263 EXPECT_EQ(3, vector[1]);
264 EXPECT_EQ(5, vector[2]);
265 EXPECT_EQ(7, vector[3]);
266}
267
268TEST(Vector, Access_ZeroLength) {
269 Vector<Counter, 0> vector;
270
271 EXPECT_EQ(0u, vector.size());
272 EXPECT_EQ(0u, vector.max_size());
273 EXPECT_TRUE(vector.empty());
274 EXPECT_TRUE(vector.full());
275
276 for (auto& item : vector) {
277 (void)item;
278 FAIL();
279 }
280}
281
282TEST(Vector, Access_Data_ArrayLocationIsIndependentOfMaxSize) {
283 Vector<int, 10> vector;
284 Vector<int>& base = static_cast<Vector<int>&>(vector);
285
286 EXPECT_EQ(vector.data(), base.data());
287 EXPECT_EQ(vector.data(), (static_cast<Vector<int, 0>&>(base).data()));
288 EXPECT_EQ(vector.data(), (static_cast<Vector<int, 1>&>(base).data()));
289 EXPECT_EQ(vector.data(), (static_cast<Vector<int, 100>&>(base).data()));
290 EXPECT_EQ(vector.data(), (static_cast<Vector<int, 999>&>(base).data()));
291}
292
293TEST(Vector, Modify_Clear) {
294 Counter::Reset();
295
296 Vector<Counter, 100> vector;
297 vector.emplace_back();
298 vector.emplace_back();
299 vector.emplace_back();
300
301 vector.clear();
302
303 EXPECT_EQ(3, Counter::created);
304 EXPECT_EQ(3, Counter::destroyed);
305}
306
307TEST(Vector, Modify_PushBack_Copy) {
308 Counter value(99);
309 Counter::Reset();
310
311 {
312 Vector<Counter, 10> vector;
313 vector.push_back(value);
314
315 EXPECT_EQ(vector.size(), 1u);
316 EXPECT_EQ(vector.front().value, 99);
317 }
318
319 EXPECT_EQ(Counter::created, 1);
320 EXPECT_EQ(Counter::destroyed, 1);
321}
322
323TEST(Vector, Modify_PushBack_Move) {
324 Counter::Reset();
325
326 {
327 Counter value(99);
328 Vector<Counter, 10> vector;
329 vector.push_back(std::move(value));
330
331 EXPECT_EQ(vector.size(), 1u);
332 EXPECT_EQ(vector.front().value, 99);
333 EXPECT_EQ(value.value, 0);
334 }
335
336 EXPECT_EQ(Counter::created, 1);
337 EXPECT_EQ(Counter::destroyed, 2);
338 EXPECT_EQ(Counter::moved, 1);
339}
340
341TEST(Vector, Modify_EmplaceBack) {
342 Counter::Reset();
343
344 {
345 Vector<Counter, 10> vector;
346 vector.emplace_back(314);
347
348 EXPECT_EQ(vector.size(), 1u);
349 EXPECT_EQ(vector.front().value, 314);
350 }
351
352 EXPECT_EQ(Counter::created, 1);
353 EXPECT_EQ(Counter::destroyed, 1);
354}
355
356TEST(Vector, Modify_Resize_Larger) {
357 Vector<CopyOnly, 10> vector(1, CopyOnly(123));
358 vector.resize(3, CopyOnly(123));
359
360 EXPECT_EQ(vector.size(), 3u);
361 for (auto& i : vector) {
362 EXPECT_EQ(i.value, 123);
363 }
364}
365
366TEST(Vector, Modify_Resize_LargerThanMax) {
367 Vector<CopyOnly, 10> vector;
368 vector.resize(1000, CopyOnly(123));
369
370 EXPECT_EQ(vector.size(), 10u);
371 for (auto& i : vector) {
372 EXPECT_EQ(i.value, 123);
373 }
374}
375
376TEST(Vector, Modify_Resize_Smaller) {
377 Vector<CopyOnly, 10> vector(9, CopyOnly(123));
378 vector.resize(3, CopyOnly(123));
379
380 EXPECT_EQ(vector.size(), 3u);
381 for (auto& i : vector) {
382 EXPECT_EQ(i.value, 123);
383 }
384}
385
386TEST(Vector, Modify_PopBack) {
387 Vector<Counter, 10> vector({Counter(1), Counter(2), Counter(3)});
388 Counter::Reset();
389
390 vector.pop_back();
391
392 EXPECT_EQ(vector.size(), 2u);
393 EXPECT_EQ(vector[0].value, 1);
394 EXPECT_EQ(vector[1].value, 2);
395
396 EXPECT_EQ(Counter::created, 0);
397 EXPECT_EQ(Counter::destroyed, 1);
398}
399
400TEST(Vector, Modify_Resize_Zero) {
401 Vector<CopyOnly, 10> vector(10, CopyOnly(123));
402 vector.resize(0, CopyOnly(123));
403
404 EXPECT_EQ(vector.size(), 0u);
405}
406
407TEST(Vector, Generic) {
408 Vector<int, 10> vector{1, 2, 3, 4, 5};
409
410 Vector<int>& generic_vector(vector);
411
412 EXPECT_EQ(generic_vector.size(), vector.size());
413 EXPECT_EQ(generic_vector.max_size(), vector.max_size());
414
415 int i = 0;
416 for (int value : vector) {
417 EXPECT_EQ(value, generic_vector[i]);
418 i += 1;
419 }
420
421 i = 0;
422 for (int value : generic_vector) {
423 EXPECT_EQ(vector[i], value);
424 i += 1;
425 }
426}
427
428} // namespace
429} // namespace pw