[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / unittests / ADT / BumpPtrListTest.cpp
blobebd0ce2532f4fb98c95839bc2e1076955bd4703d
1 //===- unittests/ADT/BumpPtrListTest.cpp - BumpPtrList unit tests ---------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/AllocatorList.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "gtest/gtest.h"
13 using namespace llvm;
15 namespace {
17 struct CountsDestructors {
18 static unsigned NumCalls;
19 ~CountsDestructors() { ++NumCalls; }
21 unsigned CountsDestructors::NumCalls = 0;
23 struct MoveOnly {
24 int V;
25 explicit MoveOnly(int V) : V(V) {}
26 MoveOnly() = delete;
27 MoveOnly(MoveOnly &&X) { V = X.V; }
28 MoveOnly(const MoveOnly &X) = delete;
29 MoveOnly &operator=(MoveOnly &&X) = delete;
30 MoveOnly &operator=(const MoveOnly &X) = delete;
33 struct EmplaceOnly {
34 int V1, V2;
35 explicit EmplaceOnly(int V1, int V2) : V1(V1), V2(V2) {}
36 EmplaceOnly() = delete;
37 EmplaceOnly(EmplaceOnly &&X) = delete;
38 EmplaceOnly(const EmplaceOnly &X) = delete;
39 EmplaceOnly &operator=(EmplaceOnly &&X) = delete;
40 EmplaceOnly &operator=(const EmplaceOnly &X) = delete;
43 TEST(BumpPtrListTest, DefaultConstructor) {
44 BumpPtrList<int> L;
45 EXPECT_TRUE(L.empty());
48 TEST(BumpPtrListTest, pushPopBack) {
49 // Build a list with push_back.
50 BumpPtrList<int> L;
51 int Ns[] = {1, 3, 9, 5, 7};
52 for (const int N : Ns)
53 L.push_back(N);
55 // Use iterators to check contents.
56 auto I = L.begin();
57 for (int N : Ns)
58 EXPECT_EQ(N, *I++);
59 EXPECT_EQ(I, L.end());
61 // Unbuild the list with pop_back.
62 for (int N : llvm::reverse(Ns)) {
63 EXPECT_EQ(N, L.back());
64 L.pop_back();
66 EXPECT_TRUE(L.empty());
69 TEST(BumpPtrListTest, pushPopFront) {
70 // Build a list with push_front.
71 BumpPtrList<int> L;
72 int Ns[] = {1, 3, 9, 5, 7};
73 for (const int N : Ns)
74 L.push_front(N);
76 // Use reverse iterators to check contents.
77 auto I = L.rbegin();
78 for (int N : Ns)
79 EXPECT_EQ(N, *I++);
80 EXPECT_EQ(I, L.rend());
82 // Unbuild the list with pop_front.
83 for (int N : llvm::reverse(Ns)) {
84 EXPECT_EQ(N, L.front());
85 L.pop_front();
87 EXPECT_TRUE(L.empty());
90 TEST(BumpPtrListTest, pushBackMoveOnly) {
91 BumpPtrList<MoveOnly> L;
92 int Ns[] = {1, 3, 9, 5, 7};
93 for (const int N : Ns) {
94 L.push_back(MoveOnly(N));
95 EXPECT_EQ(N, L.back().V);
97 // Instantiate with MoveOnly.
98 while (!L.empty())
99 L.pop_back();
102 TEST(BumpPtrListTest, pushFrontMoveOnly) {
103 BumpPtrList<MoveOnly> L;
104 int Ns[] = {1, 3, 9, 5, 7};
105 for (const int N : Ns) {
106 L.push_front(MoveOnly(N));
107 EXPECT_EQ(N, L.front().V);
109 // Instantiate with MoveOnly.
110 while (!L.empty())
111 L.pop_front();
114 TEST(BumpPtrListTest, emplaceBack) {
115 BumpPtrList<EmplaceOnly> L;
116 int N1s[] = {1, 3, 9, 5, 7};
117 int N2s[] = {7, 3, 1, 8, 2};
118 for (int I = 0; I != 5; ++I) {
119 L.emplace_back(N1s[I], N2s[I]);
120 EXPECT_EQ(N1s[I], L.back().V1);
121 EXPECT_EQ(N2s[I], L.back().V2);
123 // Instantiate with EmplaceOnly.
124 while (!L.empty())
125 L.pop_back();
128 TEST(BumpPtrListTest, emplaceFront) {
129 BumpPtrList<EmplaceOnly> L;
130 int N1s[] = {1, 3, 9, 5, 7};
131 int N2s[] = {7, 3, 1, 8, 2};
132 for (int I = 0; I != 5; ++I) {
133 L.emplace_front(N1s[I], N2s[I]);
134 EXPECT_EQ(N1s[I], L.front().V1);
135 EXPECT_EQ(N2s[I], L.front().V2);
137 // Instantiate with EmplaceOnly.
138 while (!L.empty())
139 L.pop_front();
142 TEST(BumpPtrListTest, swap) {
143 // Build two lists with different lifetimes and swap them.
144 int N1s[] = {1, 3, 5, 7, 9};
145 int N2s[] = {2, 4, 6, 8, 10};
147 BumpPtrList<int> L1;
148 L1.insert(L1.end(), std::begin(N1s), std::end(N1s));
150 BumpPtrList<int> L2;
151 L2.insert(L2.end(), std::begin(N2s), std::end(N2s));
153 // Swap the lists.
154 L1.swap(L2);
156 // Check L2's contents before it goes out of scope.
157 auto I = L2.begin();
158 for (int N : N1s)
159 EXPECT_EQ(N, *I++);
160 EXPECT_EQ(I, L2.end());
163 // Check L1's contents now that L2 is out of scope (with its allocation
164 // blocks).
165 auto I = L1.begin();
166 for (int N : N2s)
167 EXPECT_EQ(N, *I++);
168 EXPECT_EQ(I, L1.end());
171 TEST(BumpPtrListTest, clear) {
172 CountsDestructors::NumCalls = 0;
173 CountsDestructors N;
174 BumpPtrList<CountsDestructors> L;
175 L.push_back(N);
176 L.push_back(N);
177 L.push_back(N);
178 EXPECT_EQ(3u, L.size());
179 EXPECT_EQ(0u, CountsDestructors::NumCalls);
180 L.pop_back();
181 EXPECT_EQ(1u, CountsDestructors::NumCalls);
182 L.clear();
183 EXPECT_EQ(3u, CountsDestructors::NumCalls);
186 TEST(BumpPtrListTest, move) {
187 BumpPtrList<int> L1, L2;
188 L1.push_back(1);
189 L2.push_back(2);
190 L1 = std::move(L2);
191 EXPECT_EQ(1u, L1.size());
192 EXPECT_EQ(2, L1.front());
193 EXPECT_EQ(0u, L2.size());
196 TEST(BumpPtrListTest, moveCallsDestructors) {
197 CountsDestructors::NumCalls = 0;
198 BumpPtrList<CountsDestructors> L1, L2;
199 L1.emplace_back();
200 EXPECT_EQ(0u, CountsDestructors::NumCalls);
201 L1 = std::move(L2);
202 EXPECT_EQ(1u, CountsDestructors::NumCalls);
205 TEST(BumpPtrListTest, copy) {
206 BumpPtrList<int> L1, L2;
207 L1.push_back(1);
208 L2.push_back(2);
209 L1 = L2;
210 EXPECT_EQ(1u, L1.size());
211 EXPECT_EQ(2, L1.front());
212 EXPECT_EQ(1u, L2.size());
213 EXPECT_EQ(2, L2.front());
216 TEST(BumpPtrListTest, copyCallsDestructors) {
217 CountsDestructors::NumCalls = 0;
218 BumpPtrList<CountsDestructors> L1, L2;
219 L1.emplace_back();
220 EXPECT_EQ(0u, CountsDestructors::NumCalls);
221 L1 = L2;
222 EXPECT_EQ(1u, CountsDestructors::NumCalls);
225 TEST(BumpPtrListTest, resetAlloc) {
226 // Resetting an empty list should work.
227 BumpPtrList<int> L;
229 // Resetting an empty list that has allocated should also work.
230 L.resetAlloc();
231 L.push_back(5);
232 L.erase(L.begin());
233 L.resetAlloc();
235 // Resetting a non-empty list should crash.
236 L.push_back(5);
237 #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)
238 EXPECT_DEATH(L.resetAlloc(), "Cannot reset allocator if not empty");
239 #endif
242 } // end namespace