1 //===- unittests/ADT/BumpPtrListTest.cpp - BumpPtrList unit tests ---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/AllocatorList.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "gtest/gtest.h"
18 struct CountsDestructors
{
19 static unsigned NumCalls
;
20 ~CountsDestructors() { ++NumCalls
; }
22 unsigned CountsDestructors::NumCalls
= 0;
26 explicit MoveOnly(int V
) : V(V
) {}
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;
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;
44 TEST(BumpPtrListTest
, DefaultConstructor
) {
46 EXPECT_TRUE(L
.empty());
49 TEST(BumpPtrListTest
, pushPopBack
) {
50 // Build a list with push_back.
52 int Ns
[] = {1, 3, 9, 5, 7};
53 for (const int N
: Ns
)
56 // Use iterators to check contents.
60 EXPECT_EQ(I
, L
.end());
62 // Unbuild the list with pop_back.
63 for (int N
: llvm::reverse(Ns
)) {
64 EXPECT_EQ(N
, L
.back());
67 EXPECT_TRUE(L
.empty());
70 TEST(BumpPtrListTest
, pushPopFront
) {
71 // Build a list with push_front.
73 int Ns
[] = {1, 3, 9, 5, 7};
74 for (const int N
: Ns
)
77 // Use reverse iterators to check contents.
81 EXPECT_EQ(I
, L
.rend());
83 // Unbuild the list with pop_front.
84 for (int N
: llvm::reverse(Ns
)) {
85 EXPECT_EQ(N
, L
.front());
88 EXPECT_TRUE(L
.empty());
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
);
98 // Instantiate with MoveOnly.
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
);
110 // Instantiate with MoveOnly.
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
);
124 // Instantiate with EmplaceOnly.
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
);
138 // Instantiate with EmplaceOnly.
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};
149 L1
.insert(L1
.end(), std::begin(N1s
), std::end(N1s
));
152 L2
.insert(L2
.end(), std::begin(N2s
), std::end(N2s
));
157 // Check L2's contents before it goes out of scope.
161 EXPECT_EQ(I
, L2
.end());
164 // Check L1's contents now that L2 is out of scope (with its allocation
169 EXPECT_EQ(I
, L1
.end());
172 TEST(BumpPtrListTest
, clear
) {
173 CountsDestructors::NumCalls
= 0;
175 BumpPtrList
<CountsDestructors
> L
;
179 EXPECT_EQ(3u, L
.size());
180 EXPECT_EQ(0u, CountsDestructors::NumCalls
);
182 EXPECT_EQ(1u, CountsDestructors::NumCalls
);
184 EXPECT_EQ(3u, CountsDestructors::NumCalls
);
187 TEST(BumpPtrListTest
, move
) {
188 BumpPtrList
<int> L1
, L2
;
192 EXPECT_EQ(1u, L1
.size());
193 EXPECT_EQ(2, L1
.front());
194 EXPECT_EQ(0u, L2
.size());
197 TEST(BumpPtrListTest
, moveCallsDestructors
) {
198 CountsDestructors::NumCalls
= 0;
199 BumpPtrList
<CountsDestructors
> L1
, L2
;
201 EXPECT_EQ(0u, CountsDestructors::NumCalls
);
203 EXPECT_EQ(1u, CountsDestructors::NumCalls
);
206 TEST(BumpPtrListTest
, copy
) {
207 BumpPtrList
<int> 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());
217 TEST(BumpPtrListTest
, copyCallsDestructors
) {
218 CountsDestructors::NumCalls
= 0;
219 BumpPtrList
<CountsDestructors
> L1
, L2
;
221 EXPECT_EQ(0u, CountsDestructors::NumCalls
);
223 EXPECT_EQ(1u, CountsDestructors::NumCalls
);
226 TEST(BumpPtrListTest
, resetAlloc
) {
227 // Resetting an empty list should work.
230 // Resetting an empty list that has allocated should also work.
236 // Resetting a non-empty list should crash.
238 #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)
239 EXPECT_DEATH(L
.resetAlloc(), "Cannot reset allocator if not empty");