• 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::__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