llvm.org GIT mirror llvm / 40dab10
Bring TinyPtrVector under test. Somehow we never picked up unit tests for this class. These tests exercise most of the basic properties, but the API for TinyPtrVector is very strange currently. My plan is to start fleshing out the API to match that of SmallVector, but I wanted a test for what is there first. Sadly, it doesn't look reasonable to just re-use the SmallVector tests, as this container can only ever store pointers, and much of the SmallVector testing is to get construction and destruction right. Just to get this basic test working, I had to add value_type to the interface. While here I found a subtle bug in the combination of 'erase', 'begin', and 'end'. Both 'begin' and 'end' wanted to use a null pointer to indicate the "end" iterator of an empty vector, regardless of whether there is actually a vector allocated or the pointer union is null. Everything else was fine with this except for erase. If you erase the last element of a vector after it has held more than one element, we return the end iterator of the underlying SmallVector which need not be a null pointer. Instead, simply use the pointer, and poniter + size() begin/end definitions in the tiny case, and delegate to the inner vector whenever it is present. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161024 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 8 years ago
3 changed file(s) with 196 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
2626 class TinyPtrVector {
2727 public:
2828 typedef llvm::SmallVector VecTy;
29 typedef typename VecTy::value_type value_type;
30
2931 llvm::PointerUnion Val;
3032
3133 TinyPtrVector() {}
7375 typedef EltTy *iterator;
7476
7577 iterator begin() {
76 if (empty())
77 return 0;
78
7978 if (Val.template is())
8079 return Val.getAddrOfPtr1();
8180
8382
8483 }
8584 iterator end() {
86 if (empty())
87 return 0;
88
8985 if (Val.template is())
90 return begin() + 1;
86 return begin() + (Val.isNull() ? 0 : 1);
9187
9288 return Val.template get()->end();
9389 }
176172 // benefit to collapsing back to a pointer
177173 return Vec->erase(I);
178174 }
179
180 return 0;
175 return end();
181176 }
182177
183178 private:
2525 SparseSetTest.cpp
2626 StringMapTest.cpp
2727 StringRefTest.cpp
28 TinyPtrVectorTest.cpp
2829 TripleTest.cpp
2930 TwineTest.cpp
3031 VariadicFunctionTest.cpp
0 //===- llvm/unittest/ADT/TinyPtrVectorTest.cpp ----------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // TinyPtrVector unit tests.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "gtest/gtest.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/TinyPtrVector.h"
18 #include "llvm/Support/type_traits.h"
19 #include
20 #include
21 #include
22
23 using namespace llvm;
24
25 namespace {
26
27 // The world's worst RNG, but it is deterministic and makes it easy to get
28 // *some* shuffling of elements.
29 static ptrdiff_t test_shuffle_rng(ptrdiff_t i) {
30 return (i + i * 33) % i;
31 }
32 static ptrdiff_t (*test_shuffle_rng_p)(ptrdiff_t) = &test_shuffle_rng;
33
34 template
35 class TinyPtrVectorTest : public testing::Test {
36 protected:
37 typedef typename VectorT::value_type PtrT;
38 typedef typename remove_pointer::type ValueT;
39
40 VectorT V;
41 VectorT V2;
42
43 ValueT TestValues[1024];
44 std::vector TestPtrs;
45
46 TinyPtrVectorTest() {
47 for (size_t i = 0, e = array_lengthof(TestValues); i != e; ++i)
48 TestPtrs.push_back(&TestValues[i]);
49
50 std::random_shuffle(TestPtrs.begin(), TestPtrs.end(), test_shuffle_rng_p);
51 }
52
53 ArrayRef testArray(size_t N) {
54 return makeArrayRef(&TestPtrs[0], N);
55 }
56
57 void appendValues(VectorT &V, ArrayRef Values) {
58 for (size_t i = 0, e = Values.size(); i != e; ++i)
59 V.push_back(Values[i]);
60 }
61
62 void expectValues(const VectorT &V, ArrayRef Values) {
63 EXPECT_EQ(Values.empty(), V.empty());
64 EXPECT_EQ(Values.size(), V.size());
65 for (size_t i = 0, e = Values.size(); i != e; ++i) {
66 EXPECT_EQ(Values[i], V[i]);
67 EXPECT_EQ(Values[i], *llvm::next(V.begin(), i));
68 }
69 EXPECT_EQ(V.end(), llvm::next(V.begin(), Values.size()));
70 }
71 };
72
73 typedef ::testing::Types,
74 TinyPtrVector
75 > TinyPtrVectorTestTypes;
76 TYPED_TEST_CASE(TinyPtrVectorTest, TinyPtrVectorTestTypes);
77
78 TYPED_TEST(TinyPtrVectorTest, EmptyTest) {
79 this->expectValues(this->V, this->testArray(0));
80 }
81
82 TYPED_TEST(TinyPtrVectorTest, PushPopBack) {
83 this->V.push_back(this->TestPtrs[0]);
84 this->expectValues(this->V, this->testArray(1));
85 this->V.push_back(this->TestPtrs[1]);
86 this->expectValues(this->V, this->testArray(2));
87 this->V.push_back(this->TestPtrs[2]);
88 this->expectValues(this->V, this->testArray(3));
89 this->V.push_back(this->TestPtrs[3]);
90 this->expectValues(this->V, this->testArray(4));
91 this->V.push_back(this->TestPtrs[4]);
92 this->expectValues(this->V, this->testArray(5));
93
94 // Pop and clobber a few values to keep things interesting.
95 this->V.pop_back();
96 this->expectValues(this->V, this->testArray(4));
97 this->V.pop_back();
98 this->expectValues(this->V, this->testArray(3));
99 this->TestPtrs[3] = &this->TestValues[42];
100 this->TestPtrs[4] = &this->TestValues[43];
101 this->V.push_back(this->TestPtrs[3]);
102 this->expectValues(this->V, this->testArray(4));
103 this->V.push_back(this->TestPtrs[4]);
104 this->expectValues(this->V, this->testArray(5));
105
106 this->V.pop_back();
107 this->expectValues(this->V, this->testArray(4));
108 this->V.pop_back();
109 this->expectValues(this->V, this->testArray(3));
110 this->V.pop_back();
111 this->expectValues(this->V, this->testArray(2));
112 this->V.pop_back();
113 this->expectValues(this->V, this->testArray(1));
114 this->V.pop_back();
115 this->expectValues(this->V, this->testArray(0));
116
117 this->appendValues(this->V, this->testArray(42));
118 this->expectValues(this->V, this->testArray(42));
119 }
120
121 TYPED_TEST(TinyPtrVectorTest, ClearTest) {
122 this->expectValues(this->V, this->testArray(0));
123 this->V.clear();
124 this->expectValues(this->V, this->testArray(0));
125
126 this->appendValues(this->V, this->testArray(1));
127 this->expectValues(this->V, this->testArray(1));
128 this->V.clear();
129 this->expectValues(this->V, this->testArray(0));
130
131 this->appendValues(this->V, this->testArray(42));
132 this->expectValues(this->V, this->testArray(42));
133 this->V.clear();
134 this->expectValues(this->V, this->testArray(0));
135 }
136
137 TYPED_TEST(TinyPtrVectorTest, CopyAndMoveCtorTest) {
138 this->appendValues(this->V, this->testArray(42));
139 TypeParam Copy(this->V);
140 this->expectValues(Copy, this->testArray(42));
141
142 // This is a separate copy, and so it shouldn't destroy the original.
143 Copy.clear();
144 this->expectValues(Copy, this->testArray(0));
145 this->expectValues(this->V, this->testArray(42));
146
147 TypeParam Copy2(this->V2);
148 this->appendValues(Copy2, this->testArray(42));
149 this->expectValues(Copy2, this->testArray(42));
150 this->expectValues(this->V2, this->testArray(0));
151
152 #if LLVM_USE_RVALUE_REFERENCES
153 TypeParam Move(std::move(Copy2));
154 this->expectValues(Move, this->testArray(42));
155 this->expectValues(Copy2, this->testArray(0));
156 #endif
157 }
158
159 TYPED_TEST(TinyPtrVectorTest, EraseTest) {
160 this->appendValues(this->V, this->testArray(1));
161 this->expectValues(this->V, this->testArray(1));
162 this->V.erase(this->V.begin());
163 this->expectValues(this->V, this->testArray(0));
164
165 this->appendValues(this->V, this->testArray(42));
166 this->expectValues(this->V, this->testArray(42));
167 this->V.erase(this->V.begin());
168 this->TestPtrs.erase(this->TestPtrs.begin());
169 this->expectValues(this->V, this->testArray(41));
170 this->V.erase(llvm::next(this->V.begin(), 1));
171 this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 1));
172 this->expectValues(this->V, this->testArray(40));
173 this->V.erase(llvm::next(this->V.begin(), 2));
174 this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 2));
175 this->expectValues(this->V, this->testArray(39));
176 this->V.erase(llvm::next(this->V.begin(), 5));
177 this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 5));
178 this->expectValues(this->V, this->testArray(38));
179 this->V.erase(llvm::next(this->V.begin(), 13));
180 this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 13));
181 this->expectValues(this->V, this->testArray(37));
182
183 typename TypeParam::iterator I = this->V.begin();
184 do {
185 I = this->V.erase(I);
186 } while (I != this->V.end());
187 this->expectValues(this->V, this->testArray(0));
188 }
189
190 }