• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::__anoneff72c3d0111::CopyOnly30   explicit CopyOnly(int val) : value(val) {}
31 
CopyOnlypw::__anoneff72c3d0111::CopyOnly32   CopyOnly(const CopyOnly& other) { value = other.value; }
33 
operator =pw::__anoneff72c3d0111::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::__anoneff72c3d0111::MoveOnly45   explicit MoveOnly(int val) : value(val) {}
46 
47   MoveOnly(const MoveOnly&) = delete;
48 
MoveOnlypw::__anoneff72c3d0111::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::__anoneff72c3d0111::Counter64   static void Reset() { created = destroyed = moved = 0; }
65 
Counterpw::__anoneff72c3d0111::Counter66   Counter() : value(0) { created += 1; }
67 
Counterpw::__anoneff72c3d0111::Counter68   Counter(int val) : value(val) { created += 1; }
69 
Counterpw::__anoneff72c3d0111::Counter70   Counter(const Counter& other) : value(other.value) { created += 1; }
71 
Counterpw::__anoneff72c3d0111::Counter72   Counter(Counter&& other) : value(other.value) {
73     other.value = 0;
74     moved += 1;
75   }
76 
~Counterpw::__anoneff72c3d0111::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   for (size_t i = 0; i < origin_vector.size(); ++i) {
149     EXPECT_EQ(origin_vector[i].value, MoveOnly::kDeleted);
150   }
151 }
152 
TEST(Vector,Construct_InitializerList)153 TEST(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 
TEST(Vector,Destruct_ZeroLength)160 TEST(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 
TEST(Vector,Destruct_Empty)168 TEST(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 
TEST(Vector,Destruct_MultpileEntries)176 TEST(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 
TEST(Vector,Assign_Copy_SmallerToLarger)186 TEST(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 
TEST(Vector,Assign_DifferentMaxSize_Copy)200 TEST(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 
TEST(Vector,Assign_SameMaxSize_Copy)213 TEST(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 
TEST(Vector,Assign_Generic_Copy)226 TEST(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 
TEST(Vector,Assign_Move)240 TEST(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 
TEST(Vector,Assign_InitializerList)261 TEST(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 
TEST(Vector,Access_ZeroLength)273 TEST(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 
TEST(Vector,Access_Data_ArrayLocationIsIndependentOfMaxSize)287 TEST(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()));
294 }
295 
TEST(Vector,Modify_Clear)296 TEST(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 
TEST(Vector,Modify_PushBack_Copy)310 TEST(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 
TEST(Vector,Modify_PushBack_Move)326 TEST(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 
TEST(Vector,Modify_EmplaceBack)344 TEST(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 
TEST(Vector,Modify_Resize_Larger)359 TEST(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 
TEST(Vector,Modify_Resize_LargerThanMax)369 TEST(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 
TEST(Vector,Modify_Resize_Smaller)379 TEST(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 
TEST(Vector,Modify_PopBack)389 TEST(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 
TEST(Vector,Modify_Resize_Zero)403 TEST(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 
TEST(Vector,Generic)410 TEST(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 
431 // Test that Vector<T> is trivially destructible when its type is.
432 static_assert(std::is_trivially_destructible_v<Vector<int>>);
433 static_assert(std::is_trivially_destructible_v<Vector<int, 4>>);
434 
435 static_assert(std::is_trivially_destructible_v<MoveOnly>);
436 static_assert(std::is_trivially_destructible_v<Vector<MoveOnly>>);
437 static_assert(std::is_trivially_destructible_v<Vector<MoveOnly, 1>>);
438 
439 static_assert(std::is_trivially_destructible_v<CopyOnly>);
440 static_assert(std::is_trivially_destructible_v<Vector<CopyOnly>>);
441 static_assert(std::is_trivially_destructible_v<Vector<CopyOnly, 99>>);
442 
443 static_assert(!std::is_trivially_destructible_v<Counter>);
444 static_assert(!std::is_trivially_destructible_v<Vector<Counter>>);
445 static_assert(!std::is_trivially_destructible_v<Vector<Counter, 99>>);
446 
447 }  // namespace
448 }  // namespace pw
449