1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/base/list_container.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
15 // Element class having derived classes.
16 class DerivedElement
{
18 virtual ~DerivedElement() {}
27 class DerivedElement1
: public DerivedElement
{
35 class DerivedElement2
: public DerivedElement
{
43 class DerivedElement3
: public DerivedElement
{
51 const size_t kLargestDerivedElementSize
= sizeof(DerivedElement3
);
53 size_t LargestDerivedElementSize() {
54 static_assert(sizeof(DerivedElement1
) <= kLargestDerivedElementSize
,
55 "Largest Derived Element size needs update. DerivedElement1 is "
56 "currently largest.");
57 static_assert(sizeof(DerivedElement2
) <= kLargestDerivedElementSize
,
58 "Largest Derived Element size needs update. DerivedElement2 is "
59 "currently largest.");
61 return kLargestDerivedElementSize
;
64 // Element class having no derived classes.
65 class NonDerivedElement
{
67 NonDerivedElement() {}
68 ~NonDerivedElement() {}
73 bool isConstNonDerivedElementPointer(const NonDerivedElement
* ptr
) {
77 bool isConstNonDerivedElementPointer(NonDerivedElement
* ptr
) {
81 const int kMagicNumberToUseForSimpleDerivedElementOne
= 42;
82 const int kMagicNumberToUseForSimpleDerivedElementTwo
= 314;
83 const int kMagicNumberToUseForSimpleDerivedElementThree
= 1618;
85 class SimpleDerivedElement
: public DerivedElement
{
87 ~SimpleDerivedElement() override
{}
88 void set_value(int val
) { value
= val
; }
89 int get_value() { return value
; }
95 class SimpleDerivedElementConstructMagicNumberOne
96 : public SimpleDerivedElement
{
98 SimpleDerivedElementConstructMagicNumberOne() {
99 set_value(kMagicNumberToUseForSimpleDerivedElementOne
);
103 class SimpleDerivedElementConstructMagicNumberTwo
104 : public SimpleDerivedElement
{
106 SimpleDerivedElementConstructMagicNumberTwo() {
107 set_value(kMagicNumberToUseForSimpleDerivedElementTwo
);
111 class SimpleDerivedElementConstructMagicNumberThree
112 : public SimpleDerivedElement
{
114 SimpleDerivedElementConstructMagicNumberThree() {
115 set_value(kMagicNumberToUseForSimpleDerivedElementThree
);
119 class MockDerivedElement
: public SimpleDerivedElementConstructMagicNumberOne
{
121 ~MockDerivedElement() override
{ Destruct(); }
122 MOCK_METHOD0(Destruct
, void());
125 class MockDerivedElementSubclass
: public MockDerivedElement
{
127 MockDerivedElementSubclass() {
128 set_value(kMagicNumberToUseForSimpleDerivedElementTwo
);
132 const size_t kCurrentLargestDerivedElementSize
=
133 std::max(LargestDerivedElementSize(), sizeof(MockDerivedElementSubclass
));
135 TEST(ListContainerTest
, ConstructorCalledInAllocateAndConstruct
) {
136 ListContainer
<DerivedElement
> list(kCurrentLargestDerivedElementSize
);
139 SimpleDerivedElementConstructMagicNumberOne
* de_1
=
140 list
.AllocateAndConstruct
<SimpleDerivedElementConstructMagicNumberOne
>();
141 SimpleDerivedElementConstructMagicNumberTwo
* de_2
=
142 list
.AllocateAndConstruct
<SimpleDerivedElementConstructMagicNumberTwo
>();
144 EXPECT_EQ(size
, list
.size());
145 EXPECT_EQ(de_1
, list
.front());
146 EXPECT_EQ(de_2
, list
.back());
148 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne
, de_1
->get_value());
149 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo
, de_2
->get_value());
152 TEST(ListContainerTest
, DestructorCalled
) {
153 ListContainer
<DerivedElement
> list(kCurrentLargestDerivedElementSize
);
156 MockDerivedElement
* de_1
= list
.AllocateAndConstruct
<MockDerivedElement
>();
158 EXPECT_CALL(*de_1
, Destruct());
159 EXPECT_EQ(size
, list
.size());
160 EXPECT_EQ(de_1
, list
.front());
163 TEST(ListContainerTest
, DestructorCalledOnceWhenClear
) {
164 ListContainer
<DerivedElement
> list(kCurrentLargestDerivedElementSize
);
166 MockDerivedElement
* de_1
= list
.AllocateAndConstruct
<MockDerivedElement
>();
168 EXPECT_EQ(size
, list
.size());
169 EXPECT_EQ(de_1
, list
.front());
171 // Make sure destructor is called once during clear, and won't be called
173 testing::MockFunction
<void()> separator
;
175 testing::InSequence s
;
176 EXPECT_CALL(*de_1
, Destruct());
177 EXPECT_CALL(separator
, Call());
178 EXPECT_CALL(*de_1
, Destruct()).Times(0);
185 TEST(ListContainerTest
, ClearDoesNotMalloc
) {
186 const size_t reserve
= 10;
187 ListContainer
<DerivedElement
> list(kCurrentLargestDerivedElementSize
,
190 // Memory from the initial inner list that should be re-used after clear().
191 std::vector
<DerivedElement
*> reserved_element_pointers
;
192 for (size_t i
= 0; i
< reserve
; i
++) {
193 DerivedElement
* element
= list
.AllocateAndConstruct
<DerivedElement
>();
194 reserved_element_pointers
.push_back(element
);
196 EXPECT_EQ(0u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
198 // Allocate more than the reserve count, forcing new capacity to be added.
199 list
.AllocateAndConstruct
<DerivedElement
>();
200 EXPECT_NE(0u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
202 // Clear should free all memory except the first |reserve| elements.
204 EXPECT_EQ(reserve
, list
.AvailableSizeWithoutAnotherAllocationForTesting());
206 // Verify the first |reserve| elements are re-used after clear().
207 for (size_t i
= 0; i
< reserve
; i
++) {
208 DerivedElement
* element
= list
.AllocateAndConstruct
<DerivedElement
>();
209 EXPECT_EQ(element
, reserved_element_pointers
[i
]);
211 EXPECT_EQ(0u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
213 // Verify that capacity can still grow properly.
214 list
.AllocateAndConstruct
<DerivedElement
>();
215 EXPECT_NE(0u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
218 TEST(ListContainerTest
, ReplaceExistingElement
) {
219 ListContainer
<DerivedElement
> list(kCurrentLargestDerivedElementSize
);
221 MockDerivedElement
* de_1
= list
.AllocateAndConstruct
<MockDerivedElement
>();
223 EXPECT_EQ(size
, list
.size());
224 EXPECT_EQ(de_1
, list
.front());
226 // Make sure destructor is called once during clear, and won't be called
228 testing::MockFunction
<void()> separator
;
230 testing::InSequence s
;
231 EXPECT_CALL(*de_1
, Destruct());
232 EXPECT_CALL(separator
, Call());
233 EXPECT_CALL(*de_1
, Destruct()).Times(0);
236 list
.ReplaceExistingElement
<MockDerivedElementSubclass
>(list
.begin());
237 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo
, de_1
->get_value());
240 EXPECT_CALL(*de_1
, Destruct());
244 TEST(ListContainerTest
, DestructorCalledOnceWhenErase
) {
245 ListContainer
<DerivedElement
> list(kCurrentLargestDerivedElementSize
);
247 MockDerivedElement
* de_1
= list
.AllocateAndConstruct
<MockDerivedElement
>();
249 EXPECT_EQ(size
, list
.size());
250 EXPECT_EQ(de_1
, list
.front());
252 // Make sure destructor is called once during clear, and won't be called
254 testing::MockFunction
<void()> separator
;
256 testing::InSequence s
;
257 EXPECT_CALL(*de_1
, Destruct());
258 EXPECT_CALL(separator
, Call());
259 EXPECT_CALL(*de_1
, Destruct()).Times(0);
262 list
.EraseAndInvalidateAllPointers(list
.begin());
266 TEST(ListContainerTest
, SimpleIndexAccessNonDerivedElement
) {
267 ListContainer
<NonDerivedElement
> list
;
270 NonDerivedElement
* nde_1
= list
.AllocateAndConstruct
<NonDerivedElement
>();
271 NonDerivedElement
* nde_2
= list
.AllocateAndConstruct
<NonDerivedElement
>();
272 NonDerivedElement
* nde_3
= list
.AllocateAndConstruct
<NonDerivedElement
>();
274 EXPECT_EQ(size
, list
.size());
275 EXPECT_EQ(nde_1
, list
.front());
276 EXPECT_EQ(nde_3
, list
.back());
277 EXPECT_EQ(list
.front(), list
.ElementAt(0));
278 EXPECT_EQ(nde_2
, list
.ElementAt(1));
279 EXPECT_EQ(list
.back(), list
.ElementAt(2));
282 TEST(ListContainerTest
, SimpleInsertionNonDerivedElement
) {
283 ListContainer
<NonDerivedElement
> list
;
286 NonDerivedElement
* nde_1
= list
.AllocateAndConstruct
<NonDerivedElement
>();
287 list
.AllocateAndConstruct
<NonDerivedElement
>();
288 NonDerivedElement
* nde_3
= list
.AllocateAndConstruct
<NonDerivedElement
>();
290 EXPECT_EQ(size
, list
.size());
291 EXPECT_EQ(nde_1
, list
.front());
292 EXPECT_EQ(nde_3
, list
.back());
295 TEST(ListContainerTest
, SimpleInsertionAndClearNonDerivedElement
) {
296 ListContainer
<NonDerivedElement
> list
;
297 EXPECT_TRUE(list
.empty());
298 EXPECT_EQ(0u, list
.size());
301 NonDerivedElement
* nde_1
= list
.AllocateAndConstruct
<NonDerivedElement
>();
302 list
.AllocateAndConstruct
<NonDerivedElement
>();
303 NonDerivedElement
* nde_3
= list
.AllocateAndConstruct
<NonDerivedElement
>();
305 EXPECT_EQ(size
, list
.size());
306 EXPECT_EQ(nde_1
, list
.front());
307 EXPECT_EQ(nde_3
, list
.back());
308 EXPECT_FALSE(list
.empty());
311 EXPECT_TRUE(list
.empty());
312 EXPECT_EQ(0u, list
.size());
315 TEST(ListContainerTest
, SimpleInsertionClearAndInsertAgainNonDerivedElement
) {
316 ListContainer
<NonDerivedElement
> list
;
317 EXPECT_TRUE(list
.empty());
318 EXPECT_EQ(0u, list
.size());
321 NonDerivedElement
* nde_front
= list
.AllocateAndConstruct
<NonDerivedElement
>();
322 NonDerivedElement
* nde_back
= list
.AllocateAndConstruct
<NonDerivedElement
>();
324 EXPECT_EQ(size
, list
.size());
325 EXPECT_EQ(nde_front
, list
.front());
326 EXPECT_EQ(nde_back
, list
.back());
327 EXPECT_FALSE(list
.empty());
330 EXPECT_TRUE(list
.empty());
331 EXPECT_EQ(0u, list
.size());
334 nde_front
= list
.AllocateAndConstruct
<NonDerivedElement
>();
335 list
.AllocateAndConstruct
<NonDerivedElement
>();
336 nde_back
= list
.AllocateAndConstruct
<NonDerivedElement
>();
338 EXPECT_EQ(size
, list
.size());
339 EXPECT_EQ(nde_front
, list
.front());
340 EXPECT_EQ(nde_back
, list
.back());
341 EXPECT_FALSE(list
.empty());
344 // This test is used to test when there is more than one allocation needed
345 // for, ListContainer can still perform like normal vector.
346 TEST(ListContainerTest
,
347 SimpleInsertionTriggerMoreThanOneAllocationNonDerivedElement
) {
348 ListContainer
<NonDerivedElement
> list(sizeof(NonDerivedElement
), 2);
349 std::vector
<NonDerivedElement
*> nde_list
;
351 for (size_t i
= 0; i
< size
; ++i
) {
352 nde_list
.push_back(list
.AllocateAndConstruct
<NonDerivedElement
>());
354 EXPECT_EQ(size
, list
.size());
356 ListContainer
<NonDerivedElement
>::Iterator iter
= list
.begin();
357 for (std::vector
<NonDerivedElement
*>::const_iterator nde_iter
=
359 nde_iter
!= nde_list
.end(); ++nde_iter
) {
360 EXPECT_EQ(*nde_iter
, *iter
);
365 TEST(ListContainerTest
,
366 CorrectAllocationSizeForMoreThanOneAllocationNonDerivedElement
) {
367 // Constructor sets the allocation size to 2. Every time ListContainer needs
368 // to allocate again, it doubles allocation size. In this test, 10 elements is
369 // needed, thus ListContainerShould allocate spaces 2, 4 and 8 elements.
370 ListContainer
<NonDerivedElement
> list(sizeof(NonDerivedElement
), 2);
371 std::vector
<NonDerivedElement
*> nde_list
;
373 for (size_t i
= 0; i
< size
; ++i
) {
374 // Before asking for a new element, space available without another
375 // allocation follows.
379 EXPECT_EQ(0u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
383 EXPECT_EQ(1u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
387 EXPECT_EQ(2u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
390 EXPECT_EQ(3u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
393 EXPECT_EQ(5u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
396 EXPECT_EQ(6u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
399 EXPECT_EQ(7u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
404 nde_list
.push_back(list
.AllocateAndConstruct
<NonDerivedElement
>());
405 // After asking for a new element, space available without another
406 // allocation follows.
410 EXPECT_EQ(0u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
414 EXPECT_EQ(1u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
417 EXPECT_EQ(2u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
420 EXPECT_EQ(3u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
423 EXPECT_EQ(4u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
426 EXPECT_EQ(5u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
429 EXPECT_EQ(6u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
432 EXPECT_EQ(7u, list
.AvailableSizeWithoutAnotherAllocationForTesting());
438 EXPECT_EQ(size
, list
.size());
440 ListContainer
<NonDerivedElement
>::Iterator iter
= list
.begin();
441 for (std::vector
<NonDerivedElement
*>::const_iterator nde_iter
=
443 nde_iter
!= nde_list
.end(); ++nde_iter
) {
444 EXPECT_EQ(*nde_iter
, *iter
);
449 TEST(ListContainerTest
, SimpleIterationNonDerivedElement
) {
450 ListContainer
<NonDerivedElement
> list
;
451 std::vector
<NonDerivedElement
*> nde_list
;
453 for (size_t i
= 0; i
< size
; ++i
) {
454 nde_list
.push_back(list
.AllocateAndConstruct
<NonDerivedElement
>());
456 EXPECT_EQ(size
, list
.size());
458 size_t num_iters_in_list
= 0;
460 std::vector
<NonDerivedElement
*>::const_iterator nde_iter
= nde_list
.begin();
461 for (ListContainer
<NonDerivedElement
>::Iterator iter
= list
.begin();
462 iter
!= list
.end(); ++iter
) {
463 EXPECT_EQ(*nde_iter
, *iter
);
469 size_t num_iters_in_vector
= 0;
471 ListContainer
<NonDerivedElement
>::Iterator iter
= list
.begin();
472 for (std::vector
<NonDerivedElement
*>::const_iterator nde_iter
=
474 nde_iter
!= nde_list
.end(); ++nde_iter
) {
475 EXPECT_EQ(*nde_iter
, *iter
);
476 ++num_iters_in_vector
;
481 EXPECT_EQ(num_iters_in_vector
, num_iters_in_list
);
484 TEST(ListContainerTest
, SimpleConstIteratorIterationNonDerivedElement
) {
485 ListContainer
<NonDerivedElement
> list
;
486 std::vector
<const NonDerivedElement
*> nde_list
;
488 for (size_t i
= 0; i
< size
; ++i
) {
489 nde_list
.push_back(list
.AllocateAndConstruct
<NonDerivedElement
>());
491 EXPECT_EQ(size
, list
.size());
494 std::vector
<const NonDerivedElement
*>::const_iterator nde_iter
=
496 for (ListContainer
<NonDerivedElement
>::ConstIterator iter
= list
.begin();
497 iter
!= list
.end(); ++iter
) {
498 EXPECT_TRUE(isConstNonDerivedElementPointer(*iter
));
499 EXPECT_EQ(*nde_iter
, *iter
);
505 std::vector
<const NonDerivedElement
*>::const_iterator nde_iter
=
507 for (ListContainer
<NonDerivedElement
>::Iterator iter
= list
.begin();
508 iter
!= list
.end(); ++iter
) {
509 EXPECT_FALSE(isConstNonDerivedElementPointer(*iter
));
510 EXPECT_EQ(*nde_iter
, *iter
);
516 ListContainer
<NonDerivedElement
>::ConstIterator iter
= list
.begin();
517 for (std::vector
<const NonDerivedElement
*>::const_iterator nde_iter
=
519 nde_iter
!= nde_list
.end(); ++nde_iter
) {
520 EXPECT_EQ(*nde_iter
, *iter
);
526 TEST(ListContainerTest
, SimpleReverseInsertionNonDerivedElement
) {
527 ListContainer
<NonDerivedElement
> list
;
528 std::vector
<NonDerivedElement
*> nde_list
;
530 for (size_t i
= 0; i
< size
; ++i
) {
531 nde_list
.push_back(list
.AllocateAndConstruct
<NonDerivedElement
>());
533 EXPECT_EQ(size
, list
.size());
536 std::vector
<NonDerivedElement
*>::const_reverse_iterator nde_iter
=
538 for (ListContainer
<NonDerivedElement
>::ReverseIterator iter
= list
.rbegin();
539 iter
!= list
.rend(); ++iter
) {
540 EXPECT_EQ(*nde_iter
, *iter
);
546 ListContainer
<NonDerivedElement
>::ReverseIterator iter
= list
.rbegin();
547 for (std::vector
<NonDerivedElement
*>::reverse_iterator nde_iter
=
549 nde_iter
!= nde_list
.rend(); ++nde_iter
) {
550 EXPECT_EQ(*nde_iter
, *iter
);
556 TEST(ListContainerTest
, SimpleDeletion
) {
557 ListContainer
<DerivedElement
> list(kCurrentLargestDerivedElementSize
);
558 std::vector
<SimpleDerivedElement
*> sde_list
;
560 for (int i
= 0; i
< size
; ++i
) {
561 sde_list
.push_back(list
.AllocateAndConstruct
<SimpleDerivedElement
>());
562 sde_list
.back()->set_value(i
);
564 EXPECT_EQ(static_cast<size_t>(size
), list
.size());
566 list
.EraseAndInvalidateAllPointers(list
.begin());
568 EXPECT_EQ(static_cast<size_t>(size
), list
.size());
570 for (ListContainer
<DerivedElement
>::Iterator iter
= list
.begin();
571 iter
!= list
.end(); ++iter
) {
572 EXPECT_EQ(i
, static_cast<SimpleDerivedElement
*>(*iter
)->get_value());
577 TEST(ListContainerTest
, DeletionAllInAllocation
) {
578 const size_t kReserve
= 10;
579 ListContainer
<DerivedElement
> list(kCurrentLargestDerivedElementSize
,
581 std::vector
<SimpleDerivedElement
*> sde_list
;
582 // Add enough elements to cause another allocation.
583 for (size_t i
= 0; i
< kReserve
+ 1; ++i
) {
584 sde_list
.push_back(list
.AllocateAndConstruct
<SimpleDerivedElement
>());
585 sde_list
.back()->set_value(static_cast<int>(i
));
587 EXPECT_EQ(kReserve
+ 1, list
.size());
589 // Remove everything in the first allocation.
590 for (size_t i
= 0; i
< kReserve
; ++i
)
591 list
.EraseAndInvalidateAllPointers(list
.begin());
592 EXPECT_EQ(1u, list
.size());
594 // The last element is left.
595 SimpleDerivedElement
* de
= static_cast<SimpleDerivedElement
*>(*list
.begin());
596 EXPECT_EQ(static_cast<int>(kReserve
), de
->get_value());
598 // Remove the element from the 2nd allocation.
599 list
.EraseAndInvalidateAllPointers(list
.begin());
600 EXPECT_EQ(0u, list
.size());
603 TEST(ListContainerTest
, DeletionAllInAllocationReversed
) {
604 const size_t kReserve
= 10;
605 ListContainer
<DerivedElement
> list(kCurrentLargestDerivedElementSize
,
607 std::vector
<SimpleDerivedElement
*> sde_list
;
608 // Add enough elements to cause another allocation.
609 for (size_t i
= 0; i
< kReserve
+ 1; ++i
) {
610 sde_list
.push_back(list
.AllocateAndConstruct
<SimpleDerivedElement
>());
611 sde_list
.back()->set_value(static_cast<int>(i
));
613 EXPECT_EQ(kReserve
+ 1, list
.size());
615 // Remove everything in the 2nd allocation.
616 auto it
= list
.begin();
617 for (size_t i
= 0; i
< kReserve
; ++i
)
619 list
.EraseAndInvalidateAllPointers(it
);
621 // The 2nd-last element is next, and the rest of the elements exist.
622 size_t i
= kReserve
- 1;
623 for (auto it
= list
.rbegin(); it
!= list
.rend(); ++it
) {
624 SimpleDerivedElement
* de
= static_cast<SimpleDerivedElement
*>(*it
);
625 EXPECT_EQ(static_cast<int>(i
), de
->get_value());
629 // Can forward iterate too.
631 for (auto it
= list
.begin(); it
!= list
.end(); ++it
) {
632 SimpleDerivedElement
* de
= static_cast<SimpleDerivedElement
*>(*it
);
633 EXPECT_EQ(static_cast<int>(i
), de
->get_value());
637 // Remove the last thing from the 1st allocation.
639 for (size_t i
= 0; i
< kReserve
- 1; ++i
)
641 list
.EraseAndInvalidateAllPointers(it
);
643 // The 2nd-last element is next, and the rest of the elements exist.
645 for (auto it
= list
.rbegin(); it
!= list
.rend(); ++it
) {
646 SimpleDerivedElement
* de
= static_cast<SimpleDerivedElement
*>(*it
);
647 EXPECT_EQ(static_cast<int>(i
), de
->get_value());
651 // Can forward iterate too.
653 for (auto it
= list
.begin(); it
!= list
.end(); ++it
) {
654 SimpleDerivedElement
* de
= static_cast<SimpleDerivedElement
*>(*it
);
655 EXPECT_EQ(static_cast<int>(i
), de
->get_value());
660 TEST(ListContainerTest
, SimpleIterationAndManipulation
) {
661 ListContainer
<DerivedElement
> list(kCurrentLargestDerivedElementSize
);
662 std::vector
<SimpleDerivedElement
*> sde_list
;
664 for (size_t i
= 0; i
< size
; ++i
) {
665 SimpleDerivedElement
* simple_dq
=
666 list
.AllocateAndConstruct
<SimpleDerivedElement
>();
667 sde_list
.push_back(simple_dq
);
669 EXPECT_EQ(size
, list
.size());
671 ListContainer
<DerivedElement
>::Iterator iter
= list
.begin();
672 for (int i
= 0; i
< 10; ++i
) {
673 static_cast<SimpleDerivedElement
*>(*iter
)->set_value(i
);
678 for (std::vector
<SimpleDerivedElement
*>::const_iterator sde_iter
=
680 sde_iter
< sde_list
.end(); ++sde_iter
) {
681 EXPECT_EQ(i
, (*sde_iter
)->get_value());
686 TEST(ListContainerTest
, SimpleManipulationWithIndexSimpleDerivedElement
) {
687 ListContainer
<DerivedElement
> list(kCurrentLargestDerivedElementSize
);
688 std::vector
<SimpleDerivedElement
*> de_list
;
690 for (int i
= 0; i
< size
; ++i
) {
691 de_list
.push_back(list
.AllocateAndConstruct
<SimpleDerivedElement
>());
693 EXPECT_EQ(static_cast<size_t>(size
), list
.size());
695 for (int i
= 0; i
< size
; ++i
) {
696 static_cast<SimpleDerivedElement
*>(list
.ElementAt(i
))->set_value(i
);
700 for (std::vector
<SimpleDerivedElement
*>::const_iterator
701 de_iter
= de_list
.begin();
702 de_iter
!= de_list
.end(); ++de_iter
, ++i
) {
703 EXPECT_EQ(i
, (*de_iter
)->get_value());
707 TEST(ListContainerTest
,
708 SimpleManipulationWithIndexMoreThanOneAllocationSimpleDerivedElement
) {
709 ListContainer
<DerivedElement
> list(LargestDerivedElementSize(), 2);
710 std::vector
<SimpleDerivedElement
*> de_list
;
712 for (int i
= 0; i
< size
; ++i
) {
713 de_list
.push_back(list
.AllocateAndConstruct
<SimpleDerivedElement
>());
715 EXPECT_EQ(static_cast<size_t>(size
), list
.size());
717 for (int i
= 0; i
< size
; ++i
) {
718 static_cast<SimpleDerivedElement
*>(list
.ElementAt(i
))->set_value(i
);
722 for (std::vector
<SimpleDerivedElement
*>::const_iterator
723 de_iter
= de_list
.begin();
724 de_iter
!= de_list
.end(); ++de_iter
, ++i
) {
725 EXPECT_EQ(i
, (*de_iter
)->get_value());
729 TEST(ListContainerTest
,
730 SimpleIterationAndReverseIterationWithIndexNonDerivedElement
) {
731 ListContainer
<NonDerivedElement
> list
;
732 std::vector
<NonDerivedElement
*> nde_list
;
734 for (size_t i
= 0; i
< size
; ++i
) {
735 nde_list
.push_back(list
.AllocateAndConstruct
<NonDerivedElement
>());
737 EXPECT_EQ(size
, list
.size());
740 for (ListContainer
<NonDerivedElement
>::Iterator iter
= list
.begin();
741 iter
!= list
.end(); ++iter
) {
742 EXPECT_EQ(i
, iter
.index());
747 for (ListContainer
<NonDerivedElement
>::ReverseIterator iter
= list
.rbegin();
748 iter
!= list
.rend(); ++iter
) {
749 EXPECT_EQ(i
, iter
.index());
754 // Increments an int when constructed (or the counter pointer is supplied) and
755 // decrements when destructed.
756 class InstanceCounter
{
758 InstanceCounter() : counter_(nullptr) {}
759 explicit InstanceCounter(int* counter
) { SetCounter(counter
); }
764 void SetCounter(int* counter
) {
773 TEST(ListContainerTest
, RemoveLastDestruction
) {
774 // We keep an explicit instance count to make sure that the destructors are
775 // indeed getting called.
777 ListContainer
<InstanceCounter
> list(sizeof(InstanceCounter
), 1);
778 EXPECT_EQ(0, counter
);
779 EXPECT_EQ(0u, list
.size());
781 // We should be okay to add one and then go back to zero.
782 list
.AllocateAndConstruct
<InstanceCounter
>()->SetCounter(&counter
);
783 EXPECT_EQ(1, counter
);
784 EXPECT_EQ(1u, list
.size());
786 EXPECT_EQ(0, counter
);
787 EXPECT_EQ(0u, list
.size());
789 // We should also be okay to remove the last multiple times, as long as there
790 // are enough elements in the first place.
791 list
.AllocateAndConstruct
<InstanceCounter
>()->SetCounter(&counter
);
792 list
.AllocateAndConstruct
<InstanceCounter
>()->SetCounter(&counter
);
793 list
.AllocateAndConstruct
<InstanceCounter
>()->SetCounter(&counter
);
794 list
.AllocateAndConstruct
<InstanceCounter
>()->SetCounter(&counter
);
795 list
.AllocateAndConstruct
<InstanceCounter
>()->SetCounter(&counter
);
796 list
.AllocateAndConstruct
<InstanceCounter
>()->SetCounter(&counter
);
799 EXPECT_EQ(4, counter
); // Leaves one in the last list.
800 EXPECT_EQ(4u, list
.size());
802 EXPECT_EQ(3, counter
); // Removes an inner list from before.
803 EXPECT_EQ(3u, list
.size());
806 // TODO(jbroman): std::equal would work if ListContainer iterators satisfied the
807 // usual STL iterator constraints. We should fix that.
808 template <typename It1
, typename It2
>
809 bool Equal(It1 it1
, const It1
& end1
, It2 it2
) {
810 for (; it1
!= end1
; ++it1
, ++it2
) {
817 TEST(ListContainerTest
, RemoveLastIteration
) {
821 ListContainer
<SmallStruct
> list(sizeof(SmallStruct
), 1);
822 std::vector
<SmallStruct
*> pointers
;
824 // Utilities which keep these two lists in sync and check that their iteration
826 auto push
= [&list
, &pointers
]() {
827 pointers
.push_back(list
.AllocateAndConstruct
<SmallStruct
>());
829 auto pop
= [&list
, &pointers
]() {
833 auto check_equal
= [&list
, &pointers
]() {
834 // They should be of the same size, and compare equal with all four kinds of
836 // Apparently Mac doesn't have vector::cbegin and vector::crbegin?
837 const auto& const_pointers
= pointers
;
838 ASSERT_EQ(list
.size(), pointers
.size());
839 ASSERT_TRUE(Equal(list
.begin(), list
.end(), pointers
.begin()));
840 ASSERT_TRUE(Equal(list
.cbegin(), list
.cend(), const_pointers
.begin()));
841 ASSERT_TRUE(Equal(list
.rbegin(), list
.rend(), pointers
.rbegin()));
842 ASSERT_TRUE(Equal(list
.crbegin(), list
.crend(), const_pointers
.rbegin()));
845 check_equal(); // Initially empty.
847 check_equal(); // One full inner list.
849 check_equal(); // One full, one partially full.
852 check_equal(); // Two full, one partially full.
854 check_equal(); // Two full, one empty.
856 check_equal(); // One full, one partially full, one empty.
858 check_equal(); // One full, one empty.
862 ASSERT_TRUE(list
.empty());
863 check_equal(); // Empty.
866 TEST(ListContainerTest
, AppendByMovingSameList
) {
867 ListContainer
<SimpleDerivedElement
> list(kCurrentLargestDerivedElementSize
);
868 list
.AllocateAndConstruct
<SimpleDerivedElementConstructMagicNumberOne
>();
870 list
.AppendByMoving(list
.front());
871 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne
,
872 list
.back()->get_value());
873 EXPECT_EQ(2u, list
.size());
875 list
.front()->set_value(kMagicNumberToUseForSimpleDerivedElementTwo
);
876 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo
,
877 list
.front()->get_value());
878 list
.AppendByMoving(list
.front());
879 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo
,
880 list
.back()->get_value());
881 EXPECT_EQ(3u, list
.size());
884 TEST(ListContainerTest
, AppendByMovingDoesNotDestruct
) {
885 ListContainer
<DerivedElement
> list_1(kCurrentLargestDerivedElementSize
);
886 ListContainer
<DerivedElement
> list_2(kCurrentLargestDerivedElementSize
);
887 MockDerivedElement
* mde_1
= list_1
.AllocateAndConstruct
<MockDerivedElement
>();
889 // Make sure destructor isn't called during AppendByMoving.
890 list_2
.AppendByMoving(mde_1
);
891 EXPECT_CALL(*mde_1
, Destruct()).Times(0);
892 testing::Mock::VerifyAndClearExpectations(mde_1
);
893 mde_1
= static_cast<MockDerivedElement
*>(list_2
.back());
894 EXPECT_CALL(*mde_1
, Destruct());
897 TEST(ListContainerTest
, AppendByMovingReturnsMovedPointer
) {
898 ListContainer
<SimpleDerivedElement
> list_1(kCurrentLargestDerivedElementSize
);
899 ListContainer
<SimpleDerivedElement
> list_2(kCurrentLargestDerivedElementSize
);
900 SimpleDerivedElement
* simple_element
=
901 list_1
.AllocateAndConstruct
<SimpleDerivedElement
>();
903 SimpleDerivedElement
* moved_1
= list_2
.AppendByMoving(simple_element
);
904 EXPECT_EQ(list_2
.back(), moved_1
);
906 SimpleDerivedElement
* moved_2
= list_1
.AppendByMoving(moved_1
);
907 EXPECT_EQ(list_1
.back(), moved_2
);
908 EXPECT_NE(moved_1
, moved_2
);
911 TEST(ListContainerTest
, AppendByMovingReplacesSourceWithNewDerivedElement
) {
912 ListContainer
<SimpleDerivedElementConstructMagicNumberOne
> list_1(
913 kCurrentLargestDerivedElementSize
);
914 ListContainer
<SimpleDerivedElementConstructMagicNumberTwo
> list_2(
915 kCurrentLargestDerivedElementSize
);
917 list_1
.AllocateAndConstruct
<SimpleDerivedElementConstructMagicNumberOne
>();
918 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne
,
919 list_1
.front()->get_value());
921 list_2
.AppendByMoving(list_1
.front());
922 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne
,
923 list_1
.front()->get_value());
924 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne
,
925 list_2
.front()->get_value());
927 // Change the value of list_2.front() to ensure the value is actually moved.
928 list_2
.back()->set_value(kMagicNumberToUseForSimpleDerivedElementThree
);
930 list_1
.AppendByMoving(list_2
.back());
931 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne
,
932 list_1
.front()->get_value());
933 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementThree
,
934 list_1
.back()->get_value());
935 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo
,
936 list_2
.back()->get_value());
938 // AppendByMoving replaces the source element with a new derived element so
939 // we do not expect sizes to shrink after AppendByMoving is called.
940 EXPECT_EQ(2u, list_1
.size()); // One direct allocation, one AppendByMoving.
941 EXPECT_EQ(1u, list_2
.size()); // One AppendByMoving.
944 const size_t kLongCountForLongSimpleDerivedElement
= 5;
946 class LongSimpleDerivedElement
: public SimpleDerivedElement
{
948 ~LongSimpleDerivedElement() override
{}
949 void SetAllValues(unsigned long value
) {
950 for (size_t i
= 0; i
< kLongCountForLongSimpleDerivedElement
; i
++)
953 bool AreAllValuesEqualTo(size_t value
) const {
954 for (size_t i
= 1; i
< kLongCountForLongSimpleDerivedElement
; i
++) {
955 if (values
[i
] != values
[0])
962 unsigned long values
[kLongCountForLongSimpleDerivedElement
];
965 const unsigned long kMagicNumberToUseForLongSimpleDerivedElement
= 2718ul;
967 class LongSimpleDerivedElementConstructMagicNumber
968 : public LongSimpleDerivedElement
{
970 LongSimpleDerivedElementConstructMagicNumber() {
971 SetAllValues(kMagicNumberToUseForLongSimpleDerivedElement
);
975 TEST(ListContainerTest
, AppendByMovingLongAndSimpleDerivedElements
) {
976 static_assert(sizeof(LongSimpleDerivedElement
) > sizeof(SimpleDerivedElement
),
977 "LongSimpleDerivedElement should be larger than "
978 "SimpleDerivedElement's size.");
979 static_assert(sizeof(LongSimpleDerivedElement
) <= kLargestDerivedElementSize
,
980 "LongSimpleDerivedElement should be smaller than the maximum "
981 "DerivedElement size.");
983 ListContainer
<SimpleDerivedElement
> list(kCurrentLargestDerivedElementSize
);
984 list
.AllocateAndConstruct
<LongSimpleDerivedElementConstructMagicNumber
>();
985 list
.AllocateAndConstruct
<SimpleDerivedElementConstructMagicNumberOne
>();
988 static_cast<LongSimpleDerivedElement
*>(list
.front())
989 ->AreAllValuesEqualTo(kMagicNumberToUseForLongSimpleDerivedElement
));
990 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne
,
991 list
.back()->get_value());
993 // Test that moving a simple derived element actually moves enough data so
994 // that the LongSimpleDerivedElement at this location is entirely moved.
995 SimpleDerivedElement
* simple_element
= list
.back();
996 list
.AppendByMoving(list
.front());
998 static_cast<LongSimpleDerivedElement
*>(list
.back())
999 ->AreAllValuesEqualTo(kMagicNumberToUseForLongSimpleDerivedElement
));
1000 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne
,
1001 simple_element
->get_value());
1003 LongSimpleDerivedElement
* long_element
=
1004 static_cast<LongSimpleDerivedElement
*>(list
.back());
1005 list
.AppendByMoving(simple_element
);
1006 EXPECT_TRUE(long_element
->AreAllValuesEqualTo(
1007 kMagicNumberToUseForLongSimpleDerivedElement
));
1008 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne
,
1009 list
.back()->get_value());
1012 TEST(ListContainerTest
, Swap
) {
1013 ListContainer
<SimpleDerivedElement
> list_1(kCurrentLargestDerivedElementSize
);
1014 list_1
.AllocateAndConstruct
<SimpleDerivedElementConstructMagicNumberOne
>();
1015 ListContainer
<SimpleDerivedElement
> list_2(kCurrentLargestDerivedElementSize
);
1016 list_2
.AllocateAndConstruct
<SimpleDerivedElementConstructMagicNumberTwo
>();
1017 list_2
.AllocateAndConstruct
<SimpleDerivedElementConstructMagicNumberThree
>();
1019 SimpleDerivedElement
* pre_swap_list_1_front
= list_1
.front();
1021 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne
,
1022 list_1
.front()->get_value());
1023 EXPECT_EQ(1u, list_1
.size());
1025 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo
,
1026 list_2
.front()->get_value());
1027 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementThree
,
1028 list_2
.back()->get_value());
1029 EXPECT_EQ(2u, list_2
.size());
1031 list_2
.swap(list_1
);
1033 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo
,
1034 list_1
.front()->get_value());
1035 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementThree
,
1036 list_1
.back()->get_value());
1037 EXPECT_EQ(2u, list_1
.size());
1039 EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne
,
1040 list_2
.front()->get_value());
1041 EXPECT_EQ(1u, list_2
.size());
1043 // Ensure pointers are still valid after swapping.
1044 EXPECT_EQ(pre_swap_list_1_front
, list_2
.front());
1047 TEST(ListContainerTest
, GetCapacityInBytes
) {
1048 const int iterations
= 500;
1049 const size_t initial_capacity
= 10;
1050 const size_t upper_bound_on_min_capacity
= initial_capacity
;
1052 // At time of writing, removing elements from the end can cause up to 7x the
1053 // memory required to be consumed, in the worst case, since we can have up to
1054 // two trailing inner lists that are empty (for 2*size + 4*size in unused
1055 // memory, due to the exponential growth strategy).
1056 const size_t max_waste_factor
= 8;
1058 ListContainer
<DerivedElement
> list(LargestDerivedElementSize(),
1061 // The capacity should grow with the list.
1062 for (int i
= 0; i
< iterations
; i
++) {
1063 size_t capacity
= list
.GetCapacityInBytes();
1064 ASSERT_GE(capacity
, list
.size() * LargestDerivedElementSize());
1065 ASSERT_LE(capacity
, std::max(list
.size(), upper_bound_on_min_capacity
) *
1066 max_waste_factor
* LargestDerivedElementSize());
1067 list
.AllocateAndConstruct
<DerivedElement1
>();
1070 // The capacity should shrink with the list.
1071 for (int i
= 0; i
< iterations
; i
++) {
1072 size_t capacity
= list
.GetCapacityInBytes();
1073 ASSERT_GE(capacity
, list
.size() * LargestDerivedElementSize());
1074 ASSERT_LE(capacity
, std::max(list
.size(), upper_bound_on_min_capacity
) *
1075 max_waste_factor
* LargestDerivedElementSize());