1 //===- llvm/unittest/ADT/TinyPtrVectorTest.cpp ----------------------------===//
2 //
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 // TinyPtrVector unit tests.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/ADT/TinyPtrVector.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/Support/type_traits.h"
18 #include "gtest/gtest.h"
19 #include <algorithm>
20 #include <random>
21 #include <vector>
22 
23 using namespace llvm;
24 
25 namespace {
26 
27 template <typename VectorT>
28 class TinyPtrVectorTest : public testing::Test {
29 protected:
30   typedef typename VectorT::value_type PtrT;
31   typedef typename std::remove_pointer<PtrT>::type ValueT;
32 
33   VectorT V;
34   VectorT V2;
35 
36   ValueT TestValues[1024];
37   std::vector<PtrT> TestPtrs;
38 
39   TinyPtrVectorTest() {
40     for (size_t i = 0, e = array_lengthof(TestValues); i != e; ++i)
41       TestPtrs.push_back(&TestValues[i]);
42 
43     std::shuffle(TestPtrs.begin(), TestPtrs.end(), std::mt19937{});
44   }
45 
46   ArrayRef<PtrT> testArray(size_t N) {
47     return makeArrayRef(&TestPtrs[0], N);
48   }
49 
50   void appendValues(VectorT &V, ArrayRef<PtrT> Values) {
51     for (size_t i = 0, e = Values.size(); i != e; ++i)
52       V.push_back(Values[i]);
53   }
54 
55   void setVectors(ArrayRef<PtrT> Values1, ArrayRef<PtrT> Values2) {
56     V.clear();
57     appendValues(V, Values1);
58     V2.clear();
59     appendValues(V2, Values2);
60   }
61 
62   void expectValues(const VectorT &V, ArrayRef<PtrT> 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], *std::next(V.begin(), i));
68     }
69     EXPECT_EQ(V.end(), std::next(V.begin(), Values.size()));
70   }
71 };
72 
73 typedef ::testing::Types<TinyPtrVector<int*>,
74                          TinyPtrVector<double*>
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   TypeParam Move(std::move(Copy2));
153   this->expectValues(Move, this->testArray(42));
154   this->expectValues(Copy2, this->testArray(0));
155 }
156 
157 TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) {
158   this->V = this->V2;
159   this->expectValues(this->V, this->testArray(0));
160   this->expectValues(this->V2, this->testArray(0));
161   this->V = std::move(this->V2);
162   this->expectValues(this->V, this->testArray(0));
163 
164   this->setVectors(this->testArray(1), this->testArray(0));
165   this->V = this->V2;
166   this->expectValues(this->V, this->testArray(0));
167   this->expectValues(this->V2, this->testArray(0));
168   this->setVectors(this->testArray(1), this->testArray(0));
169   this->V = std::move(this->V2);
170   this->expectValues(this->V, this->testArray(0));
171 
172   this->setVectors(this->testArray(2), this->testArray(0));
173   this->V = this->V2;
174   this->expectValues(this->V, this->testArray(0));
175   this->expectValues(this->V2, this->testArray(0));
176   this->setVectors(this->testArray(2), this->testArray(0));
177   this->V = std::move(this->V2);
178   this->expectValues(this->V, this->testArray(0));
179 
180   this->setVectors(this->testArray(42), this->testArray(0));
181   this->V = this->V2;
182   this->expectValues(this->V, this->testArray(0));
183   this->expectValues(this->V2, this->testArray(0));
184   this->setVectors(this->testArray(42), this->testArray(0));
185   this->V = std::move(this->V2);
186   this->expectValues(this->V, this->testArray(0));
187 
188   this->setVectors(this->testArray(0), this->testArray(1));
189   this->V = this->V2;
190   this->expectValues(this->V, this->testArray(1));
191   this->expectValues(this->V2, this->testArray(1));
192   this->setVectors(this->testArray(0), this->testArray(1));
193   this->V = std::move(this->V2);
194   this->expectValues(this->V, this->testArray(1));
195 
196   this->setVectors(this->testArray(0), this->testArray(2));
197   this->V = this->V2;
198   this->expectValues(this->V, this->testArray(2));
199   this->expectValues(this->V2, this->testArray(2));
200   this->setVectors(this->testArray(0), this->testArray(2));
201   this->V = std::move(this->V2);
202   this->expectValues(this->V, this->testArray(2));
203 
204   this->setVectors(this->testArray(0), this->testArray(42));
205   this->V = this->V2;
206   this->expectValues(this->V, this->testArray(42));
207   this->expectValues(this->V2, this->testArray(42));
208   this->setVectors(this->testArray(0), this->testArray(42));
209   this->V = std::move(this->V2);
210   this->expectValues(this->V, this->testArray(42));
211 
212   this->setVectors(this->testArray(1), this->testArray(1));
213   this->V = this->V2;
214   this->expectValues(this->V, this->testArray(1));
215   this->expectValues(this->V2, this->testArray(1));
216   this->V = std::move(this->V2);
217   this->expectValues(this->V, this->testArray(1));
218 
219   this->setVectors(this->testArray(1), this->testArray(2));
220   this->V = this->V2;
221   this->expectValues(this->V, this->testArray(2));
222   this->expectValues(this->V2, this->testArray(2));
223   this->setVectors(this->testArray(1), this->testArray(2));
224   this->V = std::move(this->V2);
225   this->expectValues(this->V, this->testArray(2));
226 
227   this->setVectors(this->testArray(1), this->testArray(42));
228   this->V = this->V2;
229   this->expectValues(this->V, this->testArray(42));
230   this->expectValues(this->V2, this->testArray(42));
231   this->setVectors(this->testArray(1), this->testArray(42));
232   this->V = std::move(this->V2);
233   this->expectValues(this->V, this->testArray(42));
234 
235   this->setVectors(this->testArray(2), this->testArray(1));
236   this->V = this->V2;
237   this->expectValues(this->V, this->testArray(1));
238   this->expectValues(this->V2, this->testArray(1));
239   this->setVectors(this->testArray(2), this->testArray(1));
240   this->V = std::move(this->V2);
241   this->expectValues(this->V, this->testArray(1));
242 
243   this->setVectors(this->testArray(2), this->testArray(2));
244   this->V = this->V2;
245   this->expectValues(this->V, this->testArray(2));
246   this->expectValues(this->V2, this->testArray(2));
247   this->setVectors(this->testArray(2), this->testArray(2));
248   this->V = std::move(this->V2);
249   this->expectValues(this->V, this->testArray(2));
250 
251   this->setVectors(this->testArray(2), this->testArray(42));
252   this->V = this->V2;
253   this->expectValues(this->V, this->testArray(42));
254   this->expectValues(this->V2, this->testArray(42));
255   this->setVectors(this->testArray(2), this->testArray(42));
256   this->V = std::move(this->V2);
257   this->expectValues(this->V, this->testArray(42));
258 
259   this->setVectors(this->testArray(42), this->testArray(1));
260   this->V = this->V2;
261   this->expectValues(this->V, this->testArray(1));
262   this->expectValues(this->V2, this->testArray(1));
263   this->setVectors(this->testArray(42), this->testArray(1));
264   this->V = std::move(this->V2);
265   this->expectValues(this->V, this->testArray(1));
266 
267   this->setVectors(this->testArray(42), this->testArray(2));
268   this->V = this->V2;
269   this->expectValues(this->V, this->testArray(2));
270   this->expectValues(this->V2, this->testArray(2));
271   this->setVectors(this->testArray(42), this->testArray(2));
272   this->V = std::move(this->V2);
273   this->expectValues(this->V, this->testArray(2));
274 
275   this->setVectors(this->testArray(42), this->testArray(42));
276   this->V = this->V2;
277   this->expectValues(this->V, this->testArray(42));
278   this->expectValues(this->V2, this->testArray(42));
279   this->setVectors(this->testArray(42), this->testArray(42));
280   this->V = std::move(this->V2);
281   this->expectValues(this->V, this->testArray(42));
282 }
283 
284 TYPED_TEST(TinyPtrVectorTest, EraseTest) {
285   this->appendValues(this->V, this->testArray(1));
286   this->expectValues(this->V, this->testArray(1));
287   this->V.erase(this->V.begin());
288   this->expectValues(this->V, this->testArray(0));
289 
290   this->appendValues(this->V, this->testArray(42));
291   this->expectValues(this->V, this->testArray(42));
292   this->V.erase(this->V.begin());
293   this->TestPtrs.erase(this->TestPtrs.begin());
294   this->expectValues(this->V, this->testArray(41));
295   this->V.erase(std::next(this->V.begin(), 1));
296   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 1));
297   this->expectValues(this->V, this->testArray(40));
298   this->V.erase(std::next(this->V.begin(), 2));
299   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 2));
300   this->expectValues(this->V, this->testArray(39));
301   this->V.erase(std::next(this->V.begin(), 5));
302   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 5));
303   this->expectValues(this->V, this->testArray(38));
304   this->V.erase(std::next(this->V.begin(), 13));
305   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 13));
306   this->expectValues(this->V, this->testArray(37));
307 
308   typename TypeParam::iterator I = this->V.begin();
309   do {
310     I = this->V.erase(I);
311   } while (I != this->V.end());
312   this->expectValues(this->V, this->testArray(0));
313 }
314 
315 TYPED_TEST(TinyPtrVectorTest, EraseRangeTest) {
316   this->appendValues(this->V, this->testArray(1));
317   this->expectValues(this->V, this->testArray(1));
318   this->V.erase(this->V.begin(), this->V.begin());
319   this->expectValues(this->V, this->testArray(1));
320   this->V.erase(this->V.end(), this->V.end());
321   this->expectValues(this->V, this->testArray(1));
322   this->V.erase(this->V.begin(), this->V.end());
323   this->expectValues(this->V, this->testArray(0));
324 
325   this->appendValues(this->V, this->testArray(42));
326   this->expectValues(this->V, this->testArray(42));
327   this->V.erase(this->V.begin(), std::next(this->V.begin(), 1));
328   this->TestPtrs.erase(this->TestPtrs.begin(),
329                        std::next(this->TestPtrs.begin(), 1));
330   this->expectValues(this->V, this->testArray(41));
331   this->V.erase(std::next(this->V.begin(), 1), std::next(this->V.begin(), 2));
332   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 1),
333                        std::next(this->TestPtrs.begin(), 2));
334   this->expectValues(this->V, this->testArray(40));
335   this->V.erase(std::next(this->V.begin(), 2), std::next(this->V.begin(), 4));
336   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 2),
337                        std::next(this->TestPtrs.begin(), 4));
338   this->expectValues(this->V, this->testArray(38));
339   this->V.erase(std::next(this->V.begin(), 5), std::next(this->V.begin(), 10));
340   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 5),
341                        std::next(this->TestPtrs.begin(), 10));
342   this->expectValues(this->V, this->testArray(33));
343   this->V.erase(std::next(this->V.begin(), 13), std::next(this->V.begin(), 26));
344   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 13),
345                        std::next(this->TestPtrs.begin(), 26));
346   this->expectValues(this->V, this->testArray(20));
347   this->V.erase(std::next(this->V.begin(), 7), this->V.end());
348   this->expectValues(this->V, this->testArray(7));
349   this->V.erase(this->V.begin(), this->V.end());
350   this->expectValues(this->V, this->testArray(0));
351 }
352 
353 TYPED_TEST(TinyPtrVectorTest, Insert) {
354   this->V.insert(this->V.end(), this->TestPtrs[0]);
355   this->expectValues(this->V, this->testArray(1));
356   this->V.clear();
357   this->appendValues(this->V, this->testArray(4));
358   this->expectValues(this->V, this->testArray(4));
359   this->V.insert(this->V.end(), this->TestPtrs[4]);
360   this->expectValues(this->V, this->testArray(5));
361   this->V.insert(this->V.begin(), this->TestPtrs[42]);
362   this->TestPtrs.insert(this->TestPtrs.begin(), this->TestPtrs[42]);
363   this->expectValues(this->V, this->testArray(6));
364   this->V.insert(std::next(this->V.begin(), 3), this->TestPtrs[43]);
365   this->TestPtrs.insert(std::next(this->TestPtrs.begin(), 3),
366                         this->TestPtrs[43]);
367   this->expectValues(this->V, this->testArray(7));
368 }
369 
370 TYPED_TEST(TinyPtrVectorTest, InsertRange) {
371   this->V.insert(this->V.end(), this->TestPtrs.begin(), this->TestPtrs.begin());
372   this->expectValues(this->V, this->testArray(0));
373   this->V.insert(this->V.begin(), this->TestPtrs.begin(),
374                  this->TestPtrs.begin());
375   this->expectValues(this->V, this->testArray(0));
376   this->V.insert(this->V.end(), this->TestPtrs.end(), this->TestPtrs.end());
377   this->expectValues(this->V, this->testArray(0));
378   this->V.insert(this->V.end(), this->TestPtrs.begin(),
379                  std::next(this->TestPtrs.begin()));
380   this->expectValues(this->V, this->testArray(1));
381   this->V.clear();
382   this->V.insert(this->V.end(), this->TestPtrs.begin(),
383                  std::next(this->TestPtrs.begin(), 2));
384   this->expectValues(this->V, this->testArray(2));
385   this->V.clear();
386   this->V.insert(this->V.end(), this->TestPtrs.begin(),
387                  std::next(this->TestPtrs.begin(), 42));
388   this->expectValues(this->V, this->testArray(42));
389   this->V.clear();
390   this->V.insert(this->V.end(),
391                  std::next(this->TestPtrs.begin(), 5),
392                  std::next(this->TestPtrs.begin(), 13));
393   this->V.insert(this->V.begin(),
394                  std::next(this->TestPtrs.begin(), 0),
395                  std::next(this->TestPtrs.begin(), 3));
396   this->V.insert(std::next(this->V.begin(), 2),
397                  std::next(this->TestPtrs.begin(), 2),
398                  std::next(this->TestPtrs.begin(), 4));
399   this->V.erase(std::next(this->V.begin(), 4));
400   this->V.insert(std::next(this->V.begin(), 4),
401                  std::next(this->TestPtrs.begin(), 4),
402                  std::next(this->TestPtrs.begin(), 5));
403   this->expectValues(this->V, this->testArray(13));
404 }
405 
406 }
407 
408 TEST(TinyPtrVectorTest, SingleEltCtorTest) {
409   int v = 55;
410   TinyPtrVector<int *> V(&v);
411 
412   EXPECT_TRUE(V.size() == 1);
413   EXPECT_FALSE(V.empty());
414   EXPECT_TRUE(V.front() == &v);
415 }
416 
417 TEST(TinyPtrVectorTest, ArrayRefCtorTest) {
418   int data_array[128];
419   std::vector<int *> data;
420 
421   for (unsigned i = 0, e = 128; i != e; ++i) {
422     data_array[i] = 324 - int(i);
423     data.push_back(&data_array[i]);
424   }
425 
426   TinyPtrVector<int *> V(data);
427   EXPECT_TRUE(V.size() == 128);
428   EXPECT_FALSE(V.empty());
429   for (unsigned i = 0, e = 128; i != e; ++i) {
430     EXPECT_TRUE(V[i] == data[i]);
431   }
432 }
433 
434 TEST(TinyPtrVectorTest, MutableArrayRefTest) {
435   int data_array[128];
436   std::vector<int *> data;
437 
438   for (unsigned i = 0, e = 128; i != e; ++i) {
439     data_array[i] = 324 - int(i);
440     data.push_back(&data_array[i]);
441   }
442 
443   TinyPtrVector<int *> V(data);
444   EXPECT_TRUE(V.size() == 128);
445   EXPECT_FALSE(V.empty());
446 
447   MutableArrayRef<int *> mut_array = V;
448   for (unsigned i = 0, e = 128; i != e; ++i) {
449     EXPECT_TRUE(mut_array[i] == data[i]);
450     mut_array[i] = 324 + mut_array[i];
451     EXPECT_TRUE(mut_array[i] == (324 + data[i]));
452   }
453 }
454