blob: 079cc012b2e8006507e6fb2689c7433c836983a6 [file] [log] [blame]
Bill Wendling8d069ef2009-01-11 01:25:51 +00001//===- llvm/unittest/ADT/SmallVectorTest.cpp ------------------------------===//
Bill Wendlingc56c37f2009-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
Bill Wendlingc56c37f2009-01-10 12:56:31 +000014#include "llvm/ADT/SmallVector.h"
Bill Wendlingbfba2f12010-08-19 18:52:02 +000015#include "llvm/Support/Compiler.h"
Chandler Carruth130cec22012-12-04 10:23:08 +000016#include "gtest/gtest.h"
Dan Gohman42e77df2010-03-26 18:53:37 +000017#include <list>
Chandler Carruth130cec22012-12-04 10:23:08 +000018#include <stdarg.h>
Bill Wendlingc56c37f2009-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;
David Blaikieae8a9322014-06-08 19:12:28 +000029 static int numMoveConstructorCalls;
30 static int numCopyConstructorCalls;
Bill Wendlingc56c37f2009-01-10 12:56:31 +000031 static int numDestructorCalls;
32 static int numAssignmentCalls;
David Blaikieae8a9322014-06-08 19:12:28 +000033 static int numMoveAssignmentCalls;
34 static int numCopyAssignmentCalls;
Bill Wendlingc56c37f2009-01-10 12:56:31 +000035
Douglas Gregor8451cdff2014-04-30 15:49:06 +000036 bool constructed;
Bill Wendlingc56c37f2009-01-10 12:56:31 +000037 int value;
38
39public:
Douglas Gregor8451cdff2014-04-30 15:49:06 +000040 Constructable() : constructed(true), value(0) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +000041 ++numConstructorCalls;
42 }
Owen Anderson145a2602011-07-06 22:36:59 +000043
Douglas Gregor8451cdff2014-04-30 15:49:06 +000044 Constructable(int val) : constructed(true), value(val) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +000045 ++numConstructorCalls;
46 }
Owen Anderson145a2602011-07-06 22:36:59 +000047
Douglas Gregor8451cdff2014-04-30 15:49:06 +000048 Constructable(const Constructable & src) : constructed(true) {
49 value = src.value;
50 ++numConstructorCalls;
David Blaikieae8a9322014-06-08 19:12:28 +000051 ++numCopyConstructorCalls;
Douglas Gregor8451cdff2014-04-30 15:49:06 +000052 }
53
54 Constructable(Constructable && src) : constructed(true) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +000055 value = src.value;
56 ++numConstructorCalls;
David Blaikieae8a9322014-06-08 19:12:28 +000057 ++numMoveConstructorCalls;
Bill Wendlingc56c37f2009-01-10 12:56:31 +000058 }
Owen Anderson145a2602011-07-06 22:36:59 +000059
Bill Wendlingc56c37f2009-01-10 12:56:31 +000060 ~Constructable() {
Douglas Gregor8451cdff2014-04-30 15:49:06 +000061 EXPECT_TRUE(constructed);
Bill Wendlingc56c37f2009-01-10 12:56:31 +000062 ++numDestructorCalls;
Douglas Gregor8451cdff2014-04-30 15:49:06 +000063 constructed = false;
Bill Wendlingc56c37f2009-01-10 12:56:31 +000064 }
Owen Anderson145a2602011-07-06 22:36:59 +000065
Bill Wendlingc56c37f2009-01-10 12:56:31 +000066 Constructable & operator=(const Constructable & src) {
Douglas Gregor8451cdff2014-04-30 15:49:06 +000067 EXPECT_TRUE(constructed);
68 value = src.value;
69 ++numAssignmentCalls;
David Blaikieae8a9322014-06-08 19:12:28 +000070 ++numCopyAssignmentCalls;
Douglas Gregor8451cdff2014-04-30 15:49:06 +000071 return *this;
72 }
73
74 Constructable & operator=(Constructable && src) {
75 EXPECT_TRUE(constructed);
Bill Wendlingc56c37f2009-01-10 12:56:31 +000076 value = src.value;
77 ++numAssignmentCalls;
David Blaikieae8a9322014-06-08 19:12:28 +000078 ++numMoveAssignmentCalls;
Bill Wendlingc56c37f2009-01-10 12:56:31 +000079 return *this;
80 }
Owen Anderson145a2602011-07-06 22:36:59 +000081
Bill Wendlingc56c37f2009-01-10 12:56:31 +000082 int getValue() const {
83 return abs(value);
84 }
85
86 static void reset() {
87 numConstructorCalls = 0;
David Blaikieae8a9322014-06-08 19:12:28 +000088 numMoveConstructorCalls = 0;
89 numCopyConstructorCalls = 0;
Bill Wendlingc56c37f2009-01-10 12:56:31 +000090 numDestructorCalls = 0;
91 numAssignmentCalls = 0;
David Blaikieae8a9322014-06-08 19:12:28 +000092 numMoveAssignmentCalls = 0;
93 numCopyAssignmentCalls = 0;
Bill Wendlingc56c37f2009-01-10 12:56:31 +000094 }
Owen Anderson145a2602011-07-06 22:36:59 +000095
Bill Wendlingc56c37f2009-01-10 12:56:31 +000096 static int getNumConstructorCalls() {
97 return numConstructorCalls;
98 }
99
David Blaikieae8a9322014-06-08 19:12:28 +0000100 static int getNumMoveConstructorCalls() {
101 return numMoveConstructorCalls;
102 }
103
104 static int getNumCopyConstructorCalls() {
105 return numCopyConstructorCalls;
106 }
107
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000108 static int getNumDestructorCalls() {
109 return numDestructorCalls;
110 }
111
David Blaikieae8a9322014-06-08 19:12:28 +0000112 static int getNumAssignmentCalls() {
113 return numAssignmentCalls;
114 }
115
116 static int getNumMoveAssignmentCalls() {
117 return numMoveAssignmentCalls;
118 }
119
120 static int getNumCopyAssignmentCalls() {
121 return numCopyAssignmentCalls;
122 }
123
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000124 friend bool operator==(const Constructable & c0, const Constructable & c1) {
125 return c0.getValue() == c1.getValue();
126 }
127
Chandler Carruth88c54b82010-10-23 08:10:43 +0000128 friend bool LLVM_ATTRIBUTE_UNUSED
Bill Wendlingbfba2f12010-08-19 18:52:02 +0000129 operator!=(const Constructable & c0, const Constructable & c1) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000130 return c0.getValue() != c1.getValue();
131 }
132};
133
134int Constructable::numConstructorCalls;
David Blaikieae8a9322014-06-08 19:12:28 +0000135int Constructable::numCopyConstructorCalls;
136int Constructable::numMoveConstructorCalls;
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000137int Constructable::numDestructorCalls;
138int Constructable::numAssignmentCalls;
David Blaikieae8a9322014-06-08 19:12:28 +0000139int Constructable::numCopyAssignmentCalls;
140int Constructable::numMoveAssignmentCalls;
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000141
142// Test fixture class
Chandler Carruth0b012612012-07-30 22:17:52 +0000143template <typename VectorT>
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000144class SmallVectorTest : public testing::Test {
145protected:
Chandler Carruth0b012612012-07-30 22:17:52 +0000146 VectorT theVector;
147 VectorT otherVector;
Owen Anderson145a2602011-07-06 22:36:59 +0000148
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000149 void SetUp() {
150 Constructable::reset();
151 }
152
Chandler Carruth0b012612012-07-30 22:17:52 +0000153 void assertEmpty(VectorT & v) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000154 // Size tests
155 EXPECT_EQ(0u, v.size());
156 EXPECT_TRUE(v.empty());
157
158 // Iterator tests
159 EXPECT_TRUE(v.begin() == v.end());
160 }
161
162 // Assert that theVector contains the specified values, in order.
Chandler Carruth0b012612012-07-30 22:17:52 +0000163 void assertValuesInOrder(VectorT & v, size_t size, ...) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000164 EXPECT_EQ(size, v.size());
Owen Anderson145a2602011-07-06 22:36:59 +0000165
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000166 va_list ap;
167 va_start(ap, size);
168 for (size_t i = 0; i < size; ++i) {
169 int value = va_arg(ap, int);
170 EXPECT_EQ(value, v[i].getValue());
171 }
172
173 va_end(ap);
174 }
Owen Anderson145a2602011-07-06 22:36:59 +0000175
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000176 // Generate a sequence of values to initialize the vector.
Chandler Carruth0b012612012-07-30 22:17:52 +0000177 void makeSequence(VectorT & v, int start, int end) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000178 for (int i = start; i <= end; ++i) {
179 v.push_back(Constructable(i));
180 }
181 }
182};
183
Chandler Carruth0b012612012-07-30 22:17:52 +0000184typedef ::testing::Types<SmallVector<Constructable, 0>,
185 SmallVector<Constructable, 1>,
186 SmallVector<Constructable, 2>,
187 SmallVector<Constructable, 4>
188 > SmallVectorTestTypes;
189TYPED_TEST_CASE(SmallVectorTest, SmallVectorTestTypes);
190
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000191// New vector test.
Chandler Carruth0b012612012-07-30 22:17:52 +0000192TYPED_TEST(SmallVectorTest, EmptyVectorTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000193 SCOPED_TRACE("EmptyVectorTest");
Chandler Carruth0b012612012-07-30 22:17:52 +0000194 this->assertEmpty(this->theVector);
195 EXPECT_TRUE(this->theVector.rbegin() == this->theVector.rend());
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000196 EXPECT_EQ(0, Constructable::getNumConstructorCalls());
197 EXPECT_EQ(0, Constructable::getNumDestructorCalls());
198}
199
200// Simple insertions and deletions.
Chandler Carruth0b012612012-07-30 22:17:52 +0000201TYPED_TEST(SmallVectorTest, PushPopTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000202 SCOPED_TRACE("PushPopTest");
203
Chandler Carruth0b012612012-07-30 22:17:52 +0000204 // Track whether the vector will potentially have to grow.
205 bool RequiresGrowth = this->theVector.capacity() < 3;
206
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000207 // Push an element
Chandler Carruth0b012612012-07-30 22:17:52 +0000208 this->theVector.push_back(Constructable(1));
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000209
210 // Size tests
Chandler Carruth0b012612012-07-30 22:17:52 +0000211 this->assertValuesInOrder(this->theVector, 1u, 1);
212 EXPECT_FALSE(this->theVector.begin() == this->theVector.end());
213 EXPECT_FALSE(this->theVector.empty());
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000214
215 // Push another element
Chandler Carruth0b012612012-07-30 22:17:52 +0000216 this->theVector.push_back(Constructable(2));
217 this->assertValuesInOrder(this->theVector, 2u, 1, 2);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000218
Owen Anderson145a2602011-07-06 22:36:59 +0000219 // Insert at beginning
Chandler Carruth0b012612012-07-30 22:17:52 +0000220 this->theVector.insert(this->theVector.begin(), this->theVector[1]);
221 this->assertValuesInOrder(this->theVector, 3u, 2, 1, 2);
Owen Anderson145a2602011-07-06 22:36:59 +0000222
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000223 // Pop one element
Chandler Carruth0b012612012-07-30 22:17:52 +0000224 this->theVector.pop_back();
225 this->assertValuesInOrder(this->theVector, 2u, 2, 1);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000226
Owen Anderson145a2602011-07-06 22:36:59 +0000227 // Pop remaining elements
Chandler Carruth0b012612012-07-30 22:17:52 +0000228 this->theVector.pop_back();
229 this->theVector.pop_back();
230 this->assertEmpty(this->theVector);
Owen Anderson145a2602011-07-06 22:36:59 +0000231
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000232 // Check number of constructor calls. Should be 2 for each list element,
Owen Anderson145a2602011-07-06 22:36:59 +0000233 // one for the argument to push_back, one for the argument to insert,
234 // and one for the list element itself.
Chandler Carruth0b012612012-07-30 22:17:52 +0000235 if (!RequiresGrowth) {
236 EXPECT_EQ(5, Constructable::getNumConstructorCalls());
237 EXPECT_EQ(5, Constructable::getNumDestructorCalls());
238 } else {
239 // If we had to grow the vector, these only have a lower bound, but should
240 // always be equal.
241 EXPECT_LE(5, Constructable::getNumConstructorCalls());
242 EXPECT_EQ(Constructable::getNumConstructorCalls(),
243 Constructable::getNumDestructorCalls());
244 }
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000245}
246
247// Clear test.
Chandler Carruth0b012612012-07-30 22:17:52 +0000248TYPED_TEST(SmallVectorTest, ClearTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000249 SCOPED_TRACE("ClearTest");
250
Chandler Carruth0b012612012-07-30 22:17:52 +0000251 this->theVector.reserve(2);
252 this->makeSequence(this->theVector, 1, 2);
253 this->theVector.clear();
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000254
Chandler Carruth0b012612012-07-30 22:17:52 +0000255 this->assertEmpty(this->theVector);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000256 EXPECT_EQ(4, Constructable::getNumConstructorCalls());
257 EXPECT_EQ(4, Constructable::getNumDestructorCalls());
258}
259
260// Resize smaller test.
Chandler Carruth0b012612012-07-30 22:17:52 +0000261TYPED_TEST(SmallVectorTest, ResizeShrinkTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000262 SCOPED_TRACE("ResizeShrinkTest");
263
Chandler Carruth0b012612012-07-30 22:17:52 +0000264 this->theVector.reserve(3);
265 this->makeSequence(this->theVector, 1, 3);
266 this->theVector.resize(1);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000267
Chandler Carruth0b012612012-07-30 22:17:52 +0000268 this->assertValuesInOrder(this->theVector, 1u, 1);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000269 EXPECT_EQ(6, Constructable::getNumConstructorCalls());
270 EXPECT_EQ(5, Constructable::getNumDestructorCalls());
271}
272
273// Resize bigger test.
Chandler Carruth0b012612012-07-30 22:17:52 +0000274TYPED_TEST(SmallVectorTest, ResizeGrowTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000275 SCOPED_TRACE("ResizeGrowTest");
276
Chandler Carruth0b012612012-07-30 22:17:52 +0000277 this->theVector.resize(2);
Owen Anderson145a2602011-07-06 22:36:59 +0000278
Daniel Dunbar6d6023b2009-07-12 19:45:34 +0000279 // The extra constructor/destructor calls come from the temporary object used
280 // to initialize the contents of the resized array (via copy construction).
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000281 EXPECT_EQ(3, Constructable::getNumConstructorCalls());
282 EXPECT_EQ(1, Constructable::getNumDestructorCalls());
Chandler Carruth0b012612012-07-30 22:17:52 +0000283 EXPECT_EQ(2u, this->theVector.size());
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000284}
285
286// Resize with fill value.
Chandler Carruth0b012612012-07-30 22:17:52 +0000287TYPED_TEST(SmallVectorTest, ResizeFillTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000288 SCOPED_TRACE("ResizeFillTest");
289
Chandler Carruth0b012612012-07-30 22:17:52 +0000290 this->theVector.resize(3, Constructable(77));
291 this->assertValuesInOrder(this->theVector, 3u, 77, 77, 77);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000292}
293
294// Overflow past fixed size.
Chandler Carruth0b012612012-07-30 22:17:52 +0000295TYPED_TEST(SmallVectorTest, OverflowTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000296 SCOPED_TRACE("OverflowTest");
297
Daniel Dunbar6d6023b2009-07-12 19:45:34 +0000298 // Push more elements than the fixed size.
Chandler Carruth0b012612012-07-30 22:17:52 +0000299 this->makeSequence(this->theVector, 1, 10);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000300
Daniel Dunbar6d6023b2009-07-12 19:45:34 +0000301 // Test size and values.
Chandler Carruth0b012612012-07-30 22:17:52 +0000302 EXPECT_EQ(10u, this->theVector.size());
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000303 for (int i = 0; i < 10; ++i) {
Chandler Carruth0b012612012-07-30 22:17:52 +0000304 EXPECT_EQ(i+1, this->theVector[i].getValue());
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000305 }
Owen Anderson145a2602011-07-06 22:36:59 +0000306
Daniel Dunbar6d6023b2009-07-12 19:45:34 +0000307 // Now resize back to fixed size.
Chandler Carruth0b012612012-07-30 22:17:52 +0000308 this->theVector.resize(1);
Owen Anderson145a2602011-07-06 22:36:59 +0000309
Chandler Carruth0b012612012-07-30 22:17:52 +0000310 this->assertValuesInOrder(this->theVector, 1u, 1);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000311}
312
313// Iteration tests.
Chandler Carruth0b012612012-07-30 22:17:52 +0000314TYPED_TEST(SmallVectorTest, IterationTest) {
315 this->makeSequence(this->theVector, 1, 2);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000316
317 // Forward Iteration
Chandler Carruth0b012612012-07-30 22:17:52 +0000318 typename TypeParam::iterator it = this->theVector.begin();
319 EXPECT_TRUE(*it == this->theVector.front());
320 EXPECT_TRUE(*it == this->theVector[0]);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000321 EXPECT_EQ(1, it->getValue());
322 ++it;
Chandler Carruth0b012612012-07-30 22:17:52 +0000323 EXPECT_TRUE(*it == this->theVector[1]);
324 EXPECT_TRUE(*it == this->theVector.back());
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000325 EXPECT_EQ(2, it->getValue());
326 ++it;
Chandler Carruth0b012612012-07-30 22:17:52 +0000327 EXPECT_TRUE(it == this->theVector.end());
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000328 --it;
Chandler Carruth0b012612012-07-30 22:17:52 +0000329 EXPECT_TRUE(*it == this->theVector[1]);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000330 EXPECT_EQ(2, it->getValue());
331 --it;
Chandler Carruth0b012612012-07-30 22:17:52 +0000332 EXPECT_TRUE(*it == this->theVector[0]);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000333 EXPECT_EQ(1, it->getValue());
334
335 // Reverse Iteration
Chandler Carruth0b012612012-07-30 22:17:52 +0000336 typename TypeParam::reverse_iterator rit = this->theVector.rbegin();
337 EXPECT_TRUE(*rit == this->theVector[1]);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000338 EXPECT_EQ(2, rit->getValue());
339 ++rit;
Chandler Carruth0b012612012-07-30 22:17:52 +0000340 EXPECT_TRUE(*rit == this->theVector[0]);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000341 EXPECT_EQ(1, rit->getValue());
342 ++rit;
Chandler Carruth0b012612012-07-30 22:17:52 +0000343 EXPECT_TRUE(rit == this->theVector.rend());
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000344 --rit;
Chandler Carruth0b012612012-07-30 22:17:52 +0000345 EXPECT_TRUE(*rit == this->theVector[0]);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000346 EXPECT_EQ(1, rit->getValue());
347 --rit;
Chandler Carruth0b012612012-07-30 22:17:52 +0000348 EXPECT_TRUE(*rit == this->theVector[1]);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000349 EXPECT_EQ(2, rit->getValue());
350}
351
352// Swap test.
Chandler Carruth0b012612012-07-30 22:17:52 +0000353TYPED_TEST(SmallVectorTest, SwapTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000354 SCOPED_TRACE("SwapTest");
355
Chandler Carruth0b012612012-07-30 22:17:52 +0000356 this->makeSequence(this->theVector, 1, 2);
357 std::swap(this->theVector, this->otherVector);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000358
Chandler Carruth0b012612012-07-30 22:17:52 +0000359 this->assertEmpty(this->theVector);
360 this->assertValuesInOrder(this->otherVector, 2u, 1, 2);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000361}
362
363// Append test
Chandler Carruth0b012612012-07-30 22:17:52 +0000364TYPED_TEST(SmallVectorTest, AppendTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000365 SCOPED_TRACE("AppendTest");
366
Chandler Carruth0b012612012-07-30 22:17:52 +0000367 this->makeSequence(this->otherVector, 2, 3);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000368
Chandler Carruth0b012612012-07-30 22:17:52 +0000369 this->theVector.push_back(Constructable(1));
370 this->theVector.append(this->otherVector.begin(), this->otherVector.end());
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000371
Chandler Carruth0b012612012-07-30 22:17:52 +0000372 this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000373}
374
375// Append repeated test
Chandler Carruth0b012612012-07-30 22:17:52 +0000376TYPED_TEST(SmallVectorTest, AppendRepeatedTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000377 SCOPED_TRACE("AppendRepeatedTest");
378
Chandler Carruth0b012612012-07-30 22:17:52 +0000379 this->theVector.push_back(Constructable(1));
380 this->theVector.append(2, Constructable(77));
381 this->assertValuesInOrder(this->theVector, 3u, 1, 77, 77);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000382}
383
384// Assign test
Chandler Carruth0b012612012-07-30 22:17:52 +0000385TYPED_TEST(SmallVectorTest, AssignTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000386 SCOPED_TRACE("AssignTest");
387
Chandler Carruth0b012612012-07-30 22:17:52 +0000388 this->theVector.push_back(Constructable(1));
389 this->theVector.assign(2, Constructable(77));
390 this->assertValuesInOrder(this->theVector, 2u, 77, 77);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000391}
392
Douglas Gregor8451cdff2014-04-30 15:49:06 +0000393// Move-assign test
394TYPED_TEST(SmallVectorTest, MoveAssignTest) {
395 SCOPED_TRACE("MoveAssignTest");
396
397 // Set up our vector with a single element, but enough capacity for 4.
398 this->theVector.reserve(4);
399 this->theVector.push_back(Constructable(1));
400
401 // Set up the other vector with 2 elements.
402 this->otherVector.push_back(Constructable(2));
403 this->otherVector.push_back(Constructable(3));
404
405 // Move-assign from the other vector.
406 this->theVector = std::move(this->otherVector);
407
408 // Make sure we have the right result.
409 this->assertValuesInOrder(this->theVector, 2u, 2, 3);
410
411 // Make sure the # of constructor/destructor calls line up. There
412 // are two live objects after clearing the other vector.
413 this->otherVector.clear();
414 EXPECT_EQ(Constructable::getNumConstructorCalls()-2,
415 Constructable::getNumDestructorCalls());
416
417 // There shouldn't be any live objects any more.
418 this->theVector.clear();
419 EXPECT_EQ(Constructable::getNumConstructorCalls(),
420 Constructable::getNumDestructorCalls());
421}
422
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000423// Erase a single element
Chandler Carruth0b012612012-07-30 22:17:52 +0000424TYPED_TEST(SmallVectorTest, EraseTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000425 SCOPED_TRACE("EraseTest");
426
Chandler Carruth0b012612012-07-30 22:17:52 +0000427 this->makeSequence(this->theVector, 1, 3);
428 this->theVector.erase(this->theVector.begin());
429 this->assertValuesInOrder(this->theVector, 2u, 2, 3);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000430}
431
432// Erase a range of elements
Chandler Carruth0b012612012-07-30 22:17:52 +0000433TYPED_TEST(SmallVectorTest, EraseRangeTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000434 SCOPED_TRACE("EraseRangeTest");
435
Chandler Carruth0b012612012-07-30 22:17:52 +0000436 this->makeSequence(this->theVector, 1, 3);
437 this->theVector.erase(this->theVector.begin(), this->theVector.begin() + 2);
438 this->assertValuesInOrder(this->theVector, 1u, 3);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000439}
440
441// Insert a single element.
Chandler Carruth0b012612012-07-30 22:17:52 +0000442TYPED_TEST(SmallVectorTest, InsertTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000443 SCOPED_TRACE("InsertTest");
444
Chandler Carruth0b012612012-07-30 22:17:52 +0000445 this->makeSequence(this->theVector, 1, 3);
446 typename TypeParam::iterator I =
447 this->theVector.insert(this->theVector.begin() + 1, Constructable(77));
448 EXPECT_EQ(this->theVector.begin() + 1, I);
449 this->assertValuesInOrder(this->theVector, 4u, 1, 77, 2, 3);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000450}
451
David Blaikie40d4e342014-06-08 16:55:13 +0000452// Insert a copy of a single element.
453TYPED_TEST(SmallVectorTest, InsertCopy) {
454 SCOPED_TRACE("InsertTest");
455
456 this->makeSequence(this->theVector, 1, 3);
457 Constructable C(77);
458 typename TypeParam::iterator I =
459 this->theVector.insert(this->theVector.begin() + 1, C);
460 EXPECT_EQ(this->theVector.begin() + 1, I);
461 this->assertValuesInOrder(this->theVector, 4u, 1, 77, 2, 3);
462}
463
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000464// Insert repeated elements.
Chandler Carruth0b012612012-07-30 22:17:52 +0000465TYPED_TEST(SmallVectorTest, InsertRepeatedTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000466 SCOPED_TRACE("InsertRepeatedTest");
467
Chandler Carruth0b012612012-07-30 22:17:52 +0000468 this->makeSequence(this->theVector, 10, 15);
David Blaikieae8a9322014-06-08 19:12:28 +0000469 Constructable::reset();
Chandler Carruth0b012612012-07-30 22:17:52 +0000470 typename TypeParam::iterator I =
471 this->theVector.insert(this->theVector.begin() + 1, 2, Constructable(16));
David Blaikieae8a9322014-06-08 19:12:28 +0000472 EXPECT_EQ(0, Constructable::getNumCopyConstructorCalls());
Chandler Carruth0b012612012-07-30 22:17:52 +0000473 EXPECT_EQ(this->theVector.begin() + 1, I);
474 this->assertValuesInOrder(this->theVector, 8u,
475 10, 16, 16, 11, 12, 13, 14, 15);
Benjamin Kramer371b9b02012-06-17 11:52:22 +0000476
Benjamin Kramer23a9c3e02012-06-17 12:46:13 +0000477 // Insert at end.
Chandler Carruth0b012612012-07-30 22:17:52 +0000478 I = this->theVector.insert(this->theVector.end(), 2, Constructable(16));
479 EXPECT_EQ(this->theVector.begin() + 8, I);
480 this->assertValuesInOrder(this->theVector, 10u,
481 10, 16, 16, 11, 12, 13, 14, 15, 16, 16);
Benjamin Kramer23a9c3e02012-06-17 12:46:13 +0000482
483 // Empty insert.
Chandler Carruth0b012612012-07-30 22:17:52 +0000484 EXPECT_EQ(this->theVector.end(),
485 this->theVector.insert(this->theVector.end(),
486 0, Constructable(42)));
487 EXPECT_EQ(this->theVector.begin() + 1,
488 this->theVector.insert(this->theVector.begin() + 1,
489 0, Constructable(42)));
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000490}
491
492// Insert range.
Chandler Carruth0b012612012-07-30 22:17:52 +0000493TYPED_TEST(SmallVectorTest, InsertRangeTest) {
Benjamin Kramer23a9c3e02012-06-17 12:46:13 +0000494 SCOPED_TRACE("InsertRangeTest");
495
496 Constructable Arr[3] =
497 { Constructable(77), Constructable(77), Constructable(77) };
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000498
Chandler Carruth0b012612012-07-30 22:17:52 +0000499 this->makeSequence(this->theVector, 1, 3);
500 typename TypeParam::iterator I =
501 this->theVector.insert(this->theVector.begin() + 1, Arr, Arr+3);
502 EXPECT_EQ(this->theVector.begin() + 1, I);
503 this->assertValuesInOrder(this->theVector, 6u, 1, 77, 77, 77, 2, 3);
Benjamin Kramer371b9b02012-06-17 11:52:22 +0000504
Benjamin Kramer23a9c3e02012-06-17 12:46:13 +0000505 // Insert at end.
Chandler Carruth0b012612012-07-30 22:17:52 +0000506 I = this->theVector.insert(this->theVector.end(), Arr, Arr+3);
507 EXPECT_EQ(this->theVector.begin() + 6, I);
508 this->assertValuesInOrder(this->theVector, 9u,
509 1, 77, 77, 77, 2, 3, 77, 77, 77);
Benjamin Kramer23a9c3e02012-06-17 12:46:13 +0000510
511 // Empty insert.
Chandler Carruth0b012612012-07-30 22:17:52 +0000512 EXPECT_EQ(this->theVector.end(),
513 this->theVector.insert(this->theVector.end(),
514 this->theVector.begin(),
515 this->theVector.begin()));
516 EXPECT_EQ(this->theVector.begin() + 1,
517 this->theVector.insert(this->theVector.begin() + 1,
518 this->theVector.begin(),
519 this->theVector.begin()));
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000520}
521
522// Comparison tests.
Chandler Carruth0b012612012-07-30 22:17:52 +0000523TYPED_TEST(SmallVectorTest, ComparisonTest) {
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000524 SCOPED_TRACE("ComparisonTest");
525
Chandler Carruth0b012612012-07-30 22:17:52 +0000526 this->makeSequence(this->theVector, 1, 3);
527 this->makeSequence(this->otherVector, 1, 3);
Owen Anderson145a2602011-07-06 22:36:59 +0000528
Chandler Carruth0b012612012-07-30 22:17:52 +0000529 EXPECT_TRUE(this->theVector == this->otherVector);
530 EXPECT_FALSE(this->theVector != this->otherVector);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000531
Chandler Carruth0b012612012-07-30 22:17:52 +0000532 this->otherVector.clear();
533 this->makeSequence(this->otherVector, 2, 4);
Owen Anderson145a2602011-07-06 22:36:59 +0000534
Chandler Carruth0b012612012-07-30 22:17:52 +0000535 EXPECT_FALSE(this->theVector == this->otherVector);
536 EXPECT_TRUE(this->theVector != this->otherVector);
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000537}
538
539// Constant vector tests.
Chandler Carruth0b012612012-07-30 22:17:52 +0000540TYPED_TEST(SmallVectorTest, ConstVectorTest) {
541 const TypeParam constVector;
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000542
543 EXPECT_EQ(0u, constVector.size());
544 EXPECT_TRUE(constVector.empty());
545 EXPECT_TRUE(constVector.begin() == constVector.end());
546}
547
Daniel Dunbar825e9552009-08-19 17:48:28 +0000548// Direct array access.
Chandler Carruth0b012612012-07-30 22:17:52 +0000549TYPED_TEST(SmallVectorTest, DirectVectorTest) {
550 EXPECT_EQ(0u, this->theVector.size());
551 this->theVector.reserve(4);
552 EXPECT_LE(4u, this->theVector.capacity());
Daniel Dunbar825e9552009-08-19 17:48:28 +0000553 EXPECT_EQ(0, Constructable::getNumConstructorCalls());
Douglas Gregor8451cdff2014-04-30 15:49:06 +0000554 this->theVector.push_back(1);
555 this->theVector.push_back(2);
556 this->theVector.push_back(3);
557 this->theVector.push_back(4);
Chandler Carruth0b012612012-07-30 22:17:52 +0000558 EXPECT_EQ(4u, this->theVector.size());
Douglas Gregor8451cdff2014-04-30 15:49:06 +0000559 EXPECT_EQ(8, Constructable::getNumConstructorCalls());
Chandler Carruth0b012612012-07-30 22:17:52 +0000560 EXPECT_EQ(1, this->theVector[0].getValue());
561 EXPECT_EQ(2, this->theVector[1].getValue());
562 EXPECT_EQ(3, this->theVector[2].getValue());
563 EXPECT_EQ(4, this->theVector[3].getValue());
Daniel Dunbar825e9552009-08-19 17:48:28 +0000564}
565
Chandler Carruth0b012612012-07-30 22:17:52 +0000566TYPED_TEST(SmallVectorTest, IteratorTest) {
Dan Gohman42e77df2010-03-26 18:53:37 +0000567 std::list<int> L;
Chandler Carruth0b012612012-07-30 22:17:52 +0000568 this->theVector.insert(this->theVector.end(), L.begin(), L.end());
Dan Gohman42e77df2010-03-26 18:53:37 +0000569}
570
Benjamin Kramer74a12a42012-04-29 10:53:29 +0000571struct notassignable {
572 int &x;
573 notassignable(int &x) : x(x) {}
574};
575
Chandler Carruth0b012612012-07-30 22:17:52 +0000576TEST(SmallVectorCustomTest, NoAssignTest) {
Benjamin Kramer74a12a42012-04-29 10:53:29 +0000577 int x = 0;
578 SmallVector<notassignable, 2> vec;
579 vec.push_back(notassignable(x));
580 x = 42;
581 EXPECT_EQ(42, vec.pop_back_val().x);
582}
583
David Blaikie789df062014-06-08 16:00:02 +0000584struct MovedFrom {
585 bool hasValue;
586 MovedFrom() : hasValue(true) {
587 }
588 MovedFrom(MovedFrom&& m) : hasValue(m.hasValue) {
589 m.hasValue = false;
590 }
591 MovedFrom &operator=(MovedFrom&& m) {
592 hasValue = m.hasValue;
593 m.hasValue = false;
594 return *this;
595 }
596};
597
598TEST(SmallVectorTest, MidInsert) {
599 SmallVector<MovedFrom, 3> v;
600 v.push_back(MovedFrom());
601 v.insert(v.begin(), MovedFrom());
602 for (MovedFrom &m : v)
603 EXPECT_TRUE(m.hasValue);
604}
605
Bill Wendlingc56c37f2009-01-10 12:56:31 +0000606}