1 //===- unittests/ADT/BumpPtrListTest.cpp - BumpPtrList unit tests ---------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ADT/AllocatorList.h" 11 #include "llvm/ADT/STLExtras.h" 12 #include "gtest/gtest.h" 13 14 using namespace llvm; 15 16 namespace { 17 18 struct CountsDestructors { 19 static unsigned NumCalls; 20 ~CountsDestructors() { ++NumCalls; } 21 }; 22 unsigned CountsDestructors::NumCalls = 0; 23 24 struct MoveOnly { 25 int V; 26 explicit MoveOnly(int V) : V(V) {} 27 MoveOnly() = delete; 28 MoveOnly(MoveOnly &&X) { V = X.V; } 29 MoveOnly(const MoveOnly &X) = delete; 30 MoveOnly &operator=(MoveOnly &&X) = delete; 31 MoveOnly &operator=(const MoveOnly &X) = delete; 32 }; 33 34 struct EmplaceOnly { 35 int V1, V2; 36 explicit EmplaceOnly(int V1, int V2) : V1(V1), V2(V2) {} 37 EmplaceOnly() = delete; 38 EmplaceOnly(EmplaceOnly &&X) = delete; 39 EmplaceOnly(const EmplaceOnly &X) = delete; 40 EmplaceOnly &operator=(EmplaceOnly &&X) = delete; 41 EmplaceOnly &operator=(const EmplaceOnly &X) = delete; 42 }; 43 44 TEST(BumpPtrListTest, DefaultConstructor) { 45 BumpPtrList<int> L; 46 EXPECT_TRUE(L.empty()); 47 } 48 49 TEST(BumpPtrListTest, pushPopBack) { 50 // Build a list with push_back. 51 BumpPtrList<int> L; 52 int Ns[] = {1, 3, 9, 5, 7}; 53 for (const int N : Ns) 54 L.push_back(N); 55 56 // Use iterators to check contents. 57 auto I = L.begin(); 58 for (int N : Ns) 59 EXPECT_EQ(N, *I++); 60 EXPECT_EQ(I, L.end()); 61 62 // Unbuild the list with pop_back. 63 for (int N : llvm::reverse(Ns)) { 64 EXPECT_EQ(N, L.back()); 65 L.pop_back(); 66 } 67 EXPECT_TRUE(L.empty()); 68 } 69 70 TEST(BumpPtrListTest, pushPopFront) { 71 // Build a list with push_front. 72 BumpPtrList<int> L; 73 int Ns[] = {1, 3, 9, 5, 7}; 74 for (const int N : Ns) 75 L.push_front(N); 76 77 // Use reverse iterators to check contents. 78 auto I = L.rbegin(); 79 for (int N : Ns) 80 EXPECT_EQ(N, *I++); 81 EXPECT_EQ(I, L.rend()); 82 83 // Unbuild the list with pop_front. 84 for (int N : llvm::reverse(Ns)) { 85 EXPECT_EQ(N, L.front()); 86 L.pop_front(); 87 } 88 EXPECT_TRUE(L.empty()); 89 } 90 91 TEST(BumpPtrListTest, pushBackMoveOnly) { 92 BumpPtrList<MoveOnly> L; 93 int Ns[] = {1, 3, 9, 5, 7}; 94 for (const int N : Ns) { 95 L.push_back(MoveOnly(N)); 96 EXPECT_EQ(N, L.back().V); 97 } 98 // Instantiate with MoveOnly. 99 while (!L.empty()) 100 L.pop_back(); 101 } 102 103 TEST(BumpPtrListTest, pushFrontMoveOnly) { 104 BumpPtrList<MoveOnly> L; 105 int Ns[] = {1, 3, 9, 5, 7}; 106 for (const int N : Ns) { 107 L.push_front(MoveOnly(N)); 108 EXPECT_EQ(N, L.front().V); 109 } 110 // Instantiate with MoveOnly. 111 while (!L.empty()) 112 L.pop_front(); 113 } 114 115 TEST(BumpPtrListTest, emplaceBack) { 116 BumpPtrList<EmplaceOnly> L; 117 int N1s[] = {1, 3, 9, 5, 7}; 118 int N2s[] = {7, 3, 1, 8, 2}; 119 for (int I = 0; I != 5; ++I) { 120 L.emplace_back(N1s[I], N2s[I]); 121 EXPECT_EQ(N1s[I], L.back().V1); 122 EXPECT_EQ(N2s[I], L.back().V2); 123 } 124 // Instantiate with EmplaceOnly. 125 while (!L.empty()) 126 L.pop_back(); 127 } 128 129 TEST(BumpPtrListTest, emplaceFront) { 130 BumpPtrList<EmplaceOnly> L; 131 int N1s[] = {1, 3, 9, 5, 7}; 132 int N2s[] = {7, 3, 1, 8, 2}; 133 for (int I = 0; I != 5; ++I) { 134 L.emplace_front(N1s[I], N2s[I]); 135 EXPECT_EQ(N1s[I], L.front().V1); 136 EXPECT_EQ(N2s[I], L.front().V2); 137 } 138 // Instantiate with EmplaceOnly. 139 while (!L.empty()) 140 L.pop_front(); 141 } 142 143 TEST(BumpPtrListTest, swap) { 144 // Build two lists with different lifetimes and swap them. 145 int N1s[] = {1, 3, 5, 7, 9}; 146 int N2s[] = {2, 4, 6, 8, 10}; 147 148 BumpPtrList<int> L1; 149 L1.insert(L1.end(), std::begin(N1s), std::end(N1s)); 150 { 151 BumpPtrList<int> L2; 152 L2.insert(L2.end(), std::begin(N2s), std::end(N2s)); 153 154 // Swap the lists. 155 L1.swap(L2); 156 157 // Check L2's contents before it goes out of scope. 158 auto I = L2.begin(); 159 for (int N : N1s) 160 EXPECT_EQ(N, *I++); 161 EXPECT_EQ(I, L2.end()); 162 } 163 164 // Check L1's contents now that L2 is out of scope (with its allocation 165 // blocks). 166 auto I = L1.begin(); 167 for (int N : N2s) 168 EXPECT_EQ(N, *I++); 169 EXPECT_EQ(I, L1.end()); 170 } 171 172 TEST(BumpPtrListTest, clear) { 173 CountsDestructors::NumCalls = 0; 174 CountsDestructors N; 175 BumpPtrList<CountsDestructors> L; 176 L.push_back(N); 177 L.push_back(N); 178 L.push_back(N); 179 EXPECT_EQ(3u, L.size()); 180 EXPECT_EQ(0u, CountsDestructors::NumCalls); 181 L.pop_back(); 182 EXPECT_EQ(1u, CountsDestructors::NumCalls); 183 L.clear(); 184 EXPECT_EQ(3u, CountsDestructors::NumCalls); 185 } 186 187 TEST(BumpPtrListTest, move) { 188 BumpPtrList<int> L1, L2; 189 L1.push_back(1); 190 L2.push_back(2); 191 L1 = std::move(L2); 192 EXPECT_EQ(1u, L1.size()); 193 EXPECT_EQ(2, L1.front()); 194 EXPECT_EQ(0u, L2.size()); 195 } 196 197 TEST(BumpPtrListTest, moveCallsDestructors) { 198 CountsDestructors::NumCalls = 0; 199 BumpPtrList<CountsDestructors> L1, L2; 200 L1.emplace_back(); 201 EXPECT_EQ(0u, CountsDestructors::NumCalls); 202 L1 = std::move(L2); 203 EXPECT_EQ(1u, CountsDestructors::NumCalls); 204 } 205 206 TEST(BumpPtrListTest, copy) { 207 BumpPtrList<int> L1, L2; 208 L1.push_back(1); 209 L2.push_back(2); 210 L1 = L2; 211 EXPECT_EQ(1u, L1.size()); 212 EXPECT_EQ(2, L1.front()); 213 EXPECT_EQ(1u, L2.size()); 214 EXPECT_EQ(2, L2.front()); 215 } 216 217 TEST(BumpPtrListTest, copyCallsDestructors) { 218 CountsDestructors::NumCalls = 0; 219 BumpPtrList<CountsDestructors> L1, L2; 220 L1.emplace_back(); 221 EXPECT_EQ(0u, CountsDestructors::NumCalls); 222 L1 = L2; 223 EXPECT_EQ(1u, CountsDestructors::NumCalls); 224 } 225 226 TEST(BumpPtrListTest, resetAlloc) { 227 // Resetting an empty list should work. 228 BumpPtrList<int> L; 229 230 // Resetting an empty list that has allocated should also work. 231 L.resetAlloc(); 232 L.push_back(5); 233 L.erase(L.begin()); 234 L.resetAlloc(); 235 236 // Resetting a non-empty list should crash. 237 L.push_back(5); 238 #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) 239 EXPECT_DEATH(L.resetAlloc(), "Cannot reset allocator if not empty"); 240 #endif 241 } 242 243 } // end namespace 244