blob: 7404bee88c220040594ea25c52d557fb4604093a [file] [log] [blame]
Bill Wendling3d9fbee2009-01-11 01:25:51 +00001//===- llvm/unittest/ADT/SmallVectorTest.cpp ------------------------------===//
Bill Wendlingf2850d92009-01-10 12:56:31 +00002//
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// SmallVector unit tests.
11//
12//===----------------------------------------------------------------------===//
13
14#include "gtest/gtest.h"
15#include "llvm/ADT/SmallVector.h"
16#include <stdarg.h>
17
18using namespace llvm;
19
20namespace {
21
22/// A helper class that counts the total number of constructor and
23/// destructor calls.
24class Constructable {
25private:
26 static int numConstructorCalls;
27 static int numDestructorCalls;
28 static int numAssignmentCalls;
29
30 int value;
31
32public:
33 Constructable() : value(0) {
34 ++numConstructorCalls;
35 }
36
37 Constructable(int val) : value(val) {
38 ++numConstructorCalls;
39 }
40
41 Constructable(const Constructable & src) {
42 value = src.value;
43 ++numConstructorCalls;
44 }
45
46 ~Constructable() {
47 ++numDestructorCalls;
48 }
49
50 Constructable & operator=(const Constructable & src) {
51 value = src.value;
52 ++numAssignmentCalls;
53 return *this;
54 }
55
56 int getValue() const {
57 return abs(value);
58 }
59
60 static void reset() {
61 numConstructorCalls = 0;
62 numDestructorCalls = 0;
63 numAssignmentCalls = 0;
64 }
65
66 static int getNumConstructorCalls() {
67 return numConstructorCalls;
68 }
69
70 static int getNumDestructorCalls() {
71 return numDestructorCalls;
72 }
73
74 friend bool operator==(const Constructable & c0, const Constructable & c1) {
75 return c0.getValue() == c1.getValue();
76 }
77
78 friend bool operator!=(const Constructable & c0, const Constructable & c1) {
79 return c0.getValue() != c1.getValue();
80 }
81};
82
83int Constructable::numConstructorCalls;
84int Constructable::numDestructorCalls;
85int Constructable::numAssignmentCalls;
86
87// Test fixture class
88class SmallVectorTest : public testing::Test {
89protected:
90 typedef SmallVector<Constructable, 4> VectorType;
91
92 VectorType theVector;
93 VectorType otherVector;
94
95 void SetUp() {
96 Constructable::reset();
97 }
98
99 void assertEmpty(VectorType & v) {
100 // Size tests
101 EXPECT_EQ(0u, v.size());
102 EXPECT_TRUE(v.empty());
103
104 // Iterator tests
105 EXPECT_TRUE(v.begin() == v.end());
106 }
107
108 // Assert that theVector contains the specified values, in order.
109 void assertValuesInOrder(VectorType & v, size_t size, ...) {
110 EXPECT_EQ(size, v.size());
111
112 va_list ap;
113 va_start(ap, size);
114 for (size_t i = 0; i < size; ++i) {
115 int value = va_arg(ap, int);
116 EXPECT_EQ(value, v[i].getValue());
117 }
118
119 va_end(ap);
120 }
121
122 // Generate a sequence of values to initialize the vector.
123 void makeSequence(VectorType & v, int start, int end) {
124 for (int i = start; i <= end; ++i) {
125 v.push_back(Constructable(i));
126 }
127 }
128};
129
130// New vector test.
131TEST_F(SmallVectorTest, EmptyVectorTest) {
132 SCOPED_TRACE("EmptyVectorTest");
133 assertEmpty(theVector);
134 EXPECT_TRUE(theVector.rbegin() == theVector.rend());
135 EXPECT_EQ(0, Constructable::getNumConstructorCalls());
136 EXPECT_EQ(0, Constructable::getNumDestructorCalls());
137}
138
139// Simple insertions and deletions.
140TEST_F(SmallVectorTest, PushPopTest) {
141 SCOPED_TRACE("PushPopTest");
142
143 // Push an element
144 theVector.push_back(Constructable(1));
145
146 // Size tests
147 assertValuesInOrder(theVector, 1u, 1);
148 EXPECT_FALSE(theVector.begin() == theVector.end());
149 EXPECT_FALSE(theVector.empty());
150
151 // Push another element
152 theVector.push_back(Constructable(2));
153 assertValuesInOrder(theVector, 2u, 1, 2);
154
155 // Pop one element
156 theVector.pop_back();
157 assertValuesInOrder(theVector, 1u, 1);
158
159 // Pop another element
160 theVector.pop_back();
161 assertEmpty(theVector);
162
163 // Check number of constructor calls. Should be 2 for each list element,
164 // one for the argument to push_back, and one for the list element itself.
165 EXPECT_EQ(4, Constructable::getNumConstructorCalls());
166 EXPECT_EQ(4, Constructable::getNumDestructorCalls());
167}
168
169// Clear test.
170TEST_F(SmallVectorTest, ClearTest) {
171 SCOPED_TRACE("ClearTest");
172
173 makeSequence(theVector, 1, 2);
174 theVector.clear();
175
176 assertEmpty(theVector);
177 EXPECT_EQ(4, Constructable::getNumConstructorCalls());
178 EXPECT_EQ(4, Constructable::getNumDestructorCalls());
179}
180
181// Resize smaller test.
182TEST_F(SmallVectorTest, ResizeShrinkTest) {
183 SCOPED_TRACE("ResizeShrinkTest");
184
185 makeSequence(theVector, 1, 3);
186 theVector.resize(1);
187
188 assertValuesInOrder(theVector, 1u, 1);
189 EXPECT_EQ(6, Constructable::getNumConstructorCalls());
190 EXPECT_EQ(5, Constructable::getNumDestructorCalls());
191}
192
193// Resize bigger test.
194TEST_F(SmallVectorTest, ResizeGrowTest) {
195 SCOPED_TRACE("ResizeGrowTest");
196
197 theVector.resize(2);
198
199 // XXX: I don't know where the extra construct/destruct is coming from.
200 EXPECT_EQ(3, Constructable::getNumConstructorCalls());
201 EXPECT_EQ(1, Constructable::getNumDestructorCalls());
202 EXPECT_EQ(2u, theVector.size());
203}
204
205// Resize with fill value.
206TEST_F(SmallVectorTest, ResizeFillTest) {
207 SCOPED_TRACE("ResizeFillTest");
208
209 theVector.resize(3, Constructable(77));
210 assertValuesInOrder(theVector, 3u, 77, 77, 77);
211}
212
213// Overflow past fixed size.
214TEST_F(SmallVectorTest, OverflowTest) {
215 SCOPED_TRACE("OverflowTest");
216
217 // Push more elements than the fixed size
218 makeSequence(theVector, 1, 10);
219
220 // test size and values
221 EXPECT_EQ(10u, theVector.size());
222 for (int i = 0; i < 10; ++i) {
223 EXPECT_EQ(i+1, theVector[i].getValue());
224 }
225
226 // Now resize back to fixed size
227 theVector.resize(1);
228
229 assertValuesInOrder(theVector, 1u, 1);
230}
231
232// Iteration tests.
233TEST_F(SmallVectorTest, IterationTest) {
234 makeSequence(theVector, 1, 2);
235
236 // Forward Iteration
237 VectorType::iterator it = theVector.begin();
238 EXPECT_TRUE(*it == theVector.front());
239 EXPECT_TRUE(*it == theVector[0]);
240 EXPECT_EQ(1, it->getValue());
241 ++it;
242 EXPECT_TRUE(*it == theVector[1]);
243 EXPECT_TRUE(*it == theVector.back());
244 EXPECT_EQ(2, it->getValue());
245 ++it;
246 EXPECT_TRUE(it == theVector.end());
247 --it;
248 EXPECT_TRUE(*it == theVector[1]);
249 EXPECT_EQ(2, it->getValue());
250 --it;
251 EXPECT_TRUE(*it == theVector[0]);
252 EXPECT_EQ(1, it->getValue());
253
254 // Reverse Iteration
255 VectorType::reverse_iterator rit = theVector.rbegin();
256 EXPECT_TRUE(*rit == theVector[1]);
257 EXPECT_EQ(2, rit->getValue());
258 ++rit;
259 EXPECT_TRUE(*rit == theVector[0]);
260 EXPECT_EQ(1, rit->getValue());
261 ++rit;
262 EXPECT_TRUE(rit == theVector.rend());
263 --rit;
264 EXPECT_TRUE(*rit == theVector[0]);
265 EXPECT_EQ(1, rit->getValue());
266 --rit;
267 EXPECT_TRUE(*rit == theVector[1]);
268 EXPECT_EQ(2, rit->getValue());
269}
270
271// Swap test.
272TEST_F(SmallVectorTest, SwapTest) {
273 SCOPED_TRACE("SwapTest");
274
275 makeSequence(theVector, 1, 2);
276 std::swap(theVector, otherVector);
277
278 assertEmpty(theVector);
279 assertValuesInOrder(otherVector, 2u, 1, 2);
280}
281
282// Append test
283TEST_F(SmallVectorTest, AppendTest) {
284 SCOPED_TRACE("AppendTest");
285
286 makeSequence(otherVector, 2, 3);
287
288 theVector.push_back(Constructable(1));
289 theVector.append(otherVector.begin(), otherVector.end());
290
291 assertValuesInOrder(theVector, 3u, 1, 2, 3);
292}
293
294// Append repeated test
295TEST_F(SmallVectorTest, AppendRepeatedTest) {
296 SCOPED_TRACE("AppendRepeatedTest");
297
298 theVector.push_back(Constructable(1));
299 theVector.append(2, Constructable(77));
300 assertValuesInOrder(theVector, 3u, 1, 77, 77);
301}
302
303// Assign test
304TEST_F(SmallVectorTest, AssignTest) {
305 SCOPED_TRACE("AssignTest");
306
307 theVector.push_back(Constructable(1));
308 theVector.assign(2, Constructable(77));
309 assertValuesInOrder(theVector, 2u, 77, 77);
310}
311
312// Erase a single element
313TEST_F(SmallVectorTest, EraseTest) {
314 SCOPED_TRACE("EraseTest");
315
316 makeSequence(theVector, 1, 3);
317 theVector.erase(theVector.begin());
318 assertValuesInOrder(theVector, 2u, 2, 3);
319}
320
321// Erase a range of elements
322TEST_F(SmallVectorTest, EraseRangeTest) {
323 SCOPED_TRACE("EraseRangeTest");
324
325 makeSequence(theVector, 1, 3);
326 theVector.erase(theVector.begin(), theVector.begin() + 2);
327 assertValuesInOrder(theVector, 1u, 3);
328}
329
330// Insert a single element.
331TEST_F(SmallVectorTest, InsertTest) {
332 SCOPED_TRACE("InsertTest");
333
334 makeSequence(theVector, 1, 3);
335 theVector.insert(theVector.begin() + 1, Constructable(77));
336 assertValuesInOrder(theVector, 4u, 1, 77, 2, 3);
337}
338
339// Insert repeated elements.
340TEST_F(SmallVectorTest, InsertRepeatedTest) {
341 SCOPED_TRACE("InsertRepeatedTest");
342
343 makeSequence(theVector, 1, 3);
344 theVector.insert(theVector.begin() + 1, 3, Constructable(77));
345 assertValuesInOrder(theVector, 6u, 1, 77, 77, 77, 2, 3);
346}
347
348// Insert range.
349TEST_F(SmallVectorTest, InsertRangeTest) {
350 SCOPED_TRACE("InsertRepeatedTest");
351
352 makeSequence(theVector, 1, 3);
353 theVector.insert(theVector.begin() + 1, 3, Constructable(77));
354 assertValuesInOrder(theVector, 6u, 1, 77, 77, 77, 2, 3);
355}
356
357// Comparison tests.
358TEST_F(SmallVectorTest, ComparisonTest) {
359 SCOPED_TRACE("ComparisonTest");
360
361 makeSequence(theVector, 1, 3);
362 makeSequence(otherVector, 1, 3);
363
364 EXPECT_TRUE(theVector == otherVector);
365 EXPECT_FALSE(theVector != otherVector);
366
367 otherVector.clear();
368 makeSequence(otherVector, 2, 4);
369
370 EXPECT_FALSE(theVector == otherVector);
371 EXPECT_TRUE(theVector != otherVector);
372}
373
374// Constant vector tests.
375TEST_F(SmallVectorTest, ConstVectorTest) {
376 const VectorType constVector;
377
378 EXPECT_EQ(0u, constVector.size());
379 EXPECT_TRUE(constVector.empty());
380 EXPECT_TRUE(constVector.begin() == constVector.end());
381}
382
383}