Index: cc/base/list_container_unittest.cc |
diff --git a/cc/base/list_container_unittest.cc b/cc/base/list_container_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cfe593b932c4e70c3497f16b8b64b5845356ce4a |
--- /dev/null |
+++ b/cc/base/list_container_unittest.cc |
@@ -0,0 +1,712 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "cc/base/list_container.h" |
+ |
+#include <vector> |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace cc { |
+namespace { |
+ |
+// Element class having derived classes. |
+class DerivedElement { |
+ public: |
+ virtual ~DerivedElement() {} |
+ |
+ protected: |
+ bool bool_values[1]; |
+ char char_values[1]; |
+ int int_values[1]; |
+ long long_values[1]; |
+}; |
+ |
+class DerivedElement1 : public DerivedElement { |
+ protected: |
+ bool bool_values1[1]; |
+ char char_values1[1]; |
+ int int_values1[1]; |
+ long long_values1[1]; |
+}; |
+ |
+class DerivedElement2 : public DerivedElement { |
+ protected: |
+ bool bool_values2[2]; |
+ char char_values2[2]; |
+ int int_values2[2]; |
+ long long_values2[2]; |
+}; |
+ |
+class DerivedElement3 : public DerivedElement { |
+ protected: |
+ bool bool_values3[3]; |
+ char char_values3[3]; |
+ int int_values3[3]; |
+ long long_values3[3]; |
+}; |
+ |
+const size_t kLargestDerivedElementSize = sizeof(DerivedElement3); |
+ |
+size_t LargestDerivedElementSize() { |
+ static_assert(sizeof(DerivedElement1) <= kLargestDerivedElementSize, |
+ "Largest Derived Element size needs update. DerivedElement1 is " |
+ "currently largest."); |
+ static_assert(sizeof(DerivedElement2) <= kLargestDerivedElementSize, |
+ "Largest Derived Element size needs update. DerivedElement2 is " |
+ "currently largest."); |
+ |
+ return kLargestDerivedElementSize; |
+} |
+ |
+// Element class having no derived classes. |
+class NonDerivedElement { |
+ public: |
+ NonDerivedElement() {} |
+ ~NonDerivedElement() {} |
+ |
+ int int_values[1]; |
+}; |
+ |
+bool isConstNonDerivedElementPointer(const NonDerivedElement* ptr) { |
+ return true; |
+} |
+ |
+bool isConstNonDerivedElementPointer(NonDerivedElement* ptr) { |
+ return false; |
+} |
+ |
+const int kMagicNumberToUseForSimpleDerivedElementOne = 42; |
+const int kMagicNumberToUseForSimpleDerivedElementTwo = 314; |
+ |
+class SimpleDerivedElement : public DerivedElement { |
+ public: |
+ ~SimpleDerivedElement() override {} |
+ void set_value(int val) { value = val; } |
+ int get_value() { return value; } |
+ |
+ private: |
+ int value; |
+}; |
+ |
+class SimpleDerivedElementConstructMagicNumberOne |
+ : public SimpleDerivedElement { |
+ public: |
+ SimpleDerivedElementConstructMagicNumberOne() : SimpleDerivedElement() { |
+ set_value(kMagicNumberToUseForSimpleDerivedElementOne); |
+ } |
+}; |
+ |
+class SimpleDerivedElementConstructMagicNumberTwo |
+ : public SimpleDerivedElement { |
+ public: |
+ SimpleDerivedElementConstructMagicNumberTwo() : SimpleDerivedElement() { |
+ set_value(kMagicNumberToUseForSimpleDerivedElementTwo); |
+ } |
+}; |
+ |
+class MockDerivedElement : public SimpleDerivedElementConstructMagicNumberOne { |
+ public: |
+ ~MockDerivedElement() override { Destruct(); } |
+ MOCK_METHOD0(Destruct, void()); |
+}; |
+ |
+class MockDerivedElementSubclass : public MockDerivedElement { |
+ public: |
+ MockDerivedElementSubclass() { |
+ set_value(kMagicNumberToUseForSimpleDerivedElementTwo); |
+ } |
+}; |
+ |
+const size_t kCurrentLargestDerivedElementSize = |
+ std::max(LargestDerivedElementSize(), sizeof(MockDerivedElementSubclass)); |
+ |
+TEST(ListContainerTest, ConstructorCalledInAllocateAndConstruct) { |
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize); |
+ |
+ size_t size = 2; |
+ SimpleDerivedElementConstructMagicNumberOne* de_1 = |
+ list.AllocateAndConstruct<SimpleDerivedElementConstructMagicNumberOne>(); |
+ SimpleDerivedElementConstructMagicNumberTwo* de_2 = |
+ list.AllocateAndConstruct<SimpleDerivedElementConstructMagicNumberTwo>(); |
+ |
+ EXPECT_EQ(size, list.size()); |
+ EXPECT_EQ(de_1, list.front()); |
+ EXPECT_EQ(de_2, list.back()); |
+ |
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne, de_1->get_value()); |
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo, de_2->get_value()); |
+} |
+ |
+TEST(ListContainerTest, DestructorCalled) { |
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize); |
+ |
+ size_t size = 1; |
+ MockDerivedElement* de_1 = list.AllocateAndConstruct<MockDerivedElement>(); |
+ |
+ EXPECT_CALL(*de_1, Destruct()); |
+ EXPECT_EQ(size, list.size()); |
+ EXPECT_EQ(de_1, list.front()); |
+} |
+ |
+TEST(ListContainerTest, DestructorCalledOnceWhenClear) { |
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize); |
+ size_t size = 1; |
+ MockDerivedElement* de_1 = list.AllocateAndConstruct<MockDerivedElement>(); |
+ |
+ EXPECT_EQ(size, list.size()); |
+ EXPECT_EQ(de_1, list.front()); |
+ |
+ // Make sure destructor is called once during clear, and won't be called |
+ // again. |
+ testing::MockFunction<void()> separator; |
+ { |
+ testing::InSequence s; |
+ EXPECT_CALL(*de_1, Destruct()); |
+ EXPECT_CALL(separator, Call()); |
+ EXPECT_CALL(*de_1, Destruct()).Times(0); |
+ } |
+ |
+ list.clear(); |
+ separator.Call(); |
+} |
+ |
+TEST(ListContainerTest, ReplaceExistingElement) { |
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize); |
+ size_t size = 1; |
+ MockDerivedElement* de_1 = list.AllocateAndConstruct<MockDerivedElement>(); |
+ |
+ EXPECT_EQ(size, list.size()); |
+ EXPECT_EQ(de_1, list.front()); |
+ |
+ // Make sure destructor is called once during clear, and won't be called |
+ // again. |
+ testing::MockFunction<void()> separator; |
+ { |
+ testing::InSequence s; |
+ EXPECT_CALL(*de_1, Destruct()); |
+ EXPECT_CALL(separator, Call()); |
+ EXPECT_CALL(*de_1, Destruct()).Times(0); |
+ } |
+ |
+ list.ReplaceExistingElement<MockDerivedElementSubclass>(list.begin()); |
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo, de_1->get_value()); |
+ separator.Call(); |
+ |
+ EXPECT_CALL(*de_1, Destruct()); |
+ list.clear(); |
+} |
+ |
+TEST(ListContainerTest, DestructorCalledOnceWhenErase) { |
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize); |
+ size_t size = 1; |
+ MockDerivedElement* de_1 = list.AllocateAndConstruct<MockDerivedElement>(); |
+ |
+ EXPECT_EQ(size, list.size()); |
+ EXPECT_EQ(de_1, list.front()); |
+ |
+ // Make sure destructor is called once during clear, and won't be called |
+ // again. |
+ testing::MockFunction<void()> separator; |
+ { |
+ testing::InSequence s; |
+ EXPECT_CALL(*de_1, Destruct()); |
+ EXPECT_CALL(separator, Call()); |
+ EXPECT_CALL(*de_1, Destruct()).Times(0); |
+ } |
+ |
+ list.EraseAndInvalidateAllPointers(list.begin()); |
+ separator.Call(); |
+} |
+ |
+TEST(ListContainerTest, SimpleIndexAccessNonDerivedElement) { |
+ ListContainer<NonDerivedElement> list; |
+ |
+ size_t size = 3; |
+ NonDerivedElement* nde_1 = list.AllocateAndConstruct<NonDerivedElement>(); |
+ NonDerivedElement* nde_2 = list.AllocateAndConstruct<NonDerivedElement>(); |
+ NonDerivedElement* nde_3 = list.AllocateAndConstruct<NonDerivedElement>(); |
+ |
+ EXPECT_EQ(size, list.size()); |
+ EXPECT_EQ(nde_1, list.front()); |
+ EXPECT_EQ(nde_3, list.back()); |
+ EXPECT_EQ(list.front(), list.ElementAt(0)); |
+ EXPECT_EQ(nde_2, list.ElementAt(1)); |
+ EXPECT_EQ(list.back(), list.ElementAt(2)); |
+} |
+ |
+TEST(ListContainerTest, SimpleInsertionNonDerivedElement) { |
+ ListContainer<NonDerivedElement> list; |
+ |
+ size_t size = 3; |
+ NonDerivedElement* nde_1 = list.AllocateAndConstruct<NonDerivedElement>(); |
+ list.AllocateAndConstruct<NonDerivedElement>(); |
+ NonDerivedElement* nde_3 = list.AllocateAndConstruct<NonDerivedElement>(); |
+ |
+ EXPECT_EQ(size, list.size()); |
+ EXPECT_EQ(nde_1, list.front()); |
+ EXPECT_EQ(nde_3, list.back()); |
+} |
+ |
+TEST(ListContainerTest, SimpleInsertionAndClearNonDerivedElement) { |
+ ListContainer<NonDerivedElement> list; |
+ EXPECT_TRUE(list.empty()); |
+ EXPECT_EQ(0u, list.size()); |
+ |
+ size_t size = 3; |
+ NonDerivedElement* nde_1 = list.AllocateAndConstruct<NonDerivedElement>(); |
+ list.AllocateAndConstruct<NonDerivedElement>(); |
+ NonDerivedElement* nde_3 = list.AllocateAndConstruct<NonDerivedElement>(); |
+ |
+ EXPECT_EQ(size, list.size()); |
+ EXPECT_EQ(nde_1, list.front()); |
+ EXPECT_EQ(nde_3, list.back()); |
+ EXPECT_FALSE(list.empty()); |
+ |
+ list.clear(); |
+ EXPECT_TRUE(list.empty()); |
+ EXPECT_EQ(0u, list.size()); |
+} |
+ |
+TEST(ListContainerTest, SimpleInsertionClearAndInsertAgainNonDerivedElement) { |
+ ListContainer<NonDerivedElement> list; |
+ EXPECT_TRUE(list.empty()); |
+ EXPECT_EQ(0u, list.size()); |
+ |
+ size_t size = 2; |
+ NonDerivedElement* nde_front = list.AllocateAndConstruct<NonDerivedElement>(); |
+ NonDerivedElement* nde_back = list.AllocateAndConstruct<NonDerivedElement>(); |
+ |
+ EXPECT_EQ(size, list.size()); |
+ EXPECT_EQ(nde_front, list.front()); |
+ EXPECT_EQ(nde_back, list.back()); |
+ EXPECT_FALSE(list.empty()); |
+ |
+ list.clear(); |
+ EXPECT_TRUE(list.empty()); |
+ EXPECT_EQ(0u, list.size()); |
+ |
+ size = 3; |
+ nde_front = list.AllocateAndConstruct<NonDerivedElement>(); |
+ list.AllocateAndConstruct<NonDerivedElement>(); |
+ nde_back = list.AllocateAndConstruct<NonDerivedElement>(); |
+ |
+ EXPECT_EQ(size, list.size()); |
+ EXPECT_EQ(nde_front, list.front()); |
+ EXPECT_EQ(nde_back, list.back()); |
+ EXPECT_FALSE(list.empty()); |
+} |
+ |
+// This test is used to test when there is more than one allocation needed |
+// for, ListContainer can still perform like normal vector. |
+TEST(ListContainerTest, |
+ SimpleInsertionTriggerMoreThanOneAllocationNonDerivedElement) { |
+ ListContainer<NonDerivedElement> list(sizeof(NonDerivedElement), 2); |
+ std::vector<NonDerivedElement*> nde_list; |
+ size_t size = 10; |
+ for (size_t i = 0; i < size; ++i) { |
+ nde_list.push_back(list.AllocateAndConstruct<NonDerivedElement>()); |
+ } |
+ EXPECT_EQ(size, list.size()); |
+ |
+ ListContainer<NonDerivedElement>::Iterator iter = list.begin(); |
+ for (std::vector<NonDerivedElement*>::const_iterator nde_iter = |
+ nde_list.begin(); |
+ nde_iter != nde_list.end(); ++nde_iter) { |
+ EXPECT_EQ(*nde_iter, *iter); |
+ ++iter; |
+ } |
+} |
+ |
+TEST(ListContainerTest, |
+ CorrectAllocationSizeForMoreThanOneAllocationNonDerivedElement) { |
+ // Constructor sets the allocation size to 2. Every time ListContainer needs |
+ // to allocate again, it doubles allocation size. In this test, 10 elements is |
+ // needed, thus ListContainerShould allocate spaces 2, 4 and 8 elements. |
+ ListContainer<NonDerivedElement> list(sizeof(NonDerivedElement), 2); |
+ std::vector<NonDerivedElement*> nde_list; |
+ size_t size = 10; |
+ for (size_t i = 0; i < size; ++i) { |
+ // Before asking for a new element, space available without another |
+ // allocation follows. |
+ switch (i) { |
+ case 2: |
+ case 6: |
+ EXPECT_EQ(0u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ case 1: |
+ case 5: |
+ EXPECT_EQ(1u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ case 0: |
+ case 4: |
+ EXPECT_EQ(2u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ case 3: |
+ EXPECT_EQ(3u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ case 9: |
+ EXPECT_EQ(5u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ case 8: |
+ EXPECT_EQ(6u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ case 7: |
+ EXPECT_EQ(7u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ default: |
+ break; |
+ } |
+ nde_list.push_back(list.AllocateAndConstruct<NonDerivedElement>()); |
+ // After asking for a new element, space available without another |
+ // allocation follows. |
+ switch (i) { |
+ case 1: |
+ case 5: |
+ EXPECT_EQ(0u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ case 0: |
+ case 4: |
+ EXPECT_EQ(1u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ case 3: |
+ EXPECT_EQ(2u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ case 2: |
+ EXPECT_EQ(3u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ case 9: |
+ EXPECT_EQ(4u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ case 8: |
+ EXPECT_EQ(5u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ case 7: |
+ EXPECT_EQ(6u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ case 6: |
+ EXPECT_EQ(7u, list.AvailableSizeWithoutAnotherAllocationForTesting()); |
+ break; |
+ default: |
+ break; |
+ } |
+ } |
+ EXPECT_EQ(size, list.size()); |
+ |
+ ListContainer<NonDerivedElement>::Iterator iter = list.begin(); |
+ for (std::vector<NonDerivedElement*>::const_iterator nde_iter = |
+ nde_list.begin(); |
+ nde_iter != nde_list.end(); ++nde_iter) { |
+ EXPECT_EQ(*nde_iter, *iter); |
+ ++iter; |
+ } |
+} |
+ |
+TEST(ListContainerTest, SimpleIterationNonDerivedElement) { |
+ ListContainer<NonDerivedElement> list; |
+ std::vector<NonDerivedElement*> nde_list; |
+ size_t size = 10; |
+ for (size_t i = 0; i < size; ++i) { |
+ nde_list.push_back(list.AllocateAndConstruct<NonDerivedElement>()); |
+ } |
+ EXPECT_EQ(size, list.size()); |
+ |
+ size_t num_iters_in_list = 0; |
+ { |
+ std::vector<NonDerivedElement*>::const_iterator nde_iter = nde_list.begin(); |
+ for (ListContainer<NonDerivedElement>::Iterator iter = list.begin(); |
+ iter != list.end(); ++iter) { |
+ EXPECT_EQ(*nde_iter, *iter); |
+ ++num_iters_in_list; |
+ ++nde_iter; |
+ } |
+ } |
+ |
+ size_t num_iters_in_vector = 0; |
+ { |
+ ListContainer<NonDerivedElement>::Iterator iter = list.begin(); |
+ for (std::vector<NonDerivedElement*>::const_iterator nde_iter = |
+ nde_list.begin(); |
+ nde_iter != nde_list.end(); ++nde_iter) { |
+ EXPECT_EQ(*nde_iter, *iter); |
+ ++num_iters_in_vector; |
+ ++iter; |
+ } |
+ } |
+ |
+ EXPECT_EQ(num_iters_in_vector, num_iters_in_list); |
+} |
+ |
+TEST(ListContainerTest, SimpleConstIteratorIterationNonDerivedElement) { |
+ ListContainer<NonDerivedElement> list; |
+ std::vector<const NonDerivedElement*> nde_list; |
+ size_t size = 10; |
+ for (size_t i = 0; i < size; ++i) { |
+ nde_list.push_back(list.AllocateAndConstruct<NonDerivedElement>()); |
+ } |
+ EXPECT_EQ(size, list.size()); |
+ |
+ { |
+ std::vector<const NonDerivedElement*>::const_iterator nde_iter = |
+ nde_list.begin(); |
+ for (ListContainer<NonDerivedElement>::ConstIterator iter = list.begin(); |
+ iter != list.end(); ++iter) { |
+ EXPECT_TRUE(isConstNonDerivedElementPointer(*iter)); |
+ EXPECT_EQ(*nde_iter, *iter); |
+ ++nde_iter; |
+ } |
+ } |
+ |
+ { |
+ std::vector<const NonDerivedElement*>::const_iterator nde_iter = |
+ nde_list.begin(); |
+ for (ListContainer<NonDerivedElement>::Iterator iter = list.begin(); |
+ iter != list.end(); ++iter) { |
+ EXPECT_FALSE(isConstNonDerivedElementPointer(*iter)); |
+ EXPECT_EQ(*nde_iter, *iter); |
+ ++nde_iter; |
+ } |
+ } |
+ |
+ { |
+ ListContainer<NonDerivedElement>::ConstIterator iter = list.begin(); |
+ for (std::vector<const NonDerivedElement*>::const_iterator nde_iter = |
+ nde_list.begin(); |
+ nde_iter != nde_list.end(); ++nde_iter) { |
+ EXPECT_EQ(*nde_iter, *iter); |
+ ++iter; |
+ } |
+ } |
+} |
+ |
+TEST(ListContainerTest, SimpleReverseInsertionNonDerivedElement) { |
+ ListContainer<NonDerivedElement> list; |
+ std::vector<NonDerivedElement*> nde_list; |
+ size_t size = 10; |
+ for (size_t i = 0; i < size; ++i) { |
+ nde_list.push_back(list.AllocateAndConstruct<NonDerivedElement>()); |
+ } |
+ EXPECT_EQ(size, list.size()); |
+ |
+ { |
+ std::vector<NonDerivedElement*>::const_reverse_iterator nde_iter = |
+ nde_list.rbegin(); |
+ for (ListContainer<NonDerivedElement>::ReverseIterator iter = list.rbegin(); |
+ iter != list.rend(); ++iter) { |
+ EXPECT_EQ(*nde_iter, *iter); |
+ ++nde_iter; |
+ } |
+ } |
+ |
+ { |
+ ListContainer<NonDerivedElement>::ReverseIterator iter = list.rbegin(); |
+ for (std::vector<NonDerivedElement*>::reverse_iterator nde_iter = |
+ nde_list.rbegin(); |
+ nde_iter != nde_list.rend(); ++nde_iter) { |
+ EXPECT_EQ(*nde_iter, *iter); |
+ ++iter; |
+ } |
+ } |
+} |
+ |
+TEST(ListContainerTest, SimpleDeletion) { |
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize); |
+ std::vector<SimpleDerivedElement*> sde_list; |
+ size_t size = 10; |
+ for (size_t i = 0; i < size; ++i) { |
+ sde_list.push_back(list.AllocateAndConstruct<SimpleDerivedElement>()); |
+ sde_list.back()->set_value(i); |
+ } |
+ EXPECT_EQ(size, list.size()); |
+ |
+ list.EraseAndInvalidateAllPointers(list.begin()); |
+ --size; |
+ EXPECT_EQ(size, list.size()); |
+ int i = 1; |
+ for (ListContainer<DerivedElement>::Iterator iter = list.begin(); |
+ iter != list.end(); ++iter) { |
+ EXPECT_EQ(i, static_cast<SimpleDerivedElement*>(*iter)->get_value()); |
+ ++i; |
+ } |
+} |
+ |
+TEST(ListContainerTest, DeletionAllInAllocation) { |
+ const size_t kReserve = 10; |
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize, |
+ kReserve); |
+ std::vector<SimpleDerivedElement*> sde_list; |
+ // Add enough elements to cause another allocation. |
+ for (size_t i = 0; i < kReserve + 1; ++i) { |
+ sde_list.push_back(list.AllocateAndConstruct<SimpleDerivedElement>()); |
+ sde_list.back()->set_value(static_cast<int>(i)); |
+ } |
+ EXPECT_EQ(kReserve + 1, list.size()); |
+ |
+ // Remove everything in the first allocation. |
+ for (size_t i = 0; i < kReserve; ++i) |
+ list.EraseAndInvalidateAllPointers(list.begin()); |
+ EXPECT_EQ(1u, list.size()); |
+ |
+ // The last element is left. |
+ SimpleDerivedElement* de = static_cast<SimpleDerivedElement*>(*list.begin()); |
+ EXPECT_EQ(static_cast<int>(kReserve), de->get_value()); |
+ |
+ // Remove the element from the 2nd allocation. |
+ list.EraseAndInvalidateAllPointers(list.begin()); |
+ EXPECT_EQ(0u, list.size()); |
+} |
+ |
+TEST(ListContainerTest, DeletionAllInAllocationReversed) { |
+ const size_t kReserve = 10; |
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize, |
+ kReserve); |
+ std::vector<SimpleDerivedElement*> sde_list; |
+ // Add enough elements to cause another allocation. |
+ for (size_t i = 0; i < kReserve + 1; ++i) { |
+ sde_list.push_back(list.AllocateAndConstruct<SimpleDerivedElement>()); |
+ sde_list.back()->set_value(static_cast<int>(i)); |
+ } |
+ EXPECT_EQ(kReserve + 1, list.size()); |
+ |
+ // Remove everything in the 2nd allocation. |
+ auto it = list.begin(); |
+ for (size_t i = 0; i < kReserve; ++i) |
+ ++it; |
+ list.EraseAndInvalidateAllPointers(it); |
+ |
+ // The 2nd-last element is next, and the rest of the elements exist. |
+ size_t i = kReserve - 1; |
+ for (auto it = list.rbegin(); it != list.rend(); ++it) { |
+ SimpleDerivedElement* de = static_cast<SimpleDerivedElement*>(*it); |
+ EXPECT_EQ(static_cast<int>(i), de->get_value()); |
+ --i; |
+ } |
+ |
+ // Can forward iterate too. |
+ i = 0; |
+ for (auto it = list.begin(); it != list.end(); ++it) { |
+ SimpleDerivedElement* de = static_cast<SimpleDerivedElement*>(*it); |
+ EXPECT_EQ(static_cast<int>(i), de->get_value()); |
+ ++i; |
+ } |
+ |
+ // Remove the last thing from the 1st allocation. |
+ it = list.begin(); |
+ for (size_t i = 0; i < kReserve - 1; ++i) |
+ ++it; |
+ list.EraseAndInvalidateAllPointers(it); |
+ |
+ // The 2nd-last element is next, and the rest of the elements exist. |
+ i = kReserve - 2; |
+ for (auto it = list.rbegin(); it != list.rend(); ++it) { |
+ SimpleDerivedElement* de = static_cast<SimpleDerivedElement*>(*it); |
+ EXPECT_EQ(static_cast<int>(i), de->get_value()); |
+ --i; |
+ } |
+ |
+ // Can forward iterate too. |
+ i = 0; |
+ for (auto it = list.begin(); it != list.end(); ++it) { |
+ SimpleDerivedElement* de = static_cast<SimpleDerivedElement*>(*it); |
+ EXPECT_EQ(static_cast<int>(i), de->get_value()); |
+ ++i; |
+ } |
+} |
+ |
+TEST(ListContainerTest, SimpleIterationAndManipulation) { |
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize); |
+ std::vector<SimpleDerivedElement*> sde_list; |
+ size_t size = 10; |
+ for (size_t i = 0; i < size; ++i) { |
+ SimpleDerivedElement* simple_dq = |
+ list.AllocateAndConstruct<SimpleDerivedElement>(); |
+ sde_list.push_back(simple_dq); |
+ } |
+ EXPECT_EQ(size, list.size()); |
+ |
+ ListContainer<DerivedElement>::Iterator iter = list.begin(); |
+ for (int i = 0; i < 10; ++i) { |
+ static_cast<SimpleDerivedElement*>(*iter)->set_value(i); |
+ ++iter; |
+ } |
+ |
+ int i = 0; |
+ for (std::vector<SimpleDerivedElement*>::const_iterator sde_iter = |
+ sde_list.begin(); |
+ sde_iter < sde_list.end(); ++sde_iter) { |
+ EXPECT_EQ(i, (*sde_iter)->get_value()); |
+ ++i; |
+ } |
+} |
+ |
+TEST(ListContainerTest, SimpleManipulationWithIndexSimpleDerivedElement) { |
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize); |
+ std::vector<SimpleDerivedElement*> de_list; |
+ size_t size = 10; |
+ for (size_t i = 0; i < size; ++i) { |
+ de_list.push_back(list.AllocateAndConstruct<SimpleDerivedElement>()); |
+ } |
+ EXPECT_EQ(size, list.size()); |
+ |
+ for (size_t i = 0; i < size; ++i) { |
+ static_cast<SimpleDerivedElement*>(list.ElementAt(i))->set_value(i); |
+ } |
+ |
+ int i = 0; |
+ for (std::vector<SimpleDerivedElement*>::const_iterator |
+ de_iter = de_list.begin(); |
+ de_iter != de_list.end(); ++de_iter, ++i) { |
+ EXPECT_EQ(i, (*de_iter)->get_value()); |
+ } |
+} |
+ |
+TEST(ListContainerTest, |
+ SimpleManipulationWithIndexMoreThanOneAllocationSimpleDerivedElement) { |
+ ListContainer<DerivedElement> list(LargestDerivedElementSize(), 2); |
+ std::vector<SimpleDerivedElement*> de_list; |
+ size_t size = 10; |
+ for (size_t i = 0; i < size; ++i) { |
+ de_list.push_back(list.AllocateAndConstruct<SimpleDerivedElement>()); |
+ } |
+ EXPECT_EQ(size, list.size()); |
+ |
+ for (size_t i = 0; i < size; ++i) { |
+ static_cast<SimpleDerivedElement*>(list.ElementAt(i))->set_value(i); |
+ } |
+ |
+ int i = 0; |
+ for (std::vector<SimpleDerivedElement*>::const_iterator |
+ de_iter = de_list.begin(); |
+ de_iter != de_list.end(); ++de_iter, ++i) { |
+ EXPECT_EQ(i, (*de_iter)->get_value()); |
+ } |
+} |
+ |
+TEST(ListContainerTest, |
+ SimpleIterationAndReverseIterationWithIndexNonDerivedElement) { |
+ ListContainer<NonDerivedElement> list; |
+ std::vector<NonDerivedElement*> nde_list; |
+ size_t size = 10; |
+ for (size_t i = 0; i < size; ++i) { |
+ nde_list.push_back(list.AllocateAndConstruct<NonDerivedElement>()); |
+ } |
+ EXPECT_EQ(size, list.size()); |
+ |
+ size_t i = 0; |
+ for (ListContainer<NonDerivedElement>::Iterator iter = list.begin(); |
+ iter != list.end(); ++iter) { |
+ EXPECT_EQ(i, iter.index()); |
+ ++i; |
+ } |
+ |
+ i = 0; |
+ for (ListContainer<NonDerivedElement>::ReverseIterator iter = list.rbegin(); |
+ iter != list.rend(); ++iter) { |
+ EXPECT_EQ(i, iter.index()); |
+ ++i; |
+ } |
+} |
+ |
+} // namespace |
+} // namespace cc |