• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
~CountsDestructors__anon18575cfd0111::CountsDestructors20   ~CountsDestructors() { ++NumCalls; }
21 };
22 unsigned CountsDestructors::NumCalls = 0;
23 
24 struct MoveOnly {
25   int V;
MoveOnly__anon18575cfd0111::MoveOnly26   explicit MoveOnly(int V) : V(V) {}
27   MoveOnly() = delete;
MoveOnly__anon18575cfd0111::MoveOnly28   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;
EmplaceOnly__anon18575cfd0111::EmplaceOnly36   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 
TEST(BumpPtrListTest,DefaultConstructor)44 TEST(BumpPtrListTest, DefaultConstructor) {
45   BumpPtrList<int> L;
46   EXPECT_TRUE(L.empty());
47 }
48 
TEST(BumpPtrListTest,pushPopBack)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 
TEST(BumpPtrListTest,pushPopFront)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 
TEST(BumpPtrListTest,pushBackMoveOnly)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 
TEST(BumpPtrListTest,pushFrontMoveOnly)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 
TEST(BumpPtrListTest,emplaceBack)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 
TEST(BumpPtrListTest,emplaceFront)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 
TEST(BumpPtrListTest,swap)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 
TEST(BumpPtrListTest,clear)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 
TEST(BumpPtrListTest,move)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 
TEST(BumpPtrListTest,moveCallsDestructors)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 
TEST(BumpPtrListTest,copy)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 
TEST(BumpPtrListTest,copyCallsDestructors)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 
TEST(BumpPtrListTest,resetAlloc)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