1 //===- llvm/unittest/ADT/SmallVectorTest.cpp ------------------------------===//
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 // SmallVector unit tests.
12 //===----------------------------------------------------------------------===//
14 #include "gtest/gtest.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/Support/Compiler.h"
24 /// A helper class that counts the total number of constructor and
28 static int numConstructorCalls
;
29 static int numDestructorCalls
;
30 static int numAssignmentCalls
;
35 Constructable() : value(0) {
36 ++numConstructorCalls
;
39 Constructable(int val
) : value(val
) {
40 ++numConstructorCalls
;
43 Constructable(const Constructable
& src
) {
45 ++numConstructorCalls
;
52 Constructable
& operator=(const Constructable
& src
) {
58 int getValue() const {
63 numConstructorCalls
= 0;
64 numDestructorCalls
= 0;
65 numAssignmentCalls
= 0;
68 static int getNumConstructorCalls() {
69 return numConstructorCalls
;
72 static int getNumDestructorCalls() {
73 return numDestructorCalls
;
76 friend bool operator==(const Constructable
& c0
, const Constructable
& c1
) {
77 return c0
.getValue() == c1
.getValue();
80 friend bool LLVM_ATTRIBUTE_UNUSED
81 operator!=(const Constructable
& c0
, const Constructable
& c1
) {
82 return c0
.getValue() != c1
.getValue();
86 int Constructable::numConstructorCalls
;
87 int Constructable::numDestructorCalls
;
88 int Constructable::numAssignmentCalls
;
91 class SmallVectorTest
: public testing::Test
{
93 typedef SmallVector
<Constructable
, 4> VectorType
;
96 VectorType otherVector
;
99 Constructable::reset();
102 void assertEmpty(VectorType
& v
) {
104 EXPECT_EQ(0u, v
.size());
105 EXPECT_TRUE(v
.empty());
108 EXPECT_TRUE(v
.begin() == v
.end());
111 // Assert that theVector contains the specified values, in order.
112 void assertValuesInOrder(VectorType
& v
, size_t size
, ...) {
113 EXPECT_EQ(size
, v
.size());
117 for (size_t i
= 0; i
< size
; ++i
) {
118 int value
= va_arg(ap
, int);
119 EXPECT_EQ(value
, v
[i
].getValue());
125 // 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
));
134 TEST_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());
142 // Simple insertions and deletions.
143 TEST_F(SmallVectorTest
, PushPopTest
) {
144 SCOPED_TRACE("PushPopTest");
147 theVector
.push_back(Constructable(1));
150 assertValuesInOrder(theVector
, 1u, 1);
151 EXPECT_FALSE(theVector
.begin() == theVector
.end());
152 EXPECT_FALSE(theVector
.empty());
154 // Push another element
155 theVector
.push_back(Constructable(2));
156 assertValuesInOrder(theVector
, 2u, 1, 2);
159 theVector
.pop_back();
160 assertValuesInOrder(theVector
, 1u, 1);
162 // Pop another element
163 theVector
.pop_back();
164 assertEmpty(theVector
);
166 // Check number of constructor calls. Should be 2 for each list element,
167 // one for the argument to push_back, and one for the list element itself.
168 EXPECT_EQ(4, Constructable::getNumConstructorCalls());
169 EXPECT_EQ(4, Constructable::getNumDestructorCalls());
173 TEST_F(SmallVectorTest
, ClearTest
) {
174 SCOPED_TRACE("ClearTest");
176 makeSequence(theVector
, 1, 2);
179 assertEmpty(theVector
);
180 EXPECT_EQ(4, Constructable::getNumConstructorCalls());
181 EXPECT_EQ(4, Constructable::getNumDestructorCalls());
184 // Resize smaller test.
185 TEST_F(SmallVectorTest
, ResizeShrinkTest
) {
186 SCOPED_TRACE("ResizeShrinkTest");
188 makeSequence(theVector
, 1, 3);
191 assertValuesInOrder(theVector
, 1u, 1);
192 EXPECT_EQ(6, Constructable::getNumConstructorCalls());
193 EXPECT_EQ(5, Constructable::getNumDestructorCalls());
196 // Resize bigger test.
197 TEST_F(SmallVectorTest
, ResizeGrowTest
) {
198 SCOPED_TRACE("ResizeGrowTest");
202 // The extra constructor/destructor calls come from the temporary object used
203 // to initialize the contents of the resized array (via copy construction).
204 EXPECT_EQ(3, Constructable::getNumConstructorCalls());
205 EXPECT_EQ(1, Constructable::getNumDestructorCalls());
206 EXPECT_EQ(2u, theVector
.size());
209 // Resize with fill value.
210 TEST_F(SmallVectorTest
, ResizeFillTest
) {
211 SCOPED_TRACE("ResizeFillTest");
213 theVector
.resize(3, Constructable(77));
214 assertValuesInOrder(theVector
, 3u, 77, 77, 77);
217 // Overflow past fixed size.
218 TEST_F(SmallVectorTest
, OverflowTest
) {
219 SCOPED_TRACE("OverflowTest");
221 // Push more elements than the fixed size.
222 makeSequence(theVector
, 1, 10);
224 // Test size and values.
225 EXPECT_EQ(10u, theVector
.size());
226 for (int i
= 0; i
< 10; ++i
) {
227 EXPECT_EQ(i
+1, theVector
[i
].getValue());
230 // Now resize back to fixed size.
233 assertValuesInOrder(theVector
, 1u, 1);
237 TEST_F(SmallVectorTest
, IterationTest
) {
238 makeSequence(theVector
, 1, 2);
241 VectorType::iterator it
= theVector
.begin();
242 EXPECT_TRUE(*it
== theVector
.front());
243 EXPECT_TRUE(*it
== theVector
[0]);
244 EXPECT_EQ(1, it
->getValue());
246 EXPECT_TRUE(*it
== theVector
[1]);
247 EXPECT_TRUE(*it
== theVector
.back());
248 EXPECT_EQ(2, it
->getValue());
250 EXPECT_TRUE(it
== theVector
.end());
252 EXPECT_TRUE(*it
== theVector
[1]);
253 EXPECT_EQ(2, it
->getValue());
255 EXPECT_TRUE(*it
== theVector
[0]);
256 EXPECT_EQ(1, it
->getValue());
259 VectorType::reverse_iterator rit
= theVector
.rbegin();
260 EXPECT_TRUE(*rit
== theVector
[1]);
261 EXPECT_EQ(2, rit
->getValue());
263 EXPECT_TRUE(*rit
== theVector
[0]);
264 EXPECT_EQ(1, rit
->getValue());
266 EXPECT_TRUE(rit
== theVector
.rend());
268 EXPECT_TRUE(*rit
== theVector
[0]);
269 EXPECT_EQ(1, rit
->getValue());
271 EXPECT_TRUE(*rit
== theVector
[1]);
272 EXPECT_EQ(2, rit
->getValue());
276 TEST_F(SmallVectorTest
, SwapTest
) {
277 SCOPED_TRACE("SwapTest");
279 makeSequence(theVector
, 1, 2);
280 std::swap(theVector
, otherVector
);
282 assertEmpty(theVector
);
283 assertValuesInOrder(otherVector
, 2u, 1, 2);
287 TEST_F(SmallVectorTest
, AppendTest
) {
288 SCOPED_TRACE("AppendTest");
290 makeSequence(otherVector
, 2, 3);
292 theVector
.push_back(Constructable(1));
293 theVector
.append(otherVector
.begin(), otherVector
.end());
295 assertValuesInOrder(theVector
, 3u, 1, 2, 3);
298 // Append repeated test
299 TEST_F(SmallVectorTest
, AppendRepeatedTest
) {
300 SCOPED_TRACE("AppendRepeatedTest");
302 theVector
.push_back(Constructable(1));
303 theVector
.append(2, Constructable(77));
304 assertValuesInOrder(theVector
, 3u, 1, 77, 77);
308 TEST_F(SmallVectorTest
, AssignTest
) {
309 SCOPED_TRACE("AssignTest");
311 theVector
.push_back(Constructable(1));
312 theVector
.assign(2, Constructable(77));
313 assertValuesInOrder(theVector
, 2u, 77, 77);
316 // Erase a single element
317 TEST_F(SmallVectorTest
, EraseTest
) {
318 SCOPED_TRACE("EraseTest");
320 makeSequence(theVector
, 1, 3);
321 theVector
.erase(theVector
.begin());
322 assertValuesInOrder(theVector
, 2u, 2, 3);
325 // Erase a range of elements
326 TEST_F(SmallVectorTest
, EraseRangeTest
) {
327 SCOPED_TRACE("EraseRangeTest");
329 makeSequence(theVector
, 1, 3);
330 theVector
.erase(theVector
.begin(), theVector
.begin() + 2);
331 assertValuesInOrder(theVector
, 1u, 3);
334 // Insert a single element.
335 TEST_F(SmallVectorTest
, InsertTest
) {
336 SCOPED_TRACE("InsertTest");
338 makeSequence(theVector
, 1, 3);
339 theVector
.insert(theVector
.begin() + 1, Constructable(77));
340 assertValuesInOrder(theVector
, 4u, 1, 77, 2, 3);
343 // Insert repeated elements.
344 TEST_F(SmallVectorTest
, InsertRepeatedTest
) {
345 SCOPED_TRACE("InsertRepeatedTest");
347 makeSequence(theVector
, 10, 15);
348 theVector
.insert(theVector
.begin() + 1, 2, Constructable(16));
349 assertValuesInOrder(theVector
, 8u, 10, 16, 16, 11, 12, 13, 14, 15);
353 TEST_F(SmallVectorTest
, InsertRangeTest
) {
354 SCOPED_TRACE("InsertRepeatedTest");
356 makeSequence(theVector
, 1, 3);
357 theVector
.insert(theVector
.begin() + 1, 3, Constructable(77));
358 assertValuesInOrder(theVector
, 6u, 1, 77, 77, 77, 2, 3);
362 TEST_F(SmallVectorTest
, ComparisonTest
) {
363 SCOPED_TRACE("ComparisonTest");
365 makeSequence(theVector
, 1, 3);
366 makeSequence(otherVector
, 1, 3);
368 EXPECT_TRUE(theVector
== otherVector
);
369 EXPECT_FALSE(theVector
!= otherVector
);
372 makeSequence(otherVector
, 2, 4);
374 EXPECT_FALSE(theVector
== otherVector
);
375 EXPECT_TRUE(theVector
!= otherVector
);
378 // Constant vector tests.
379 TEST_F(SmallVectorTest
, ConstVectorTest
) {
380 const VectorType constVector
;
382 EXPECT_EQ(0u, constVector
.size());
383 EXPECT_TRUE(constVector
.empty());
384 EXPECT_TRUE(constVector
.begin() == constVector
.end());
387 // Direct array access.
388 TEST_F(SmallVectorTest
, DirectVectorTest
) {
389 EXPECT_EQ(0u, theVector
.size());
390 EXPECT_LE(4u, theVector
.capacity());
391 EXPECT_EQ(0, Constructable::getNumConstructorCalls());
392 theVector
.end()[0] = 1;
393 theVector
.end()[1] = 2;
394 theVector
.end()[2] = 3;
395 theVector
.end()[3] = 4;
396 theVector
.set_size(4);
397 EXPECT_EQ(4u, theVector
.size());
398 EXPECT_EQ(4, Constructable::getNumConstructorCalls());
399 EXPECT_EQ(1, theVector
[0].getValue());
400 EXPECT_EQ(2, theVector
[1].getValue());
401 EXPECT_EQ(3, theVector
[2].getValue());
402 EXPECT_EQ(4, theVector
[3].getValue());
405 TEST_F(SmallVectorTest
, IteratorTest
) {
407 theVector
.insert(theVector
.end(), L
.begin(), L
.end());