blob: 8f6d2f4ac1509054489b8222dc70c8cf887b0516 [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"
Bill Wendlingd4008502010-08-19 18:52:02 +000016#include "llvm/Support/Compiler.h"
Bill Wendlingf2850d92009-01-10 12:56:31 +000017#include <stdarg.h>
Dan Gohmana7a33fd2010-03-26 18:53:37 +000018#include <list>
Bill Wendlingf2850d92009-01-10 12:56:31 +000019
20using namespace llvm;
21
22namespace {
23
24/// A helper class that counts the total number of constructor and
25/// destructor calls.
26class Constructable {
27private:
28 static int numConstructorCalls;
29 static int numDestructorCalls;
30 static int numAssignmentCalls;
31
32 int value;
33
34public:
35 Constructable() : value(0) {
36 ++numConstructorCalls;
37 }
Owen Anderson9cbd7af2011-07-06 22:36:59 +000038
Bill Wendlingf2850d92009-01-10 12:56:31 +000039 Constructable(int val) : value(val) {
40 ++numConstructorCalls;
41 }
Owen Anderson9cbd7af2011-07-06 22:36:59 +000042
Bill Wendlingf2850d92009-01-10 12:56:31 +000043 Constructable(const Constructable & src) {
44 value = src.value;
45 ++numConstructorCalls;
46 }
Owen Anderson9cbd7af2011-07-06 22:36:59 +000047
Bill Wendlingf2850d92009-01-10 12:56:31 +000048 ~Constructable() {
49 ++numDestructorCalls;
50 }
Owen Anderson9cbd7af2011-07-06 22:36:59 +000051
Bill Wendlingf2850d92009-01-10 12:56:31 +000052 Constructable & operator=(const Constructable & src) {
53 value = src.value;
54 ++numAssignmentCalls;
55 return *this;
56 }
Owen Anderson9cbd7af2011-07-06 22:36:59 +000057
Bill Wendlingf2850d92009-01-10 12:56:31 +000058 int getValue() const {
59 return abs(value);
60 }
61
62 static void reset() {
63 numConstructorCalls = 0;
64 numDestructorCalls = 0;
65 numAssignmentCalls = 0;
66 }
Owen Anderson9cbd7af2011-07-06 22:36:59 +000067
Bill Wendlingf2850d92009-01-10 12:56:31 +000068 static int getNumConstructorCalls() {
69 return numConstructorCalls;
70 }
71
72 static int getNumDestructorCalls() {
73 return numDestructorCalls;
74 }
75
76 friend bool operator==(const Constructable & c0, const Constructable & c1) {
77 return c0.getValue() == c1.getValue();
78 }
79
Chandler Carruth100c2672010-10-23 08:10:43 +000080 friend bool LLVM_ATTRIBUTE_UNUSED
Bill Wendlingd4008502010-08-19 18:52:02 +000081 operator!=(const Constructable & c0, const Constructable & c1) {
Bill Wendlingf2850d92009-01-10 12:56:31 +000082 return c0.getValue() != c1.getValue();
83 }
84};
85
86int Constructable::numConstructorCalls;
87int Constructable::numDestructorCalls;
88int Constructable::numAssignmentCalls;
89
90// Test fixture class
91class SmallVectorTest : public testing::Test {
92protected:
93 typedef SmallVector<Constructable, 4> VectorType;
Owen Anderson9cbd7af2011-07-06 22:36:59 +000094
Bill Wendlingf2850d92009-01-10 12:56:31 +000095 VectorType theVector;
96 VectorType otherVector;
Owen Anderson9cbd7af2011-07-06 22:36:59 +000097
Bill Wendlingf2850d92009-01-10 12:56:31 +000098 void SetUp() {
99 Constructable::reset();
100 }
101
102 void assertEmpty(VectorType & v) {
103 // Size tests
104 EXPECT_EQ(0u, v.size());
105 EXPECT_TRUE(v.empty());
106
107 // Iterator tests
108 EXPECT_TRUE(v.begin() == v.end());
109 }
110
111 // Assert that theVector contains the specified values, in order.
112 void assertValuesInOrder(VectorType & v, size_t size, ...) {
113 EXPECT_EQ(size, v.size());
Owen Anderson9cbd7af2011-07-06 22:36:59 +0000114
Bill Wendlingf2850d92009-01-10 12:56:31 +0000115 va_list ap;
116 va_start(ap, size);
117 for (size_t i = 0; i < size; ++i) {
118 int value = va_arg(ap, int);
119 EXPECT_EQ(value, v[i].getValue());
120 }
121
122 va_end(ap);
123 }
Owen Anderson9cbd7af2011-07-06 22:36:59 +0000124
Bill Wendlingf2850d92009-01-10 12:56:31 +0000125 // Generate a sequence of values to initialize the vector.
126 void makeSequence(VectorType & v, int start, int end) {
127 for (int i = start; i <= end; ++i) {
128 v.push_back(Constructable(i));
129 }
130 }
131};
132
133// New vector test.
134TEST_F(SmallVectorTest, EmptyVectorTest) {
135 SCOPED_TRACE("EmptyVectorTest");
136 assertEmpty(theVector);
137 EXPECT_TRUE(theVector.rbegin() == theVector.rend());
138 EXPECT_EQ(0, Constructable::getNumConstructorCalls());
139 EXPECT_EQ(0, Constructable::getNumDestructorCalls());
140}
141
142// Simple insertions and deletions.
143TEST_F(SmallVectorTest, PushPopTest) {
144 SCOPED_TRACE("PushPopTest");
145
146 // Push an element
147 theVector.push_back(Constructable(1));
148
149 // Size tests
150 assertValuesInOrder(theVector, 1u, 1);
151 EXPECT_FALSE(theVector.begin() == theVector.end());
152 EXPECT_FALSE(theVector.empty());
153
154 // Push another element
155 theVector.push_back(Constructable(2));
156 assertValuesInOrder(theVector, 2u, 1, 2);
157
Owen Anderson9cbd7af2011-07-06 22:36:59 +0000158 // Insert at beginning
159 theVector.insert(theVector.begin(), theVector[1]);
160 assertValuesInOrder(theVector, 3u, 2, 1, 2);
161
Bill Wendlingf2850d92009-01-10 12:56:31 +0000162 // Pop one element
163 theVector.pop_back();
Owen Anderson9cbd7af2011-07-06 22:36:59 +0000164 assertValuesInOrder(theVector, 2u, 2, 1);
Bill Wendlingf2850d92009-01-10 12:56:31 +0000165
Owen Anderson9cbd7af2011-07-06 22:36:59 +0000166 // Pop remaining elements
167 theVector.pop_back();
Bill Wendlingf2850d92009-01-10 12:56:31 +0000168 theVector.pop_back();
169 assertEmpty(theVector);
Owen Anderson9cbd7af2011-07-06 22:36:59 +0000170
Bill Wendlingf2850d92009-01-10 12:56:31 +0000171 // Check number of constructor calls. Should be 2 for each list element,
Owen Anderson9cbd7af2011-07-06 22:36:59 +0000172 // one for the argument to push_back, one for the argument to insert,
173 // and one for the list element itself.
174 EXPECT_EQ(5, Constructable::getNumConstructorCalls());
175 EXPECT_EQ(5, Constructable::getNumDestructorCalls());
Bill Wendlingf2850d92009-01-10 12:56:31 +0000176}
177
178// Clear test.
179TEST_F(SmallVectorTest, ClearTest) {
180 SCOPED_TRACE("ClearTest");
181
182 makeSequence(theVector, 1, 2);
183 theVector.clear();
184
185 assertEmpty(theVector);
186 EXPECT_EQ(4, Constructable::getNumConstructorCalls());
187 EXPECT_EQ(4, Constructable::getNumDestructorCalls());
188}
189
190// Resize smaller test.
191TEST_F(SmallVectorTest, ResizeShrinkTest) {
192 SCOPED_TRACE("ResizeShrinkTest");
193
194 makeSequence(theVector, 1, 3);
195 theVector.resize(1);
196
197 assertValuesInOrder(theVector, 1u, 1);
198 EXPECT_EQ(6, Constructable::getNumConstructorCalls());
199 EXPECT_EQ(5, Constructable::getNumDestructorCalls());
200}
201
202// Resize bigger test.
203TEST_F(SmallVectorTest, ResizeGrowTest) {
204 SCOPED_TRACE("ResizeGrowTest");
205
206 theVector.resize(2);
Owen Anderson9cbd7af2011-07-06 22:36:59 +0000207
Daniel Dunbar614be082009-07-12 19:45:34 +0000208 // The extra constructor/destructor calls come from the temporary object used
209 // to initialize the contents of the resized array (via copy construction).
Bill Wendlingf2850d92009-01-10 12:56:31 +0000210 EXPECT_EQ(3, Constructable::getNumConstructorCalls());
211 EXPECT_EQ(1, Constructable::getNumDestructorCalls());
212 EXPECT_EQ(2u, theVector.size());
213}
214
215// Resize with fill value.
216TEST_F(SmallVectorTest, ResizeFillTest) {
217 SCOPED_TRACE("ResizeFillTest");
218
219 theVector.resize(3, Constructable(77));
220 assertValuesInOrder(theVector, 3u, 77, 77, 77);
221}
222
223// Overflow past fixed size.
224TEST_F(SmallVectorTest, OverflowTest) {
225 SCOPED_TRACE("OverflowTest");
226
Daniel Dunbar614be082009-07-12 19:45:34 +0000227 // Push more elements than the fixed size.
Bill Wendlingf2850d92009-01-10 12:56:31 +0000228 makeSequence(theVector, 1, 10);
229
Daniel Dunbar614be082009-07-12 19:45:34 +0000230 // Test size and values.
Bill Wendlingf2850d92009-01-10 12:56:31 +0000231 EXPECT_EQ(10u, theVector.size());
232 for (int i = 0; i < 10; ++i) {
233 EXPECT_EQ(i+1, theVector[i].getValue());
234 }
Owen Anderson9cbd7af2011-07-06 22:36:59 +0000235
Daniel Dunbar614be082009-07-12 19:45:34 +0000236 // Now resize back to fixed size.
Bill Wendlingf2850d92009-01-10 12:56:31 +0000237 theVector.resize(1);
Owen Anderson9cbd7af2011-07-06 22:36:59 +0000238
Bill Wendlingf2850d92009-01-10 12:56:31 +0000239 assertValuesInOrder(theVector, 1u, 1);
240}
241
242// Iteration tests.
243TEST_F(SmallVectorTest, IterationTest) {
244 makeSequence(theVector, 1, 2);
245
246 // Forward Iteration
247 VectorType::iterator it = theVector.begin();
248 EXPECT_TRUE(*it == theVector.front());
249 EXPECT_TRUE(*it == theVector[0]);
250 EXPECT_EQ(1, it->getValue());
251 ++it;
252 EXPECT_TRUE(*it == theVector[1]);
253 EXPECT_TRUE(*it == theVector.back());
254 EXPECT_EQ(2, it->getValue());
255 ++it;
256 EXPECT_TRUE(it == theVector.end());
257 --it;
258 EXPECT_TRUE(*it == theVector[1]);
259 EXPECT_EQ(2, it->getValue());
260 --it;
261 EXPECT_TRUE(*it == theVector[0]);
262 EXPECT_EQ(1, it->getValue());
263
264 // Reverse Iteration
265 VectorType::reverse_iterator rit = theVector.rbegin();
266 EXPECT_TRUE(*rit == theVector[1]);
267 EXPECT_EQ(2, rit->getValue());
268 ++rit;
269 EXPECT_TRUE(*rit == theVector[0]);
270 EXPECT_EQ(1, rit->getValue());
271 ++rit;
272 EXPECT_TRUE(rit == theVector.rend());
273 --rit;
274 EXPECT_TRUE(*rit == theVector[0]);
275 EXPECT_EQ(1, rit->getValue());
276 --rit;
277 EXPECT_TRUE(*rit == theVector[1]);
278 EXPECT_EQ(2, rit->getValue());
279}
280
281// Swap test.
282TEST_F(SmallVectorTest, SwapTest) {
283 SCOPED_TRACE("SwapTest");
284
285 makeSequence(theVector, 1, 2);
286 std::swap(theVector, otherVector);
287
288 assertEmpty(theVector);
289 assertValuesInOrder(otherVector, 2u, 1, 2);
290}
291
292// Append test
293TEST_F(SmallVectorTest, AppendTest) {
294 SCOPED_TRACE("AppendTest");
295
296 makeSequence(otherVector, 2, 3);
297
298 theVector.push_back(Constructable(1));
299 theVector.append(otherVector.begin(), otherVector.end());
300
301 assertValuesInOrder(theVector, 3u, 1, 2, 3);
302}
303
304// Append repeated test
305TEST_F(SmallVectorTest, AppendRepeatedTest) {
306 SCOPED_TRACE("AppendRepeatedTest");
307
308 theVector.push_back(Constructable(1));
309 theVector.append(2, Constructable(77));
310 assertValuesInOrder(theVector, 3u, 1, 77, 77);
311}
312
313// Assign test
314TEST_F(SmallVectorTest, AssignTest) {
315 SCOPED_TRACE("AssignTest");
316
317 theVector.push_back(Constructable(1));
318 theVector.assign(2, Constructable(77));
319 assertValuesInOrder(theVector, 2u, 77, 77);
320}
321
322// Erase a single element
323TEST_F(SmallVectorTest, EraseTest) {
324 SCOPED_TRACE("EraseTest");
325
326 makeSequence(theVector, 1, 3);
327 theVector.erase(theVector.begin());
328 assertValuesInOrder(theVector, 2u, 2, 3);
329}
330
331// Erase a range of elements
332TEST_F(SmallVectorTest, EraseRangeTest) {
333 SCOPED_TRACE("EraseRangeTest");
334
335 makeSequence(theVector, 1, 3);
336 theVector.erase(theVector.begin(), theVector.begin() + 2);
337 assertValuesInOrder(theVector, 1u, 3);
338}
339
340// Insert a single element.
341TEST_F(SmallVectorTest, InsertTest) {
342 SCOPED_TRACE("InsertTest");
343
344 makeSequence(theVector, 1, 3);
345 theVector.insert(theVector.begin() + 1, Constructable(77));
346 assertValuesInOrder(theVector, 4u, 1, 77, 2, 3);
347}
348
349// Insert repeated elements.
350TEST_F(SmallVectorTest, InsertRepeatedTest) {
351 SCOPED_TRACE("InsertRepeatedTest");
352
Owen Anderson3f7c72a2009-04-23 00:15:26 +0000353 makeSequence(theVector, 10, 15);
354 theVector.insert(theVector.begin() + 1, 2, Constructable(16));
355 assertValuesInOrder(theVector, 8u, 10, 16, 16, 11, 12, 13, 14, 15);
Benjamin Kramer5f6c7cf2012-06-17 11:52:22 +0000356
357 EXPECT_EQ(theVector.end(),
358 theVector.insert(theVector.end(), 0, Constructable(42)));
Bill Wendlingf2850d92009-01-10 12:56:31 +0000359}
360
361// Insert range.
362TEST_F(SmallVectorTest, InsertRangeTest) {
363 SCOPED_TRACE("InsertRepeatedTest");
364
365 makeSequence(theVector, 1, 3);
366 theVector.insert(theVector.begin() + 1, 3, Constructable(77));
367 assertValuesInOrder(theVector, 6u, 1, 77, 77, 77, 2, 3);
Benjamin Kramer5f6c7cf2012-06-17 11:52:22 +0000368
369 EXPECT_EQ(theVector.end(), theVector.insert(theVector.end(),
370 theVector.begin(),
371 theVector.begin()));
Bill Wendlingf2850d92009-01-10 12:56:31 +0000372}
373
374// Comparison tests.
375TEST_F(SmallVectorTest, ComparisonTest) {
376 SCOPED_TRACE("ComparisonTest");
377
378 makeSequence(theVector, 1, 3);
379 makeSequence(otherVector, 1, 3);
Owen Anderson9cbd7af2011-07-06 22:36:59 +0000380
Bill Wendlingf2850d92009-01-10 12:56:31 +0000381 EXPECT_TRUE(theVector == otherVector);
382 EXPECT_FALSE(theVector != otherVector);
383
384 otherVector.clear();
385 makeSequence(otherVector, 2, 4);
Owen Anderson9cbd7af2011-07-06 22:36:59 +0000386
Bill Wendlingf2850d92009-01-10 12:56:31 +0000387 EXPECT_FALSE(theVector == otherVector);
388 EXPECT_TRUE(theVector != otherVector);
389}
390
391// Constant vector tests.
392TEST_F(SmallVectorTest, ConstVectorTest) {
Chris Lattnerdb125cf2011-07-18 04:54:35 +0000393 VectorType constVector;
Bill Wendlingf2850d92009-01-10 12:56:31 +0000394
395 EXPECT_EQ(0u, constVector.size());
396 EXPECT_TRUE(constVector.empty());
397 EXPECT_TRUE(constVector.begin() == constVector.end());
398}
399
Daniel Dunbarc2da6fb2009-08-19 17:48:28 +0000400// Direct array access.
401TEST_F(SmallVectorTest, DirectVectorTest) {
402 EXPECT_EQ(0u, theVector.size());
Dan Gohman5ffc72e2010-03-18 18:47:50 +0000403 EXPECT_LE(4u, theVector.capacity());
Daniel Dunbarc2da6fb2009-08-19 17:48:28 +0000404 EXPECT_EQ(0, Constructable::getNumConstructorCalls());
405 theVector.end()[0] = 1;
406 theVector.end()[1] = 2;
407 theVector.end()[2] = 3;
408 theVector.end()[3] = 4;
409 theVector.set_size(4);
410 EXPECT_EQ(4u, theVector.size());
411 EXPECT_EQ(4, Constructable::getNumConstructorCalls());
412 EXPECT_EQ(1, theVector[0].getValue());
413 EXPECT_EQ(2, theVector[1].getValue());
414 EXPECT_EQ(3, theVector[2].getValue());
415 EXPECT_EQ(4, theVector[3].getValue());
416}
417
Dan Gohmana7a33fd2010-03-26 18:53:37 +0000418TEST_F(SmallVectorTest, IteratorTest) {
419 std::list<int> L;
420 theVector.insert(theVector.end(), L.begin(), L.end());
421}
422
Benjamin Kramer3703baa2012-04-29 10:53:29 +0000423struct notassignable {
424 int &x;
425 notassignable(int &x) : x(x) {}
426};
427
428TEST_F(SmallVectorTest, NoAssignTest) {
429 int x = 0;
430 SmallVector<notassignable, 2> vec;
431 vec.push_back(notassignable(x));
432 x = 42;
433 EXPECT_EQ(42, vec.pop_back_val().x);
434}
435
Bill Wendlingf2850d92009-01-10 12:56:31 +0000436}