• 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/inline_deque.h"
16 
17 #include <algorithm>
18 #include <array>
19 #include <cstddef>
20 
21 #include "pw_compilation_testing/negative_compilation.h"
22 #include "pw_containers/algorithm.h"
23 #include "pw_containers_private/test_helpers.h"
24 #include "pw_unit_test/framework.h"
25 
26 namespace pw::containers {
27 namespace {
28 
29 using namespace std::literals::string_view_literals;
30 using test::CopyOnly;
31 using test::Counter;
32 using test::MoveOnly;
33 
TEST(InlineDeque,Construct_Sized)34 TEST(InlineDeque, Construct_Sized) {
35   InlineDeque<int, 3> deque;
36   EXPECT_TRUE(deque.empty());
37   EXPECT_EQ(deque.size(), 0u);
38   EXPECT_EQ(deque.max_size(), 3u);
39 }
40 
TEST(InlineDeque,Construct_GenericSized)41 TEST(InlineDeque, Construct_GenericSized) {
42   InlineDeque<int, 3> sized_deque;
43   InlineDeque<int>& deque(sized_deque);
44   EXPECT_TRUE(deque.empty());
45   EXPECT_EQ(deque.size(), 0u);
46   EXPECT_EQ(deque.max_size(), 3u);
47 }
48 
TEST(InlineDeque,Construct_ConstexprSized)49 TEST(InlineDeque, Construct_ConstexprSized) {
50   constexpr InlineDeque<int, 3> deque(pw::kConstexpr);
51   EXPECT_TRUE(deque.empty());
52   EXPECT_EQ(deque.size(), 0u);
53   EXPECT_EQ(deque.max_size(), 3u);
54 }
55 
TEST(InlineDeque,Construct_CopySameCapacity)56 TEST(InlineDeque, Construct_CopySameCapacity) {
57   InlineDeque<CopyOnly, 4> deque(4, CopyOnly(123));
58   const auto& deque_ref = deque;
59   InlineDeque<CopyOnly, 4> copied(deque_ref);
60 
61   ASSERT_EQ(4u, deque.size());
62   EXPECT_EQ(123, deque[3].value);
63 
64   ASSERT_EQ(4u, copied.size());
65   EXPECT_EQ(123, copied[3].value);
66 }
67 
TEST(InlineDeque,Construct_MoveSameCapacity)68 TEST(InlineDeque, Construct_MoveSameCapacity) {
69   InlineDeque<MoveOnly, 4> deque;
70   deque.emplace_back(MoveOnly(1));
71   deque.emplace_back(MoveOnly(2));
72   deque.emplace_back(MoveOnly(3));
73   deque.emplace_back(MoveOnly(4));
74   InlineDeque<MoveOnly, 4> moved(std::move(deque));
75 
76   // NOLINTNEXTLINE(bugprone-use-after-move)
77   EXPECT_EQ(0u, deque.size());
78 
79   ASSERT_EQ(4u, moved.size());
80   EXPECT_EQ(4, moved[3].value);
81 }
82 
TEST(InlineDeque,Construct_CopyLargerCapacity)83 TEST(InlineDeque, Construct_CopyLargerCapacity) {
84   InlineDeque<CopyOnly, 4> deque(4, CopyOnly(123));
85   InlineDeque<CopyOnly, 5> copied(deque);
86 
87   ASSERT_EQ(4u, deque.size());
88   EXPECT_EQ(123, deque[3].value);
89 
90   ASSERT_EQ(4u, copied.size());
91   EXPECT_EQ(123, copied[3].value);
92 }
93 
TEST(InlineDeque,Construct_MoveLargerCapacity)94 TEST(InlineDeque, Construct_MoveLargerCapacity) {
95   InlineDeque<MoveOnly, 4> deque;
96   deque.emplace_back(MoveOnly(1));
97   deque.emplace_back(MoveOnly(2));
98   deque.emplace_back(MoveOnly(3));
99   deque.emplace_back(MoveOnly(4));
100   InlineDeque<MoveOnly, 5> moved(std::move(deque));
101 
102   // NOLINTNEXTLINE(bugprone-use-after-move)
103   EXPECT_EQ(0u, deque.size());
104 
105   ASSERT_EQ(4u, moved.size());
106   EXPECT_EQ(4, moved[3].value);
107 }
108 
TEST(InlineDeque,Construct_CopySmallerCapacity)109 TEST(InlineDeque, Construct_CopySmallerCapacity) {
110   InlineDeque<CopyOnly, 4> deque(3, CopyOnly(123));
111   InlineDeque<CopyOnly, 3> copied(deque);
112 
113   ASSERT_EQ(3u, deque.size());
114   EXPECT_EQ(123, deque[2].value);
115 
116   ASSERT_EQ(3u, copied.size());
117   EXPECT_EQ(123, copied[2].value);
118 }
119 
TEST(InlineDeque,Destruct_ZeroLength)120 TEST(InlineDeque, Destruct_ZeroLength) {
121   Counter::Reset();
122   {
123     InlineDeque<Counter, 0> deque;
124     EXPECT_EQ(deque.size(), 0u);
125   }
126   EXPECT_EQ(Counter::created, 0);
127   EXPECT_EQ(Counter::destroyed, 0);
128 }
129 
TEST(InlineDeque,Destruct_Empty)130 TEST(InlineDeque, Destruct_Empty) {
131   Counter::Reset();
132 
133   {
134     InlineDeque<Counter, 3> deque;
135     EXPECT_EQ(deque.size(), 0u);
136   }
137   EXPECT_EQ(Counter::created, 0);
138   EXPECT_EQ(Counter::destroyed, 0);
139 }
140 
TEST(InlineDeque,Destruct_MultipleEntries)141 TEST(InlineDeque, Destruct_MultipleEntries) {
142   Counter value;
143   Counter::Reset();
144 
145   {
146     InlineDeque<Counter, 128> deque(100, value);
147   }
148 
149   EXPECT_EQ(Counter::created, 100);
150   EXPECT_EQ(Counter::destroyed, 100);
151 }
152 
TEST(InlineDeque,Assign_InitializerList)153 TEST(InlineDeque, Assign_InitializerList) {
154   InlineDeque<int, 4> deque = {1, 3, 5, 7};
155 
156   ASSERT_EQ(4u, deque.size());
157 
158   EXPECT_EQ(1, deque[0]);
159   EXPECT_EQ(3, deque[1]);
160   EXPECT_EQ(5, deque[2]);
161   EXPECT_EQ(7, deque[3]);
162 }
163 
TEST(InlineDeque,Assign_CopySameCapacity)164 TEST(InlineDeque, Assign_CopySameCapacity) {
165   InlineDeque<CopyOnly, 4> deque(4, CopyOnly(123));
166   InlineDeque<CopyOnly, 4> copied = deque;
167 
168   ASSERT_EQ(4u, deque.size());
169   EXPECT_EQ(123, deque[3].value);
170 
171   ASSERT_EQ(4u, copied.size());
172   EXPECT_EQ(123, copied[3].value);
173 }
174 
TEST(InlineDeque,Assign_CopyLargerCapacity)175 TEST(InlineDeque, Assign_CopyLargerCapacity) {
176   InlineDeque<CopyOnly, 4> deque(4, CopyOnly(123));
177   InlineDeque<CopyOnly, 5> copied = deque;
178 
179   ASSERT_EQ(4u, deque.size());
180   EXPECT_EQ(123, deque[3].value);
181 
182   ASSERT_EQ(4u, copied.size());
183   EXPECT_EQ(123, copied[3].value);
184 }
185 
TEST(InlineDeque,Assign_CopySmallerCapacity)186 TEST(InlineDeque, Assign_CopySmallerCapacity) {
187   InlineDeque<CopyOnly, 4> deque(3, CopyOnly(123));
188   InlineDeque<CopyOnly, 3> copied = deque;
189 
190   ASSERT_EQ(3u, deque.size());
191   EXPECT_EQ(123, deque[2].value);
192 
193   ASSERT_EQ(3u, copied.size());
194   EXPECT_EQ(123, copied[2].value);
195 }
196 
TEST(InlineDeque,Assign_MoveSameCapacity)197 TEST(InlineDeque, Assign_MoveSameCapacity) {
198   InlineDeque<MoveOnly, 4> deque;
199   deque.emplace_back(MoveOnly(1));
200   deque.emplace_back(MoveOnly(2));
201   deque.emplace_back(MoveOnly(3));
202   deque.emplace_back(MoveOnly(4));
203   InlineDeque<MoveOnly, 4> moved = std::move(deque);
204 
205   // NOLINTNEXTLINE(bugprone-use-after-move)
206   EXPECT_EQ(0u, deque.size());
207 
208   ASSERT_EQ(4u, moved.size());
209   EXPECT_EQ(4, moved[3].value);
210 }
211 
TEST(InlineDeque,Assign_MoveLargerCapacity)212 TEST(InlineDeque, Assign_MoveLargerCapacity) {
213   InlineDeque<MoveOnly, 4> deque;
214   deque.emplace_back(MoveOnly(1));
215   deque.emplace_back(MoveOnly(2));
216   deque.emplace_back(MoveOnly(3));
217   deque.emplace_back(MoveOnly(4));
218   InlineDeque<MoveOnly, 5> moved = std::move(deque);
219 
220   // NOLINTNEXTLINE(bugprone-use-after-move)
221   EXPECT_EQ(0u, deque.size());
222 
223   ASSERT_EQ(4u, moved.size());
224   EXPECT_EQ(4, moved[3].value);
225 }
226 
TEST(InlineDeque,Assign_MoveSmallerCapacity)227 TEST(InlineDeque, Assign_MoveSmallerCapacity) {
228   InlineDeque<MoveOnly, 4> deque;
229   deque.emplace_back(MoveOnly(1));
230   deque.emplace_back(MoveOnly(2));
231   deque.emplace_back(MoveOnly(3));
232   InlineDeque<MoveOnly, 3> moved = std::move(deque);
233 
234   // NOLINTNEXTLINE(bugprone-use-after-move)
235   EXPECT_EQ(0u, deque.size());
236 
237   ASSERT_EQ(3u, moved.size());
238   EXPECT_EQ(3, moved[2].value);
239 }
240 
TEST(InlineDeque,Access_Iterator)241 TEST(InlineDeque, Access_Iterator) {
242   InlineDeque<Counter, 2> deque(2);
243   for (Counter& item : deque) {
244     EXPECT_EQ(item.value, 0);
245   }
246   for (const Counter& item : deque) {
247     EXPECT_EQ(item.value, 0);
248   }
249 }
250 
TEST(InlineDeque,Access_ConstIterator)251 TEST(InlineDeque, Access_ConstIterator) {
252   const InlineDeque<Counter, 2> deque(2);
253   for (const Counter& item : deque) {
254     EXPECT_EQ(item.value, 0);
255   }
256 }
257 
TEST(InlineDeque,Access_ZeroLength)258 TEST(InlineDeque, Access_ZeroLength) {
259   InlineDeque<Counter, 0> deque;
260 
261   EXPECT_EQ(0u, deque.size());
262   EXPECT_EQ(0u, deque.max_size());
263   EXPECT_TRUE(deque.empty());
264   EXPECT_TRUE(deque.full());
265 
266   for (Counter& item : deque) {
267     (void)item;
268     FAIL();
269   }
270 }
271 
TEST(InlineDeque,Access_ContiguousData)272 TEST(InlineDeque, Access_ContiguousData) {
273   // Content = {}, Storage = [x, x]
274   InlineDeque<int, 2> deque;
275 
276   {
277     auto [first, second] = deque.contiguous_data();
278     EXPECT_EQ(first.size(), 0u);
279     EXPECT_EQ(second.size(), 0u);
280   }
281 
282   // Content = {1}, Storage = [1, x]
283   deque.push_back(1);
284   {
285     auto [first, second] = deque.contiguous_data();
286     EXPECT_TRUE(Equal(first, std::array<int, 1>{1}));
287     EXPECT_TRUE(Equal(second, std::array<int, 0>{}));
288   }
289 
290   // Content = {1, 2}, Storage = [1, 2]
291   deque.push_back(2);
292   EXPECT_TRUE(deque.full());
293   {
294     auto [first, second] = deque.contiguous_data();
295     EXPECT_TRUE(Equal(first, std::array<int, 2>{1, 2}));
296     EXPECT_TRUE(Equal(second, std::array<int, 0>{}));
297   }
298 
299   // Content = {2}, Storage = [x, 2]
300   deque.pop_front();
301   {
302     auto [first, second] = deque.contiguous_data();
303     EXPECT_TRUE(Equal(first, std::array<int, 1>{2}));
304     EXPECT_TRUE(Equal(second, std::array<int, 0>{}));
305   }
306 
307   // Content = {2, 1}, Storage = [1, 2]
308   deque.push_back(1);
309   {
310     auto [first, second] = deque.contiguous_data();
311     EXPECT_TRUE(Equal(first, std::array<int, 1>{2}));
312     EXPECT_TRUE(Equal(second, std::array<int, 1>{1}));
313   }
314 
315   // Content = {1}, Storage = [1, x]
316   deque.pop_front();
317   {
318     auto [first, second] = deque.contiguous_data();
319     EXPECT_TRUE(Equal(first, std::array<int, 1>{1}));
320     EXPECT_TRUE(Equal(second, std::array<int, 0>{}));
321   }
322 
323   // Content = {1, 2}, Storage = [1, 2]
324   deque.push_back(2);
325   {
326     auto [first, second] = deque.contiguous_data();
327     EXPECT_TRUE(Equal(first, std::array<int, 2>{1, 2}));
328     EXPECT_TRUE(Equal(second, std::array<int, 0>{}));
329   }
330 }
331 
TEST(InlineDeque,Access_ConstContiguousData)332 TEST(InlineDeque, Access_ConstContiguousData) {
333   // Content = {1, 2}, Storage = [1, 2]
334   const InlineDeque<int, 2> deque = {1, 2};
335 
336   {
337     auto [first, second] = deque.contiguous_data();
338     EXPECT_EQ(first.size(), 2u);
339     EXPECT_EQ(second.size(), 0u);
340   }
341 }
342 
TEST(InlineDeque,Modify_Clear)343 TEST(InlineDeque, Modify_Clear) {
344   Counter::Reset();
345 
346   InlineDeque<Counter, 100> deque;
347   deque.emplace_back();
348   deque.emplace_back();
349   deque.emplace_back();
350 
351   deque.clear();
352 
353   EXPECT_EQ(3, Counter::created);
354   EXPECT_EQ(3, Counter::destroyed);
355 }
356 
TEST(InlineDeque,Modify_PushBack_Copy)357 TEST(InlineDeque, Modify_PushBack_Copy) {
358   Counter value(99);
359   Counter::Reset();
360 
361   {
362     InlineDeque<Counter, 10> deque;
363     deque.push_back(value);
364 
365     ASSERT_EQ(deque.size(), 1u);
366     EXPECT_EQ(deque.front().value, 99);
367   }
368 
369   EXPECT_EQ(Counter::created, 1);
370   EXPECT_EQ(Counter::destroyed, 1);
371 }
372 
TEST(InlineDeque,Modify_PushBack_Move)373 TEST(InlineDeque, Modify_PushBack_Move) {
374   Counter::Reset();
375 
376   {
377     Counter value(99);
378     InlineDeque<Counter, 10> deque;
379     deque.push_back(std::move(value));
380 
381     EXPECT_EQ(deque.size(), 1u);
382     EXPECT_EQ(deque.front().value, 99);
383     // NOLINTNEXTLINE(bugprone-use-after-move)
384     EXPECT_EQ(value.value, 0);
385   }
386 
387   EXPECT_EQ(Counter::created, 1);
388   EXPECT_EQ(Counter::destroyed, 2);
389   EXPECT_EQ(Counter::moved, 1);
390 }
391 
TEST(InlineDeque,Modify_EmplaceBack)392 TEST(InlineDeque, Modify_EmplaceBack) {
393   Counter::Reset();
394 
395   {
396     InlineDeque<Counter, 10> deque;
397     deque.emplace_back(314);
398 
399     ASSERT_EQ(deque.size(), 1u);
400     EXPECT_EQ(deque.front().value, 314);
401   }
402 
403   EXPECT_EQ(Counter::created, 1);
404   EXPECT_EQ(Counter::destroyed, 1);
405 }
406 
TEST(InlineDeque,Modify_WrapForwards)407 TEST(InlineDeque, Modify_WrapForwards) {
408   Counter::Reset();
409 
410   {
411     InlineDeque<Counter, 3> deque;
412     deque.emplace_back(1);
413     deque.emplace_back(2);
414     deque.emplace_back(3);
415 
416     ASSERT_EQ(deque.size(), 3u);
417     EXPECT_EQ(deque[0].value, 1);
418     EXPECT_EQ(deque.front().value, 1);
419     EXPECT_EQ(deque[1].value, 2);
420     EXPECT_EQ(deque[2].value, 3);
421     EXPECT_EQ(deque.back().value, 3);
422 
423     deque.pop_front();
424     deque.emplace_back(4);
425 
426     ASSERT_EQ(deque.size(), 3u);
427     EXPECT_EQ(deque[0].value, 2);
428     EXPECT_EQ(deque.front().value, 2);
429     EXPECT_EQ(deque[1].value, 3);
430     EXPECT_EQ(deque[2].value, 4);
431     EXPECT_EQ(deque.back().value, 4);
432   }
433 
434   EXPECT_EQ(Counter::created, 4);
435   EXPECT_EQ(Counter::destroyed, 4);
436 }
437 
TEST(InlineDeque,Modify_WrapBackwards)438 TEST(InlineDeque, Modify_WrapBackwards) {
439   Counter::Reset();
440 
441   {
442     InlineDeque<Counter, 3> deque;
443     deque.emplace_front(1);
444     deque.emplace_front(2);
445     deque.emplace_front(3);
446 
447     ASSERT_EQ(deque.size(), 3u);
448     EXPECT_EQ(deque[0].value, 3);
449     EXPECT_EQ(deque.front().value, 3);
450     EXPECT_EQ(deque[1].value, 2);
451     EXPECT_EQ(deque[2].value, 1);
452     EXPECT_EQ(deque.back().value, 1);
453 
454     deque.pop_back();
455     deque.emplace_front(4);
456 
457     ASSERT_EQ(deque.size(), 3u);
458     EXPECT_EQ(deque[0].value, 4);
459     EXPECT_EQ(deque.front().value, 4);
460     EXPECT_EQ(deque[1].value, 3);
461     EXPECT_EQ(deque[2].value, 2);
462     EXPECT_EQ(deque.back().value, 2);
463   }
464 
465   EXPECT_EQ(Counter::created, 4);
466   EXPECT_EQ(Counter::destroyed, 4);
467 }
468 
TEST(InlineDeque,Modify_PushFront_Copy)469 TEST(InlineDeque, Modify_PushFront_Copy) {
470   Counter value(99);
471   Counter::Reset();
472 
473   {
474     InlineDeque<Counter, 10> deque;
475     deque.push_front(value);
476 
477     EXPECT_EQ(deque.size(), 1u);
478     EXPECT_EQ(deque.front().value, 99);
479   }
480 
481   EXPECT_EQ(Counter::created, 1);
482   EXPECT_EQ(Counter::destroyed, 1);
483 }
484 
TEST(InlineDeque,Modify_PushFront_Move)485 TEST(InlineDeque, Modify_PushFront_Move) {
486   Counter::Reset();
487 
488   {
489     Counter value(99);
490     InlineDeque<Counter, 10> deque;
491     deque.push_front(std::move(value));
492 
493     EXPECT_EQ(deque.size(), 1u);
494     EXPECT_EQ(deque.front().value, 99);
495     // NOLINTNEXTLINE(bugprone-use-after-move)
496     EXPECT_EQ(value.value, 0);
497   }
498 
499   EXPECT_EQ(Counter::created, 1);
500   EXPECT_EQ(Counter::destroyed, 2);
501   EXPECT_EQ(Counter::moved, 1);
502 }
503 
TEST(InlineDeque,Modify_EmplaceFront)504 TEST(InlineDeque, Modify_EmplaceFront) {
505   Counter::Reset();
506 
507   {
508     InlineDeque<Counter, 10> deque;
509     deque.emplace_front(314);
510 
511     EXPECT_EQ(deque.size(), 1u);
512     EXPECT_EQ(deque.front().value, 314);
513   }
514 
515   EXPECT_EQ(Counter::created, 1);
516   EXPECT_EQ(Counter::destroyed, 1);
517 }
518 
TEST(InlineDeque,Modify_PopBack)519 TEST(InlineDeque, Modify_PopBack) {
520   Counter::Reset();
521 
522   InlineDeque<Counter, 3> deque;
523   deque.emplace_front(1);  // This wraps to the other end.
524   deque.emplace_back(2);   // This is the first entry in storage.
525   deque.emplace_back(3);
526   // Content = {1, 2, 3}, Storage = [2, 3, 1]
527 
528   ASSERT_EQ(deque.size(), 3u);
529   EXPECT_EQ(deque[0].value, 1);
530   EXPECT_EQ(deque[1].value, 2);
531   EXPECT_EQ(deque[2].value, 3);
532 
533   deque.pop_back();
534   // Content = {1, 2}, Storage = [2, x, 1]
535   ASSERT_EQ(deque.size(), 2u);
536   EXPECT_EQ(deque[0].value, 1);
537   EXPECT_EQ(deque[1].value, 2);
538 
539   // This wraps around.
540   deque.pop_back();
541   // Content = {1}, Storage = [x, x, 1]
542 
543   ASSERT_EQ(deque.size(), 1u);
544   EXPECT_EQ(deque[0].value, 1);
545 
546   EXPECT_EQ(Counter::created, 3);
547   EXPECT_EQ(Counter::destroyed, 2);
548 }
549 
TEST(InlineDeque,Modify_PopFront)550 TEST(InlineDeque, Modify_PopFront) {
551   Counter::Reset();
552 
553   InlineDeque<Counter, 3> deque;
554   deque.emplace_front(1);  // This wraps to the other end.
555   deque.emplace_back(2);   // This is the first entry in storage.
556   deque.emplace_back(3);
557   // Content = {1, 2, 3}, Storage = [2, 3, 1]
558 
559   ASSERT_EQ(deque.size(), 3u);
560   EXPECT_EQ(deque[0].value, 1);
561   EXPECT_EQ(deque[1].value, 2);
562   EXPECT_EQ(deque[2].value, 3);
563 
564   // This wraps around
565   deque.pop_front();
566   // Content = {2, 3}, Storage = [2, 3, x]
567 
568   EXPECT_EQ(deque.size(), 2u);
569   EXPECT_EQ(deque[0].value, 2);
570   EXPECT_EQ(deque[1].value, 3);
571 
572   deque.pop_front();
573   // Content = {3}, Storage = [x, 3, x]
574   ASSERT_EQ(deque.size(), 1u);
575   EXPECT_EQ(deque[0].value, 3);
576 
577   EXPECT_EQ(Counter::created, 3);
578   EXPECT_EQ(Counter::destroyed, 2);
579 }
580 
TEST(InlineDeque,Modify_Resize_Larger)581 TEST(InlineDeque, Modify_Resize_Larger) {
582   InlineDeque<CopyOnly, 10> deque(1, CopyOnly(123));
583   deque.resize(3, CopyOnly(123));
584 
585   EXPECT_EQ(deque.size(), 3u);
586   for (auto& i : deque) {
587     EXPECT_EQ(i.value, 123);
588   }
589 }
590 
TEST(InlineDeque,Modify_Resize_LargerThanMax)591 TEST(InlineDeque, Modify_Resize_LargerThanMax) {
592   InlineDeque<CopyOnly, 10> deque;
593   deque.resize(1000, CopyOnly(123));
594 
595   EXPECT_EQ(deque.size(), 10u);
596   for (auto& i : deque) {
597     EXPECT_EQ(i.value, 123);
598   }
599 }
600 
TEST(InlineDeque,Modify_Resize_Smaller)601 TEST(InlineDeque, Modify_Resize_Smaller) {
602   InlineDeque<CopyOnly, 10> deque(9, CopyOnly(123));
603   deque.resize(3, CopyOnly(123));
604 
605   EXPECT_EQ(deque.size(), 3u);
606   for (auto& i : deque) {
607     EXPECT_EQ(i.value, 123);
608   }
609 }
610 
TEST(InlineDeque,Modify_Resize_Zero)611 TEST(InlineDeque, Modify_Resize_Zero) {
612   InlineDeque<CopyOnly, 10> deque(10, CopyOnly(123));
613   deque.resize(0, CopyOnly(123));
614 
615   EXPECT_EQ(deque.size(), 0u);
616 }
617 
TEST(InlineDeque,Generic)618 TEST(InlineDeque, Generic) {
619   InlineDeque<int, 10> deque;
620   InlineDeque<int>& generic_deque(deque);
621   generic_deque = {1, 2, 3, 4, 5};
622 
623   EXPECT_EQ(generic_deque.size(), deque.size());
624   EXPECT_EQ(generic_deque.max_size(), deque.max_size());
625 
626   unsigned short i = 0;
627   for (int value : deque) {
628     EXPECT_EQ(value, generic_deque[i]);
629     i += 1;
630   }
631 
632   i = 0;
633   for (int value : generic_deque) {
634     EXPECT_EQ(deque[i], value);
635     i += 1;
636   }
637 }
638 
TEST(InlineDeque,ConstexprMaxSize)639 TEST(InlineDeque, ConstexprMaxSize) {
640   InlineDeque<int, 10> deque;
641   constexpr size_t kMaxSize = deque.max_size();
642   EXPECT_EQ(deque.max_size(), kMaxSize);
643 
644   // Ensure the generic sized container does not have a constexpr max_size().
645   [[maybe_unused]] InlineDeque<int>& generic_deque(deque);
646 #if PW_NC_TEST(InlineDeque_GenericMaxSize_NotConstexpr)
647   PW_NC_EXPECT_CLANG(
648       "kGenericMaxSize.* must be initialized by a constant expression");
649   PW_NC_EXPECT_GCC("call to non-'constexpr' function .*InlineDeque.*max_size");
650   [[maybe_unused]] constexpr size_t kGenericMaxSize = generic_deque.max_size();
651 #endif  // PW_NC_TEST
652 }
653 
TEST(InlineDeque,StdMaxElement)654 TEST(InlineDeque, StdMaxElement) {
655   // Content = {1, 2, 3, 4}, Storage = [1, 2, 3, 4]
656   InlineDeque<int, 4> deque = {1, 2, 3, 4};
657 
658   auto max_element_it = std::max_element(deque.begin(), deque.end());
659   ASSERT_NE(max_element_it, deque.end());
660   EXPECT_EQ(*max_element_it, 4);
661 
662   // Content = {2, 3, 4}, Storage = [x, 2, 3, 4]
663   deque.pop_front();
664 
665   max_element_it = std::max_element(deque.begin(), deque.end());
666   ASSERT_NE(max_element_it, deque.end());
667   EXPECT_EQ(*max_element_it, 4);
668 
669   // Content = {2, 3, 4, 5}, Storage = [5, 2, 3, 4]
670   deque.push_back(5);
671   max_element_it = std::max_element(deque.begin(), deque.end());
672   ASSERT_NE(max_element_it, deque.end());
673   EXPECT_EQ(*max_element_it, 5);
674 
675   // Content = {}, Storage = [x, x, x, x]
676   deque.clear();
677 
678   max_element_it = std::max_element(deque.begin(), deque.end());
679   ASSERT_EQ(max_element_it, deque.end());
680 }
681 
TEST(InlineDeque,StdMaxElementConst)682 TEST(InlineDeque, StdMaxElementConst) {
683   // Content = {1, 2, 3, 4}, Storage = [1, 2, 3, 4]
684   InlineDeque<int, 4> deque = {1, 2, 3, 4};
685 
686   auto max_element_it = std::max_element(deque.cbegin(), deque.cend());
687   ASSERT_NE(max_element_it, deque.cend());
688   EXPECT_EQ(*max_element_it, 4);
689 
690   // Content = {2, 3, 4}, Storage = [x, 2, 3, 4]
691   deque.pop_front();
692 
693   max_element_it = std::max_element(deque.cbegin(), deque.cend());
694   ASSERT_NE(max_element_it, deque.cend());
695   EXPECT_EQ(*max_element_it, 4);
696 
697   // Content = {2, 3, 4, 5}, Storage = [5, 2, 3, 4]
698   deque.push_back(5);
699   max_element_it = std::max_element(deque.cbegin(), deque.cend());
700   ASSERT_NE(max_element_it, deque.cend());
701   EXPECT_EQ(*max_element_it, 5);
702 
703   // Content = {}, Storage = [x, x, x, x]
704   deque.clear();
705 
706   max_element_it = std::max_element(deque.cbegin(), deque.cend());
707   ASSERT_EQ(max_element_it, deque.cend());
708 }
709 
TEST(InlineDeque,OperatorPlus)710 TEST(InlineDeque, OperatorPlus) {
711   // Content = {0, 0, 1, 2}, Storage = [0, 0, 1, 2]
712   InlineDeque<int, 4> deque = {0, 0, 1, 2};
713   // Content = {0, 1, 2}, Storage = [x, 0, 1, 2]
714   deque.pop_front();
715   // Content = {0, 1, 2, 3}, Storage = [3, 0, 1, 2]
716   deque.push_back(3);
717   // Content = {1, 2, 3}, Storage = [3, x, 1, 2]
718   deque.pop_front();
719   // Content = {1, 2, 3, 4}, Storage = [3, 4, 1, 2]
720   deque.push_back(4);
721 
722   for (int i = 0; i < 4; i++) {
723     ASSERT_EQ(*(deque.begin() + i), static_cast<int>(i + 1));
724     ASSERT_EQ(*(i + deque.begin()), static_cast<int>(i + 1));
725   }
726 
727   ASSERT_EQ(deque.begin() + deque.size(), deque.end());
728 }
729 
TEST(InlineDeque,OperatorPlusPlus)730 TEST(InlineDeque, OperatorPlusPlus) {
731   // Content = {0, 0, 1, 2}, Storage = [0, 0, 1, 2]
732   InlineDeque<int, 4> deque = {0, 0, 1, 2};
733   // Content = {0, 1, 2}, Storage = [x, 0, 1, 2]
734   deque.pop_front();
735   // Content = {0, 1, 2, 3}, Storage = [3, 0, 1, 2]
736   deque.push_back(3);
737   // Content = {1, 2, 3}, Storage = [3, x, 1, 2]
738   deque.pop_front();
739   // Content = {1, 2, 3, 4}, Storage = [3, 4, 1, 2]
740   deque.push_back(4);
741 
742   auto it = deque.begin();
743 
744   ASSERT_EQ(*it, 1);
745   it++;
746   ASSERT_EQ(*it, 2);
747   it++;
748   ASSERT_EQ(*it, 3);
749   it++;
750   ASSERT_EQ(*it, 4);
751   it++;
752 
753   ASSERT_EQ(it, deque.end());
754 }
755 
TEST(InlineDeque,OperatorPlusEquals)756 TEST(InlineDeque, OperatorPlusEquals) {
757   // Content = {0, 0, 1, 2}, Storage = [0, 0, 1, 2]
758   InlineDeque<int, 4> deque = {0, 0, 1, 2};
759   // Content = {0, 1, 2}, Storage = [x, 0, 1, 2]
760   deque.pop_front();
761   // Content = {0, 1, 2, 3}, Storage = [3, 0, 1, 2]
762   deque.push_back(3);
763   // Content = {1, 2, 3}, Storage = [3, x, 1, 2]
764   deque.pop_front();
765   // Content = {1, 2, 3, 4}, Storage = [3, 4, 1, 2]
766   deque.push_back(4);
767 
768   auto it = deque.begin();
769 
770   ASSERT_EQ(*it, 1);
771   it += 1;
772   ASSERT_EQ(*it, 2);
773   it += 1;
774   ASSERT_EQ(*it, 3);
775   it += 1;
776   ASSERT_EQ(*it, 4);
777   it += 1;
778   ASSERT_EQ(it, deque.end());
779 
780   it = deque.begin();
781   ASSERT_EQ(*it, 1);
782   it += 2;
783   ASSERT_EQ(*it, 3);
784   it += 2;
785   ASSERT_EQ(it, deque.end());
786 
787   it = deque.begin();
788   it += deque.size();
789 
790   ASSERT_EQ(it, deque.end());
791 }
792 
TEST(InlineDeque,OpeartorMinus)793 TEST(InlineDeque, OpeartorMinus) {
794   // Content = {0, 0, 1, 2}, Storage = [0, 0, 1, 2]
795   InlineDeque<int, 4> deque = {0, 0, 1, 2};
796   // Content = {0, 1, 2}, Storage = [x, 0, 1, 2]
797   deque.pop_front();
798   // Content = {0, 1, 2, 3}, Storage = [3, 0, 1, 2]
799   deque.push_back(3);
800   // Content = {1, 2, 3}, Storage = [3, x, 1, 2]
801   deque.pop_front();
802   // Content = {1, 2, 3, 4}, Storage = [3, 4, 1, 2]
803   deque.push_back(4);
804 
805   for (int i = 1; i <= 4; i++) {
806     ASSERT_EQ(*(deque.end() - i), static_cast<int>(5 - i));
807   }
808 
809   ASSERT_EQ(deque.end() - deque.size(), deque.begin());
810 }
TEST(InlineDeque,OperatorMinusMinus)811 TEST(InlineDeque, OperatorMinusMinus) {
812   // Content = {0, 0, 1, 2}, Storage = [0, 0, 1, 2]
813   InlineDeque<int, 4> deque = {0, 0, 1, 2};
814   // Content = {0, 1, 2}, Storage = [x, 0, 1, 2]
815   deque.pop_front();
816   // Content = {0, 1, 2, 3}, Storage = [3, 0, 1, 2]
817   deque.push_back(3);
818   // Content = {1, 2, 3}, Storage = [3, x, 1, 2]
819   deque.pop_front();
820   // Content = {1, 2, 3, 4}, Storage = [3, 4, 1, 2]
821   deque.push_back(4);
822 
823   auto it = deque.end();
824 
825   it--;
826   ASSERT_EQ(*it, 4);
827   it--;
828   ASSERT_EQ(*it, 3);
829   it--;
830   ASSERT_EQ(*it, 2);
831   it--;
832   ASSERT_EQ(*it, 1);
833 
834   ASSERT_EQ(it, deque.begin());
835 }
836 
TEST(InlineDeque,OperatorMinusEquals)837 TEST(InlineDeque, OperatorMinusEquals) {
838   // Content = {0, 0, 1, 2}, Storage = [0, 0, 1, 2]
839   InlineDeque<int, 4> deque = {0, 0, 1, 2};
840   // Content = {0, 1, 2}, Storage = [x, 0, 1, 2]
841   deque.pop_front();
842   // Content = {0, 1, 2, 3}, Storage = [3, 0, 1, 2]
843   deque.push_back(3);
844   // Content = {1, 2, 3}, Storage = [3, x, 1, 2]
845   deque.pop_front();
846   // Content = {1, 2, 3, 4}, Storage = [3, 4, 1, 2]
847   deque.push_back(4);
848 
849   auto it = deque.end();
850 
851   it -= 1;
852   ASSERT_EQ(*it, 4);
853   it -= 1;
854   ASSERT_EQ(*it, 3);
855   it -= 1;
856   ASSERT_EQ(*it, 2);
857   it -= 1;
858   ASSERT_EQ(*it, 1);
859 
860   ASSERT_EQ(it, deque.begin());
861 
862   it = deque.end();
863 
864   it -= 2;
865   ASSERT_EQ(*it, 3);
866   it -= 2;
867   ASSERT_EQ(*it, 1);
868 
869   ASSERT_EQ(it, deque.begin());
870 
871   it = deque.end();
872   it -= deque.size();
873 
874   ASSERT_EQ(it, deque.begin());
875 }
876 
TEST(InlineDeque,OperatorSquareBracket)877 TEST(InlineDeque, OperatorSquareBracket) {
878   // Content = {0, 0, 1, 2}, Storage = [0, 0, 1, 2]
879   InlineDeque<int, 4> deque = {0, 0, 1, 2};
880   // Content = {0, 1, 2}, Storage = [x, 0, 1, 2]
881   deque.pop_front();
882   // Content = {0, 1, 2, 3}, Storage = [3, 0, 1, 2]
883   deque.push_back(3);
884   // Content = {1, 2, 3}, Storage = [3, x, 1, 2]
885   deque.pop_front();
886   // Content = {1, 2, 3, 4}, Storage = [3, 4, 1, 2]
887   deque.push_back(4);
888 
889   for (unsigned short i = 0; i < deque.size(); i++) {
890     ASSERT_EQ(deque.begin()[i], static_cast<int>(i + 1));
891   }
892 }
893 
TEST(InlineDeque,OperatorLessThan)894 TEST(InlineDeque, OperatorLessThan) {
895   // Content = {0, 0, 1, 2}, Storage = [0, 0, 1, 2]
896   InlineDeque<int, 4> deque = {0, 0, 1, 2};
897   // Content = {0, 1, 2}, Storage = [x, 0, 1, 2]
898   deque.pop_front();
899   // Content = {0, 1, 2, 3}, Storage = [3, 0, 1, 2]
900   deque.push_back(3);
901   // Content = {1, 2, 3}, Storage = [3, x, 1, 2]
902   deque.pop_front();
903   // Content = {1, 2, 3, 4}, Storage = [3, 4, 1, 2]
904   deque.push_back(4);
905 
906   for (int i = 0; i < deque.size(); i++) {
907     for (int j = 0; j < i; j++) {
908       ASSERT_TRUE((deque.begin() + j) < (deque.begin() + i));
909     }
910 
911     ASSERT_TRUE((deque.begin() + i) < deque.end());
912   }
913 }
914 
TEST(InlineDeque,OperatorLessThanEqual)915 TEST(InlineDeque, OperatorLessThanEqual) {
916   // Content = {0, 0, 1, 2}, Storage = [0, 0, 1, 2]
917   InlineDeque<int, 4> deque = {0, 0, 1, 2};
918   // Content = {0, 1, 2}, Storage = [x, 0, 1, 2]
919   deque.pop_front();
920   // Content = {0, 1, 2, 3}, Storage = [3, 0, 1, 2]
921   deque.push_back(3);
922   // Content = {1, 2, 3}, Storage = [3, x, 1, 2]
923   deque.pop_front();
924   // Content = {1, 2, 3, 4}, Storage = [3, 4, 1, 2]
925   deque.push_back(4);
926 
927   for (int i = 0; i < deque.size(); i++) {
928     for (int j = 0; j <= i; j++) {
929       ASSERT_TRUE((deque.begin() + j) <= (deque.begin() + i));
930     }
931 
932     ASSERT_TRUE((deque.begin() + i) <= deque.end());
933   }
934 }
935 
TEST(InlineDeque,OperatorGreater)936 TEST(InlineDeque, OperatorGreater) {
937   // Content = {0, 0, 1, 2}, Storage = [0, 0, 1, 2]
938   InlineDeque<int, 4> deque = {0, 0, 1, 2};
939   // Content = {0, 1, 2}, Storage = [x, 0, 1, 2]
940   deque.pop_front();
941   // Content = {0, 1, 2, 3}, Storage = [3, 0, 1, 2]
942   deque.push_back(3);
943   // Content = {1, 2, 3}, Storage = [3, x, 1, 2]
944   deque.pop_front();
945   // Content = {1, 2, 3, 4}, Storage = [3, 4, 1, 2]
946   deque.push_back(4);
947 
948   for (int i = 0; i < deque.size(); i++) {
949     for (int j = i + 1; j < deque.size(); j++) {
950       ASSERT_TRUE((deque.begin() + j) > (deque.begin() + i));
951     }
952 
953     ASSERT_TRUE(deque.end() > (deque.begin() + i));
954   }
955 }
956 
TEST(InlineDeque,OperatorGreaterThanEqual)957 TEST(InlineDeque, OperatorGreaterThanEqual) {
958   // Content = {0, 0, 1, 2}, Storage = [0, 0, 1, 2]
959   InlineDeque<int, 4> deque = {0, 0, 1, 2};
960   // Content = {0, 1, 2}, Storage = [x, 0, 1, 2]
961   deque.pop_front();
962   // Content = {0, 1, 2, 3}, Storage = [3, 0, 1, 2]
963   deque.push_back(3);
964   // Content = {1, 2, 3}, Storage = [3, x, 1, 2]
965   deque.pop_front();
966   // Content = {1, 2, 3, 4}, Storage = [3, 4, 1, 2]
967   deque.push_back(4);
968 
969   for (int i = 0; i < deque.size(); i++) {
970     for (int j = i; j < deque.size(); j++) {
971       ASSERT_TRUE((deque.begin() + j) >= (deque.begin() + i));
972     }
973 
974     ASSERT_TRUE(deque.end() >= (deque.begin() + i));
975   }
976 }
977 
TEST(InlineDeque,DereferenceOperator)978 TEST(InlineDeque, DereferenceOperator) {
979   // Content = {0, 0, 1, 2}, Storage = [0, 0, 1, 2]
980   InlineDeque<int, 4> deque = {0, 0, 1, 2};
981   // Content = {0, 1, 2}, Storage = [x, 0, 1, 2]
982   deque.pop_front();
983   // Content = {0, 1, 2, 3}, Storage = [3, 0, 1, 2]
984   deque.push_back(3);
985   // Content = {1, 2, 3}, Storage = [3, x, 1, 2]
986   deque.pop_front();
987   // Content = {1, 2, 3, 4}, Storage = [3, 4, 1, 2]
988   deque.push_back(4);
989 
990   for (int i = 0; i < deque.size(); i++) {
991     const auto it = deque.begin() + i;
992     ASSERT_EQ(*(it.operator->()), static_cast<int>(i + 1));
993   }
994 }
995 
996 // Test that InlineDeque<T> is trivially destructible when its type is.
997 static_assert(std::is_trivially_destructible_v<InlineDeque<int, 4>>);
998 
999 static_assert(std::is_trivially_destructible_v<MoveOnly>);
1000 static_assert(std::is_trivially_destructible_v<InlineDeque<MoveOnly, 1>>);
1001 
1002 static_assert(std::is_trivially_destructible_v<CopyOnly>);
1003 static_assert(std::is_trivially_destructible_v<InlineDeque<CopyOnly, 99>>);
1004 
1005 static_assert(!std::is_trivially_destructible_v<Counter>);
1006 static_assert(!std::is_trivially_destructible_v<InlineDeque<Counter, 99>>);
1007 
1008 // Generic-capacity deques cannot be constructed or destructed.
1009 static_assert(!std::is_constructible_v<InlineDeque<int>>);
1010 static_assert(!std::is_destructible_v<InlineDeque<int>>);
1011 
1012 // Tests that InlineDeque<T> does not have any extra padding.
1013 static_assert(sizeof(InlineDeque<uint8_t, 1>) ==
1014               sizeof(InlineDeque<uint8_t>::size_type) * 4 +
1015                   std::max(sizeof(InlineDeque<uint8_t>::size_type),
1016                            sizeof(uint8_t)));
1017 static_assert(sizeof(InlineDeque<uint8_t, 2>) ==
1018               sizeof(InlineDeque<uint8_t>::size_type) * 4 +
1019                   2 * sizeof(uint8_t));
1020 static_assert(sizeof(InlineDeque<uint16_t, 1>) ==
1021               sizeof(InlineDeque<uint16_t>::size_type) * 4 + sizeof(uint16_t));
1022 static_assert(sizeof(InlineDeque<uint32_t, 1>) ==
1023               sizeof(InlineDeque<uint32_t>::size_type) * 4 + sizeof(uint32_t));
1024 static_assert(sizeof(InlineDeque<uint64_t, 1>) ==
1025               sizeof(InlineDeque<uint64_t>::size_type) * 4 + sizeof(uint64_t));
1026 
1027 // Test that InlineDeque<T> is copy constructible
1028 static_assert(std::is_copy_constructible_v<InlineDeque<int, 4>::iterator>);
1029 
1030 // Test that InlineDeque<T> is move constructible
1031 static_assert(std::is_move_constructible_v<InlineDeque<MoveOnly, 4>::iterator>);
1032 
1033 // Test that InlineDeque<T> is copy assignable
1034 static_assert(std::is_copy_assignable_v<InlineDeque<int>::iterator>);
1035 static_assert(std::is_copy_assignable_v<InlineDeque<int, 4>::iterator>);
1036 
1037 // Test that InlineDeque<T> is move assignable
1038 static_assert(std::is_move_assignable_v<InlineDeque<MoveOnly>>);
1039 static_assert(std::is_move_assignable_v<InlineDeque<MoveOnly, 4>>);
1040 
1041 // Test that InlineDeque<T>::iterator can be converted to a const_iterator
1042 static_assert(std::is_convertible<InlineDeque<int>::iterator,
1043                                   InlineDeque<int>::const_iterator>::value);
1044 static_assert(std::is_convertible<InlineDeque<int, 4>::iterator,
1045                                   InlineDeque<int, 4>::const_iterator>::value);
1046 
1047 // Test that InlineDeque<T>::const_iterator can NOT be converted to a iterator
1048 static_assert(!std::is_convertible<InlineDeque<int>::const_iterator,
1049                                    InlineDeque<int>::iterator>::value);
1050 static_assert(!std::is_convertible<InlineDeque<int, 4>::const_iterator,
1051                                    InlineDeque<int, 4>::iterator>::value);
1052 
1053 }  // namespace
1054 }  // namespace pw::containers
1055