blob: 9f56c1deeafaa182829e6bb67c386b1166ecbfcb [file] [log] [blame]
Armando Montanez516022c2020-05-14 09:12:19 -07001// 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/intrusive_list.h"
16
Wyatt Hepler70f033e2020-06-10 22:22:27 -070017#include <array>
Armando Montanez516022c2020-05-14 09:12:19 -070018#include <cstddef>
19#include <cstdint>
20
21#include "gtest/gtest.h"
22#include "pw_preprocessor/util.h"
23
24namespace pw {
25namespace {
26
27class TestItem : public IntrusiveList<TestItem>::Item {
28 public:
29 TestItem() : number_(0) {}
30 TestItem(int number) : number_(number) {}
Wyatt Hepler70f033e2020-06-10 22:22:27 -070031
Armando Montanez516022c2020-05-14 09:12:19 -070032 int GetNumber() const { return number_; }
33 void SetNumber(int num) { number_ = num; }
34
Wyatt Hepler70f033e2020-06-10 22:22:27 -070035 // Add equality comparison to ensure comparisons are done by identity rather
36 // than equality for the remove function.
37 bool operator==(const TestItem& other) const {
38 return number_ == other.number_;
39 }
40
Armando Montanez516022c2020-05-14 09:12:19 -070041 private:
42 int number_;
43};
44
Wyatt Hepler70f033e2020-06-10 22:22:27 -070045TEST(IntrusiveList, Construct_InitializerList_Empty) {
46 IntrusiveList<TestItem> list({});
47 EXPECT_TRUE(list.empty());
48}
49
50TEST(IntrusiveList, Construct_InitializerList_One) {
51 TestItem one(1);
52 IntrusiveList<TestItem> list({&one});
53
54 EXPECT_EQ(&one, &list.front());
55}
56
57TEST(IntrusiveList, Construct_InitializerList_Multiple) {
58 TestItem one(1);
59 TestItem two(2);
60 TestItem thr(3);
61
62 IntrusiveList<TestItem> list({&one, &two, &thr});
63 auto it = list.begin();
64 EXPECT_EQ(&one, &(*it++));
65 EXPECT_EQ(&two, &(*it++));
66 EXPECT_EQ(&thr, &(*it++));
67 EXPECT_EQ(list.end(), it);
68}
69
70TEST(IntrusiveList, Construct_ObjectIterator_Empty) {
71 std::array<TestItem, 0> array;
72 IntrusiveList<TestItem> list(array.begin(), array.end());
73
74 EXPECT_TRUE(list.empty());
75}
76
77TEST(IntrusiveList, Construct_ObjectIterator_One) {
78 std::array<TestItem, 1> array{{{1}}};
79 IntrusiveList<TestItem> list(array.begin(), array.end());
80
81 EXPECT_EQ(&array.front(), &list.front());
82}
83
84TEST(IntrusiveList, Construct_ObjectIterator_Multiple) {
85 std::array<TestItem, 3> array{{{1}, {2}, {3}}};
86
87 IntrusiveList<TestItem> list(array.begin(), array.end());
88 auto it = list.begin();
89 EXPECT_EQ(&array[0], &(*it++));
90 EXPECT_EQ(&array[1], &(*it++));
91 EXPECT_EQ(&array[2], &(*it++));
92 EXPECT_EQ(list.end(), it);
93}
94
95TEST(IntrusiveList, Construct_PointerIterator_Empty) {
96 std::array<TestItem*, 0> array;
97 IntrusiveList<TestItem> list(array.begin(), array.end());
98
99 EXPECT_TRUE(list.empty());
100}
101
102TEST(IntrusiveList, Construct_PointerIterator_One) {
103 std::array<TestItem, 1> array{{{1}}};
104 std::array<TestItem*, 1> ptrs{{&array[0]}};
105
106 IntrusiveList<TestItem> list(ptrs.begin(), ptrs.end());
107
108 EXPECT_EQ(ptrs[0], &list.front());
109}
110
111TEST(IntrusiveList, Construct_PointerIterator_Multiple) {
112 std::array<TestItem, 3> array{{{1}, {2}, {3}}};
113 std::array<TestItem*, 3> ptrs{{&array[0], &array[1], &array[2]}};
114
115 IntrusiveList<TestItem> list(ptrs.begin(), ptrs.end());
116 auto it = list.begin();
117 EXPECT_EQ(ptrs[0], &(*it++));
118 EXPECT_EQ(ptrs[1], &(*it++));
119 EXPECT_EQ(ptrs[2], &(*it++));
120 EXPECT_EQ(list.end(), it);
121}
122
123TEST(IntrusiveList, Assign_ReplacesPriorContents) {
124 std::array<TestItem, 3> array{{{0}, {100}, {200}}};
125 IntrusiveList<TestItem> list(array.begin(), array.end());
126
127 list.assign(array.begin() + 1, array.begin() + 2);
128
129 auto it = list.begin();
130 EXPECT_EQ(&array[1], &(*it++));
131 EXPECT_EQ(list.end(), it);
132}
133
134TEST(IntrusiveList, Assign_EmptyRange) {
135 std::array<TestItem, 3> array{{{0}, {100}, {200}}};
136 IntrusiveList<TestItem> list(array.begin(), array.end());
137
138 list.assign(array.begin() + 1, array.begin() + 1);
139
140 EXPECT_TRUE(list.empty());
141}
142
Armando Montanez516022c2020-05-14 09:12:19 -0700143TEST(IntrusiveList, PushOne) {
144 constexpr int kMagicValue = 31;
Armando Montanez516022c2020-05-14 09:12:19 -0700145 TestItem item1(kMagicValue);
Keir Mierle69cd61d2020-08-18 13:47:46 -0700146 IntrusiveList<TestItem> list;
147 list.push_back(item1);
148 EXPECT_FALSE(list.empty());
149 EXPECT_EQ(list.front().GetNumber(), kMagicValue);
Armando Montanez516022c2020-05-14 09:12:19 -0700150}
151
152TEST(IntrusiveList, PushThree) {
Armando Montanez516022c2020-05-14 09:12:19 -0700153 TestItem item1(1);
154 TestItem item2(2);
155 TestItem item3(3);
Keir Mierle69cd61d2020-08-18 13:47:46 -0700156
157 IntrusiveList<TestItem> list;
158 list.push_back(item1);
159 list.push_back(item2);
160 list.push_back(item3);
Armando Montanez516022c2020-05-14 09:12:19 -0700161
162 int loop_count = 0;
Keir Mierle69cd61d2020-08-18 13:47:46 -0700163 for (auto& test_item : list) {
Armando Montanez516022c2020-05-14 09:12:19 -0700164 loop_count++;
165 EXPECT_EQ(loop_count, test_item.GetNumber());
166 }
167 EXPECT_EQ(loop_count, 3);
168}
169
170TEST(IntrusiveList, IsEmpty) {
Armando Montanez516022c2020-05-14 09:12:19 -0700171 TestItem item1(1);
Keir Mierle69cd61d2020-08-18 13:47:46 -0700172
173 IntrusiveList<TestItem> list;
174 EXPECT_TRUE(list.empty());
175
176 list.push_back(item1);
177 EXPECT_FALSE(list.empty());
Armando Montanez516022c2020-05-14 09:12:19 -0700178}
179
180TEST(IntrusiveList, InsertAfter) {
Keir Mierle69cd61d2020-08-18 13:47:46 -0700181 // Create a test item to insert midway through the list.
Armando Montanez516022c2020-05-14 09:12:19 -0700182 constexpr int kMagicValue = 42;
Keir Mierle69cd61d2020-08-18 13:47:46 -0700183 TestItem inserted_item(kMagicValue);
184
185 // Create initial values to fill in the start/end.
Armando Montanez516022c2020-05-14 09:12:19 -0700186 TestItem item_array[20];
Keir Mierle69cd61d2020-08-18 13:47:46 -0700187
188 IntrusiveList<TestItem> list;
Armando Montanez516022c2020-05-14 09:12:19 -0700189 // Fill the list with TestItem objects that have a value of zero.
190 for (size_t i = 0; i < PW_ARRAY_SIZE(item_array); ++i) {
191 item_array[i].SetNumber(0);
Keir Mierle69cd61d2020-08-18 13:47:46 -0700192 list.push_back(item_array[i]);
Armando Montanez516022c2020-05-14 09:12:19 -0700193 }
194
Keir Mierle69cd61d2020-08-18 13:47:46 -0700195 // Move an iterator to the middle of the list, and then insert the magic item.
196 auto it = list.begin();
Armando Montanez516022c2020-05-14 09:12:19 -0700197 size_t expected_index = 1; // Expected index is iterator index + 1.
198 for (size_t i = 0; i < PW_ARRAY_SIZE(item_array) / 2; ++i) {
199 it++;
200 expected_index++;
201 }
Keir Mierle69cd61d2020-08-18 13:47:46 -0700202 it = list.insert_after(it, inserted_item);
Armando Montanez516022c2020-05-14 09:12:19 -0700203
204 // Ensure the returned iterator from insert_after is the newly inserted
205 // element.
206 EXPECT_EQ(it->GetNumber(), kMagicValue);
207
208 // Ensure the value is in the expected location (index of the iterator + 1).
209 size_t i = 0;
Keir Mierle69cd61d2020-08-18 13:47:46 -0700210 for (TestItem& item : list) {
Armando Montanez516022c2020-05-14 09:12:19 -0700211 if (item.GetNumber() == kMagicValue) {
212 EXPECT_EQ(i, expected_index);
213 } else {
214 EXPECT_EQ(item.GetNumber(), 0);
215 }
216 i++;
217 }
218
219 // Ensure the list didn't break and change sizes.
220 EXPECT_EQ(i, PW_ARRAY_SIZE(item_array) + 1);
221}
222
223TEST(IntrusiveList, PushFront) {
224 constexpr int kMagicValue = 42;
Keir Mierle69cd61d2020-08-18 13:47:46 -0700225 TestItem pushed_item(kMagicValue);
226
Armando Montanez516022c2020-05-14 09:12:19 -0700227 TestItem item_array[20];
Keir Mierle69cd61d2020-08-18 13:47:46 -0700228 IntrusiveList<TestItem> list;
Armando Montanez516022c2020-05-14 09:12:19 -0700229 // Fill the list with TestItem objects that have a value of zero.
230 for (size_t i = 0; i < PW_ARRAY_SIZE(item_array); ++i) {
231 item_array[i].SetNumber(0);
Keir Mierle69cd61d2020-08-18 13:47:46 -0700232 list.push_back(item_array[i]);
Armando Montanez516022c2020-05-14 09:12:19 -0700233 }
234
235 // Create a test item to push to the front of the list.
Keir Mierle69cd61d2020-08-18 13:47:46 -0700236 list.push_front(pushed_item);
237 EXPECT_EQ(list.front().GetNumber(), kMagicValue);
Armando Montanez516022c2020-05-14 09:12:19 -0700238}
239
240TEST(IntrusiveList, Clear_Empty) {
Keir Mierle69cd61d2020-08-18 13:47:46 -0700241 IntrusiveList<TestItem> list;
242 EXPECT_TRUE(list.empty());
243 list.clear();
244 EXPECT_TRUE(list.empty());
Armando Montanez516022c2020-05-14 09:12:19 -0700245}
246
247TEST(IntrusiveList, Clear_OneItem) {
Armando Montanez516022c2020-05-14 09:12:19 -0700248 TestItem item(42);
Keir Mierle69cd61d2020-08-18 13:47:46 -0700249 IntrusiveList<TestItem> list;
250 list.push_back(item);
251 EXPECT_FALSE(list.empty());
252 list.clear();
253 EXPECT_TRUE(list.empty());
Armando Montanez516022c2020-05-14 09:12:19 -0700254}
255
256TEST(IntrusiveList, Clear_TwoItems) {
Armando Montanez516022c2020-05-14 09:12:19 -0700257 TestItem item1(42);
258 TestItem item2(42);
Keir Mierle69cd61d2020-08-18 13:47:46 -0700259 IntrusiveList<TestItem> list;
260 list.push_back(item1);
261 list.push_back(item2);
262 EXPECT_FALSE(list.empty());
263 list.clear();
264 EXPECT_TRUE(list.empty());
Armando Montanez516022c2020-05-14 09:12:19 -0700265}
266
267TEST(IntrusiveList, Clear_ReinsertClearedItems) {
268 std::array<TestItem, 20> item_array;
Keir Mierle69cd61d2020-08-18 13:47:46 -0700269 IntrusiveList<TestItem> list;
270 EXPECT_TRUE(list.empty());
271 list.clear();
272 EXPECT_TRUE(list.empty());
Armando Montanez516022c2020-05-14 09:12:19 -0700273
274 // Fill the list with TestItem objects.
275 for (size_t i = 0; i < item_array.size(); ++i) {
276 item_array[i].SetNumber(0);
Keir Mierle69cd61d2020-08-18 13:47:46 -0700277 list.push_back(item_array[i]);
Armando Montanez516022c2020-05-14 09:12:19 -0700278 }
279
280 // Remove everything.
Keir Mierle69cd61d2020-08-18 13:47:46 -0700281 list.clear();
282 EXPECT_TRUE(list.empty());
Armando Montanez516022c2020-05-14 09:12:19 -0700283
284 // Ensure all the removed elements can still be added back to a list.
285 for (size_t i = 0; i < item_array.size(); ++i) {
286 item_array[i].SetNumber(0);
Keir Mierle69cd61d2020-08-18 13:47:46 -0700287 list.push_back(item_array[i]);
Armando Montanez516022c2020-05-14 09:12:19 -0700288 }
289}
290
291TEST(IntrusiveList, PopFront) {
292 constexpr int kValue1 = 32;
293 constexpr int kValue2 = 4083;
294
Armando Montanez516022c2020-05-14 09:12:19 -0700295 TestItem item1(kValue1);
296 TestItem item2(kValue2);
297
Keir Mierle69cd61d2020-08-18 13:47:46 -0700298 IntrusiveList<TestItem> list;
299 EXPECT_TRUE(list.empty());
300
301 list.push_front(item2);
302 list.push_front(item1);
303 list.pop_front();
304 EXPECT_EQ(list.front().GetNumber(), kValue2);
305 EXPECT_FALSE(list.empty());
306 list.pop_front();
307 EXPECT_TRUE(list.empty());
Armando Montanez516022c2020-05-14 09:12:19 -0700308}
309
310TEST(IntrusiveList, PopFrontAndReinsert) {
311 constexpr int kValue1 = 32;
312 constexpr int kValue2 = 4083;
313
Armando Montanez516022c2020-05-14 09:12:19 -0700314 TestItem item1(kValue1);
315 TestItem item2(kValue2);
316
Keir Mierle69cd61d2020-08-18 13:47:46 -0700317 IntrusiveList<TestItem> list;
318 EXPECT_TRUE(list.empty());
319
320 list.push_front(item2);
321 list.push_front(item1);
322 list.pop_front();
323 list.push_front(item1);
324 EXPECT_EQ(list.front().GetNumber(), kValue1);
Armando Montanez516022c2020-05-14 09:12:19 -0700325}
326
327TEST(IntrusiveList, ListFront) {
Armando Montanez516022c2020-05-14 09:12:19 -0700328 TestItem item1(1);
329 TestItem item2(0);
330 TestItem item3(0xffff);
331
Keir Mierle69cd61d2020-08-18 13:47:46 -0700332 IntrusiveList<TestItem> list;
333 list.push_back(item1);
334 list.push_back(item2);
335 list.push_back(item3);
Armando Montanez516022c2020-05-14 09:12:19 -0700336
Keir Mierle69cd61d2020-08-18 13:47:46 -0700337 EXPECT_EQ(&item1, &list.front());
338 EXPECT_EQ(&item1, &(*list.begin()));
Armando Montanez516022c2020-05-14 09:12:19 -0700339}
340
341TEST(IntrusiveList, IteratorIncrement) {
342 TestItem item_array[20];
Keir Mierle69cd61d2020-08-18 13:47:46 -0700343 IntrusiveList<TestItem> list;
Armando Montanez516022c2020-05-14 09:12:19 -0700344 for (size_t i = 0; i < PW_ARRAY_SIZE(item_array); ++i) {
345 item_array[i].SetNumber(i);
Keir Mierle69cd61d2020-08-18 13:47:46 -0700346 list.push_back(item_array[i]);
Armando Montanez516022c2020-05-14 09:12:19 -0700347 }
348
Keir Mierle69cd61d2020-08-18 13:47:46 -0700349 auto it = list.begin();
Armando Montanez516022c2020-05-14 09:12:19 -0700350 int i = 0;
Keir Mierle69cd61d2020-08-18 13:47:46 -0700351 while (it != list.end()) {
Armando Montanez516022c2020-05-14 09:12:19 -0700352 if (i == 0) {
353 // Test pre-incrementing on the first element.
354 EXPECT_EQ((++it)->GetNumber(), item_array[++i].GetNumber());
355 } else {
356 EXPECT_EQ((it++)->GetNumber(), item_array[i++].GetNumber());
357 }
358 }
359}
360
361TEST(IntrusiveList, ConstIteratorRead) {
362 // For this test, items are checked to be non-zero.
363 TestItem item1(1);
364 TestItem item2(99);
Keir Mierle69cd61d2020-08-18 13:47:46 -0700365 IntrusiveList<TestItem> list;
Armando Montanez516022c2020-05-14 09:12:19 -0700366
Keir Mierle69cd61d2020-08-18 13:47:46 -0700367 const IntrusiveList<TestItem>* const_list = &list;
Armando Montanez516022c2020-05-14 09:12:19 -0700368
Keir Mierle69cd61d2020-08-18 13:47:46 -0700369 list.push_back(item1);
370 list.push_back(item2);
Armando Montanez516022c2020-05-14 09:12:19 -0700371
372 auto it = const_list->begin();
373 while (it != const_list->end()) {
374 EXPECT_NE(it->GetNumber(), 0);
375 it++;
376 }
377}
378
Armando Montanez516022c2020-05-14 09:12:19 -0700379// TODO(pwbug/47): These tests should fail to compile, enable when no-compile
380// tests are set up in Pigweed.
Ewout van Bekkume4d7b692020-10-15 13:12:30 -0700381#define NO_COMPILE_TESTS 0
382#if NO_COMPILE_TESTS
Armando Montanez516022c2020-05-14 09:12:19 -0700383TEST(IntrusiveList, ConstIteratorModify) {
384 TestItem item1(1);
385 TestItem item2(99);
Keir Mierle69cd61d2020-08-18 13:47:46 -0700386 IntrusiveList<TestItem> list;
Armando Montanez516022c2020-05-14 09:12:19 -0700387
Keir Mierle69cd61d2020-08-18 13:47:46 -0700388 const IntrusiveList<TestItem>* const_list = &list;
Armando Montanez516022c2020-05-14 09:12:19 -0700389
Keir Mierle69cd61d2020-08-18 13:47:46 -0700390 list.push_back(item1);
391 list.push_back(item2);
Armando Montanez516022c2020-05-14 09:12:19 -0700392
393 auto it = const_list->begin();
394 while (it != const_list->end()) {
395 it->SetNumber(0);
396 it++;
397 }
398}
399#endif // NO_COMPILE_TESTS
400
Wyatt Hepler70f033e2020-06-10 22:22:27 -0700401// TODO(pwbug/88): These tests should trigger a CHECK failure. This requires
402// using a testing version of pw_assert.
Ewout van Bekkume4d7b692020-10-15 13:12:30 -0700403#define TESTING_CHECK_FAILURES_IS_SUPPORTED 0
Wyatt Hepler70f033e2020-06-10 22:22:27 -0700404#if TESTING_CHECK_FAILURES_IS_SUPPORTED
Wyatt Hepler70f033e2020-06-10 22:22:27 -0700405TEST(IntrusiveList, Construct_DuplicateItems) {
406 TestItem item(1);
407 IntrusiveList<TestItem> list({&item, &item});
408}
409
410TEST(IntrusiveList, InsertAfter_SameItem) {
411 TestItem item(1);
412 IntrusiveList<TestItem> list({&item});
413
414 list.insert_after(list.begin(), item);
415}
416
417TEST(IntrusiveList, InsertAfter_SameItemAfterEnd) {
418 TestItem item(1);
419 IntrusiveList<TestItem> list({&item});
420
421 list.insert_after(list.end(), item);
422}
423
424TEST(IntrusiveList, PushBack_SameItem) {
425 TestItem item(1);
426 IntrusiveList<TestItem> list({&item});
427
428 list.push_back(item);
429}
430
431TEST(IntrusiveList, PushFront_SameItem) {
432 TestItem item(1);
433 IntrusiveList<TestItem> list({&item});
434
435 list.push_front(item);
436}
Wyatt Hepler70f033e2020-06-10 22:22:27 -0700437#endif // TESTING_CHECK_FAILURES_IS_SUPPORTED
438
439TEST(IntrusiveList, EraseAfter_FirstItem) {
440 std::array<TestItem, 3> items{{{0}, {1}, {2}}};
441 IntrusiveList<TestItem> list(items.begin(), items.end());
442
443 auto it = list.erase_after(list.before_begin());
444 EXPECT_EQ(list.begin(), it);
445 EXPECT_EQ(&items[1], &list.front());
446}
447
448TEST(IntrusiveList, EraseAfter_LastItem) {
449 std::array<TestItem, 3> items{{{0}, {1}, {2}}};
450 IntrusiveList<TestItem> list(items.begin(), items.end());
451
452 auto it = list.begin();
453 ++it;
454
455 it = list.erase_after(it);
456 EXPECT_EQ(list.end(), it);
457
458 it = list.begin();
459 ++it;
460
461 EXPECT_EQ(&items[1], &(*it));
462}
463
464TEST(IntrusiveList, EraseAfter_AllItems) {
465 std::array<TestItem, 3> items{{{0}, {1}, {2}}};
466 IntrusiveList<TestItem> list(items.begin(), items.end());
467
468 list.erase_after(list.begin());
469 list.erase_after(list.begin());
470 auto it = list.erase_after(list.before_begin());
471
472 EXPECT_EQ(list.end(), it);
473 EXPECT_TRUE(list.empty());
474}
475
476TEST(IntrusiveList, Remove_EmptyList) {
477 std::array<TestItem, 1> items{{{3}}};
478 IntrusiveList<TestItem> list(items.begin(), items.begin()); // Add nothing!
479
480 EXPECT_TRUE(list.empty());
481 EXPECT_FALSE(list.remove(items[0]));
482}
483
484TEST(IntrusiveList, Remove_SingleItem_NotPresent) {
485 std::array<TestItem, 1> items{{{1}}};
486 IntrusiveList<TestItem> list(items.begin(), items.end());
487
488 EXPECT_FALSE(list.remove(TestItem(1)));
489 EXPECT_EQ(&items.front(), &list.front());
490}
491
492TEST(IntrusiveList, Remove_SingleItem_Removed) {
493 std::array<TestItem, 1> items{{{1}}};
494 IntrusiveList<TestItem> list(items.begin(), items.end());
495
496 EXPECT_TRUE(list.remove(items[0]));
497 EXPECT_TRUE(list.empty());
498}
499
500TEST(IntrusiveList, Remove_MultipleItems_NotPresent) {
501 std::array<TestItem, 5> items{{{1}, {1}, {2}, {3}, {4}}};
502 IntrusiveList<TestItem> list(items.begin(), items.end());
503
504 EXPECT_FALSE(list.remove(TestItem(1)));
505}
506
507TEST(IntrusiveList, Remove_MultipleItems_RemoveAndPushBack) {
508 std::array<TestItem, 5> items{{{1}, {1}, {2}, {3}, {4}}};
509 IntrusiveList<TestItem> list(items.begin(), items.end());
510
511 EXPECT_TRUE(list.remove(items[0]));
512 EXPECT_TRUE(list.remove(items[3]));
513 list.push_back(items[0]); // Make sure can add the item after removing it.
514
515 auto it = list.begin();
516 EXPECT_EQ(&items[1], &(*it++));
517 EXPECT_EQ(&items[2], &(*it++));
518 EXPECT_EQ(&items[4], &(*it++));
519 EXPECT_EQ(&items[0], &(*it++));
520 EXPECT_EQ(list.end(), it);
521}
522
Keir Mierle69cd61d2020-08-18 13:47:46 -0700523TEST(IntrusiveList, ItemsRemoveThemselvesFromListsWhenDestructed) {
524 // Create a list with some items it.
525 TestItem a, b, c, d;
526 IntrusiveList<TestItem> list;
527 list.push_back(a);
528 list.push_back(b);
529 list.push_back(c);
530 list.push_back(d);
531
532 // Insert items that will be destructed before the list.
533 {
534 TestItem x, y, z, w;
535 list.push_back(x);
536 list.push_back(z);
537 list.push_front(y);
538 list.push_front(w);
539
540 auto it = list.begin();
541 EXPECT_EQ(&w, &(*it++));
542 EXPECT_EQ(&y, &(*it++));
543 EXPECT_EQ(&a, &(*it++));
544 EXPECT_EQ(&b, &(*it++));
545 EXPECT_EQ(&c, &(*it++));
546 EXPECT_EQ(&d, &(*it++));
547 EXPECT_EQ(&x, &(*it++));
548 EXPECT_EQ(&z, &(*it++));
549 EXPECT_EQ(list.end(), it);
550
551 // Here, x, y, z, w are removed from the list for the destructor.
552 }
553
554 // Ensure we get back our original list.
555 auto it = list.begin();
556 EXPECT_EQ(&a, &(*it++));
557 EXPECT_EQ(&b, &(*it++));
558 EXPECT_EQ(&c, &(*it++));
559 EXPECT_EQ(&d, &(*it++));
560 EXPECT_EQ(list.end(), it);
561}
562
Keir Mierlefbd4a112020-09-20 21:20:49 -0700563TEST(IntrusiveList, SizeBasic) {
564 IntrusiveList<TestItem> list;
565 EXPECT_EQ(list.size(), 0u);
566
567 TestItem one(55);
568 list.push_front(one);
569 EXPECT_EQ(list.size(), static_cast<size_t>(1));
570
571 TestItem two(66);
572 list.push_back(two);
573 EXPECT_EQ(list.size(), static_cast<size_t>(2));
574
575 TestItem thr(77);
576 list.push_back(thr);
577 EXPECT_EQ(list.size(), static_cast<size_t>(3));
578}
579
580TEST(IntrusiveList, SizeScoped) {
581 IntrusiveList<TestItem> list;
582 EXPECT_EQ(list.size(), 0u);
583
584 // Add elements in new scopes; verify size on the way in and on the way out.
585 {
586 TestItem one(55);
587 list.push_back(one);
588 EXPECT_EQ(list.size(), static_cast<size_t>(1));
589
590 {
591 TestItem two(66);
592 list.push_back(two);
593 EXPECT_EQ(list.size(), static_cast<size_t>(2));
594 {
595 TestItem thr(77);
596 list.push_back(thr);
597 EXPECT_EQ(list.size(), static_cast<size_t>(3));
598 }
599 EXPECT_EQ(list.size(), static_cast<size_t>(2));
600 }
601 EXPECT_EQ(list.size(), static_cast<size_t>(1));
602 }
603 EXPECT_EQ(list.size(), static_cast<size_t>(0));
604}
605
Armando Montanez516022c2020-05-14 09:12:19 -0700606} // namespace
607} // namespace pw