1 //===- llvm/unittest/ADT/TinyPtrVectorTest.cpp ----------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // TinyPtrVector unit tests.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/ADT/TinyPtrVector.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/Support/type_traits.h"
17 #include "gtest/gtest.h"
25 template <typename T
> struct RemovePointer
: std::remove_pointer
<T
> {};
27 template <typename PointerTy
, unsigned IntBits
, typename IntType
,
28 typename PtrTraits
, typename Info
>
30 PointerIntPair
<PointerTy
, IntBits
, IntType
, PtrTraits
, Info
>> {
31 typedef typename RemovePointer
<PointerTy
>::type type
;
34 template <typename VectorT
>
35 class TinyPtrVectorTest
: public testing::Test
{
37 typedef typename
VectorT::value_type PtrT
;
38 typedef typename RemovePointer
<PtrT
>::type ValueT
;
39 using PtrTraits
= PointerLikeTypeTraits
<PtrT
>;
44 ValueT TestValues
[1024];
45 std::vector
<PtrT
> TestPtrs
;
48 for (size_t i
= 0, e
= std::size(TestValues
); i
!= e
; ++i
)
49 TestPtrs
.push_back(PtrT(&TestValues
[i
]));
51 std::shuffle(TestPtrs
.begin(), TestPtrs
.end(), std::mt19937
{});
54 PtrT
makePtr(ValueT
*V
) { return PtrT(V
); }
56 ArrayRef
<PtrT
> testArray(size_t N
) { return ArrayRef(&TestPtrs
[0], N
); }
58 void appendValues(VectorT
&V
, ArrayRef
<PtrT
> Values
) {
59 for (size_t i
= 0, e
= Values
.size(); i
!= e
; ++i
)
60 V
.push_back(Values
[i
]);
63 void setVectors(ArrayRef
<PtrT
> Values1
, ArrayRef
<PtrT
> Values2
) {
65 appendValues(V
, Values1
);
67 appendValues(V2
, Values2
);
70 void expectValues(const VectorT
&V
, ArrayRef
<PtrT
> Values
) {
71 EXPECT_EQ(Values
.empty(), V
.empty());
72 EXPECT_EQ(Values
.size(), V
.size());
73 for (size_t i
= 0, e
= Values
.size(); i
!= e
; ++i
) {
74 EXPECT_EQ(Values
[i
], V
[i
]);
75 EXPECT_EQ(Values
[i
], *std::next(V
.begin(), i
));
77 EXPECT_EQ(V
.end(), std::next(V
.begin(), Values
.size()));
81 typedef ::testing::Types
<TinyPtrVector
<int *>, TinyPtrVector
<double *>,
82 TinyPtrVector
<PointerIntPair
<int *, 1>>>
83 TinyPtrVectorTestTypes
;
84 TYPED_TEST_SUITE(TinyPtrVectorTest
, TinyPtrVectorTestTypes
, );
86 TYPED_TEST(TinyPtrVectorTest
, EmptyTest
) {
87 this->expectValues(this->V
, this->testArray(0));
90 TYPED_TEST(TinyPtrVectorTest
, PushPopBack
) {
91 this->V
.push_back(this->TestPtrs
[0]);
92 this->expectValues(this->V
, this->testArray(1));
93 this->V
.push_back(this->TestPtrs
[1]);
94 this->expectValues(this->V
, this->testArray(2));
95 this->V
.push_back(this->TestPtrs
[2]);
96 this->expectValues(this->V
, this->testArray(3));
97 this->V
.push_back(this->TestPtrs
[3]);
98 this->expectValues(this->V
, this->testArray(4));
99 this->V
.push_back(this->TestPtrs
[4]);
100 this->expectValues(this->V
, this->testArray(5));
102 // Pop and clobber a few values to keep things interesting.
104 this->expectValues(this->V
, this->testArray(4));
106 this->expectValues(this->V
, this->testArray(3));
107 this->TestPtrs
[3] = this->makePtr(&this->TestValues
[42]);
108 this->TestPtrs
[4] = this->makePtr(&this->TestValues
[43]);
109 this->V
.push_back(this->TestPtrs
[3]);
110 this->expectValues(this->V
, this->testArray(4));
111 this->V
.push_back(this->TestPtrs
[4]);
112 this->expectValues(this->V
, this->testArray(5));
115 this->expectValues(this->V
, this->testArray(4));
117 this->expectValues(this->V
, this->testArray(3));
119 this->expectValues(this->V
, this->testArray(2));
121 this->expectValues(this->V
, this->testArray(1));
123 this->expectValues(this->V
, this->testArray(0));
125 this->appendValues(this->V
, this->testArray(42));
126 this->expectValues(this->V
, this->testArray(42));
129 TYPED_TEST(TinyPtrVectorTest
, ClearTest
) {
130 this->expectValues(this->V
, this->testArray(0));
132 this->expectValues(this->V
, this->testArray(0));
134 this->appendValues(this->V
, this->testArray(1));
135 this->expectValues(this->V
, this->testArray(1));
137 this->expectValues(this->V
, this->testArray(0));
139 this->appendValues(this->V
, this->testArray(42));
140 this->expectValues(this->V
, this->testArray(42));
142 this->expectValues(this->V
, this->testArray(0));
145 TYPED_TEST(TinyPtrVectorTest
, CopyAndMoveCtorTest
) {
146 this->appendValues(this->V
, this->testArray(42));
147 TypeParam
Copy(this->V
);
148 this->expectValues(Copy
, this->testArray(42));
150 // This is a separate copy, and so it shouldn't destroy the original.
152 this->expectValues(Copy
, this->testArray(0));
153 this->expectValues(this->V
, this->testArray(42));
155 TypeParam
Copy2(this->V2
);
156 this->appendValues(Copy2
, this->testArray(42));
157 this->expectValues(Copy2
, this->testArray(42));
158 this->expectValues(this->V2
, this->testArray(0));
160 TypeParam
Move(std::move(Copy2
));
161 this->expectValues(Move
, this->testArray(42));
162 this->expectValues(Copy2
, this->testArray(0));
164 TypeParam
MultipleElements(this->testArray(2));
165 TypeParam
SingleElement(this->testArray(1));
166 MultipleElements
= std::move(SingleElement
);
167 this->expectValues(MultipleElements
, this->testArray(1));
168 this->expectValues(SingleElement
, this->testArray(0));
171 TYPED_TEST(TinyPtrVectorTest
, CopyAndMoveTest
) {
173 this->expectValues(this->V
, this->testArray(0));
174 this->expectValues(this->V2
, this->testArray(0));
175 this->V
= std::move(this->V2
);
176 this->expectValues(this->V
, this->testArray(0));
178 this->setVectors(this->testArray(1), this->testArray(0));
180 this->expectValues(this->V
, this->testArray(0));
181 this->expectValues(this->V2
, this->testArray(0));
182 this->setVectors(this->testArray(1), this->testArray(0));
183 this->V
= std::move(this->V2
);
184 this->expectValues(this->V
, this->testArray(0));
186 this->setVectors(this->testArray(2), this->testArray(0));
188 this->expectValues(this->V
, this->testArray(0));
189 this->expectValues(this->V2
, this->testArray(0));
190 this->setVectors(this->testArray(2), this->testArray(0));
191 this->V
= std::move(this->V2
);
192 this->expectValues(this->V
, this->testArray(0));
194 this->setVectors(this->testArray(42), this->testArray(0));
196 this->expectValues(this->V
, this->testArray(0));
197 this->expectValues(this->V2
, this->testArray(0));
198 this->setVectors(this->testArray(42), this->testArray(0));
199 this->V
= std::move(this->V2
);
200 this->expectValues(this->V
, this->testArray(0));
202 this->setVectors(this->testArray(0), this->testArray(1));
204 this->expectValues(this->V
, this->testArray(1));
205 this->expectValues(this->V2
, this->testArray(1));
206 this->setVectors(this->testArray(0), this->testArray(1));
207 this->V
= std::move(this->V2
);
208 this->expectValues(this->V
, this->testArray(1));
210 this->setVectors(this->testArray(0), this->testArray(2));
212 this->expectValues(this->V
, this->testArray(2));
213 this->expectValues(this->V2
, this->testArray(2));
214 this->setVectors(this->testArray(0), this->testArray(2));
215 this->V
= std::move(this->V2
);
216 this->expectValues(this->V
, this->testArray(2));
218 this->setVectors(this->testArray(0), this->testArray(42));
220 this->expectValues(this->V
, this->testArray(42));
221 this->expectValues(this->V2
, this->testArray(42));
222 this->setVectors(this->testArray(0), this->testArray(42));
223 this->V
= std::move(this->V2
);
224 this->expectValues(this->V
, this->testArray(42));
226 this->setVectors(this->testArray(1), this->testArray(1));
228 this->expectValues(this->V
, this->testArray(1));
229 this->expectValues(this->V2
, this->testArray(1));
230 this->V
= std::move(this->V2
);
231 this->expectValues(this->V
, this->testArray(1));
233 this->setVectors(this->testArray(1), this->testArray(2));
235 this->expectValues(this->V
, this->testArray(2));
236 this->expectValues(this->V2
, this->testArray(2));
237 this->setVectors(this->testArray(1), this->testArray(2));
238 this->V
= std::move(this->V2
);
239 this->expectValues(this->V
, this->testArray(2));
241 this->setVectors(this->testArray(1), this->testArray(42));
243 this->expectValues(this->V
, this->testArray(42));
244 this->expectValues(this->V2
, this->testArray(42));
245 this->setVectors(this->testArray(1), this->testArray(42));
246 this->V
= std::move(this->V2
);
247 this->expectValues(this->V
, this->testArray(42));
249 this->setVectors(this->testArray(2), this->testArray(1));
251 this->expectValues(this->V
, this->testArray(1));
252 this->expectValues(this->V2
, this->testArray(1));
253 this->setVectors(this->testArray(2), this->testArray(1));
254 this->V
= std::move(this->V2
);
255 this->expectValues(this->V
, this->testArray(1));
257 this->setVectors(this->testArray(2), this->testArray(2));
259 this->expectValues(this->V
, this->testArray(2));
260 this->expectValues(this->V2
, this->testArray(2));
261 this->setVectors(this->testArray(2), this->testArray(2));
262 this->V
= std::move(this->V2
);
263 this->expectValues(this->V
, this->testArray(2));
265 this->setVectors(this->testArray(2), this->testArray(42));
267 this->expectValues(this->V
, this->testArray(42));
268 this->expectValues(this->V2
, this->testArray(42));
269 this->setVectors(this->testArray(2), this->testArray(42));
270 this->V
= std::move(this->V2
);
271 this->expectValues(this->V
, this->testArray(42));
273 this->setVectors(this->testArray(42), this->testArray(1));
275 this->expectValues(this->V
, this->testArray(1));
276 this->expectValues(this->V2
, this->testArray(1));
277 this->setVectors(this->testArray(42), this->testArray(1));
278 this->V
= std::move(this->V2
);
279 this->expectValues(this->V
, this->testArray(1));
281 this->setVectors(this->testArray(42), this->testArray(2));
283 this->expectValues(this->V
, this->testArray(2));
284 this->expectValues(this->V2
, this->testArray(2));
285 this->setVectors(this->testArray(42), this->testArray(2));
286 this->V
= std::move(this->V2
);
287 this->expectValues(this->V
, this->testArray(2));
289 this->setVectors(this->testArray(42), this->testArray(42));
291 this->expectValues(this->V
, this->testArray(42));
292 this->expectValues(this->V2
, this->testArray(42));
293 this->setVectors(this->testArray(42), this->testArray(42));
294 this->V
= std::move(this->V2
);
295 this->expectValues(this->V
, this->testArray(42));
298 TYPED_TEST(TinyPtrVectorTest
, EraseTest
) {
299 this->appendValues(this->V
, this->testArray(1));
300 this->expectValues(this->V
, this->testArray(1));
301 this->V
.erase(this->V
.begin());
302 this->expectValues(this->V
, this->testArray(0));
304 this->appendValues(this->V
, this->testArray(42));
305 this->expectValues(this->V
, this->testArray(42));
306 this->V
.erase(this->V
.begin());
307 this->TestPtrs
.erase(this->TestPtrs
.begin());
308 this->expectValues(this->V
, this->testArray(41));
309 this->V
.erase(std::next(this->V
.begin(), 1));
310 this->TestPtrs
.erase(std::next(this->TestPtrs
.begin(), 1));
311 this->expectValues(this->V
, this->testArray(40));
312 this->V
.erase(std::next(this->V
.begin(), 2));
313 this->TestPtrs
.erase(std::next(this->TestPtrs
.begin(), 2));
314 this->expectValues(this->V
, this->testArray(39));
315 this->V
.erase(std::next(this->V
.begin(), 5));
316 this->TestPtrs
.erase(std::next(this->TestPtrs
.begin(), 5));
317 this->expectValues(this->V
, this->testArray(38));
318 this->V
.erase(std::next(this->V
.begin(), 13));
319 this->TestPtrs
.erase(std::next(this->TestPtrs
.begin(), 13));
320 this->expectValues(this->V
, this->testArray(37));
322 typename
TypeParam::iterator I
= this->V
.begin();
324 I
= this->V
.erase(I
);
325 } while (I
!= this->V
.end());
326 this->expectValues(this->V
, this->testArray(0));
329 TYPED_TEST(TinyPtrVectorTest
, EraseRangeTest
) {
330 this->appendValues(this->V
, this->testArray(1));
331 this->expectValues(this->V
, this->testArray(1));
332 this->V
.erase(this->V
.begin(), this->V
.begin());
333 this->expectValues(this->V
, this->testArray(1));
334 this->V
.erase(this->V
.end(), this->V
.end());
335 this->expectValues(this->V
, this->testArray(1));
336 this->V
.erase(this->V
.begin(), this->V
.end());
337 this->expectValues(this->V
, this->testArray(0));
339 this->appendValues(this->V
, this->testArray(42));
340 this->expectValues(this->V
, this->testArray(42));
341 this->V
.erase(this->V
.begin(), std::next(this->V
.begin(), 1));
342 this->TestPtrs
.erase(this->TestPtrs
.begin(),
343 std::next(this->TestPtrs
.begin(), 1));
344 this->expectValues(this->V
, this->testArray(41));
345 this->V
.erase(std::next(this->V
.begin(), 1), std::next(this->V
.begin(), 2));
346 this->TestPtrs
.erase(std::next(this->TestPtrs
.begin(), 1),
347 std::next(this->TestPtrs
.begin(), 2));
348 this->expectValues(this->V
, this->testArray(40));
349 this->V
.erase(std::next(this->V
.begin(), 2), std::next(this->V
.begin(), 4));
350 this->TestPtrs
.erase(std::next(this->TestPtrs
.begin(), 2),
351 std::next(this->TestPtrs
.begin(), 4));
352 this->expectValues(this->V
, this->testArray(38));
353 this->V
.erase(std::next(this->V
.begin(), 5), std::next(this->V
.begin(), 10));
354 this->TestPtrs
.erase(std::next(this->TestPtrs
.begin(), 5),
355 std::next(this->TestPtrs
.begin(), 10));
356 this->expectValues(this->V
, this->testArray(33));
357 this->V
.erase(std::next(this->V
.begin(), 13), std::next(this->V
.begin(), 26));
358 this->TestPtrs
.erase(std::next(this->TestPtrs
.begin(), 13),
359 std::next(this->TestPtrs
.begin(), 26));
360 this->expectValues(this->V
, this->testArray(20));
361 this->V
.erase(std::next(this->V
.begin(), 7), this->V
.end());
362 this->expectValues(this->V
, this->testArray(7));
363 this->V
.erase(this->V
.begin(), this->V
.end());
364 this->expectValues(this->V
, this->testArray(0));
367 TYPED_TEST(TinyPtrVectorTest
, Insert
) {
368 this->V
.insert(this->V
.end(), this->TestPtrs
[0]);
369 this->expectValues(this->V
, this->testArray(1));
371 this->appendValues(this->V
, this->testArray(4));
372 this->expectValues(this->V
, this->testArray(4));
373 this->V
.insert(this->V
.end(), this->TestPtrs
[4]);
374 this->expectValues(this->V
, this->testArray(5));
375 this->V
.insert(this->V
.begin(), this->TestPtrs
[42]);
376 this->TestPtrs
.insert(this->TestPtrs
.begin(), this->TestPtrs
[42]);
377 this->expectValues(this->V
, this->testArray(6));
378 this->V
.insert(std::next(this->V
.begin(), 3), this->TestPtrs
[43]);
379 this->TestPtrs
.insert(std::next(this->TestPtrs
.begin(), 3),
381 this->expectValues(this->V
, this->testArray(7));
384 TYPED_TEST(TinyPtrVectorTest
, InsertRange
) {
385 this->V
.insert(this->V
.end(), this->TestPtrs
.begin(), this->TestPtrs
.begin());
386 this->expectValues(this->V
, this->testArray(0));
387 this->V
.insert(this->V
.begin(), this->TestPtrs
.begin(),
388 this->TestPtrs
.begin());
389 this->expectValues(this->V
, this->testArray(0));
390 this->V
.insert(this->V
.end(), this->TestPtrs
.end(), this->TestPtrs
.end());
391 this->expectValues(this->V
, this->testArray(0));
392 this->V
.insert(this->V
.end(), this->TestPtrs
.begin(),
393 std::next(this->TestPtrs
.begin()));
394 this->expectValues(this->V
, this->testArray(1));
396 this->V
.insert(this->V
.end(), this->TestPtrs
.begin(),
397 std::next(this->TestPtrs
.begin(), 2));
398 this->expectValues(this->V
, this->testArray(2));
400 this->V
.insert(this->V
.end(), this->TestPtrs
.begin(),
401 std::next(this->TestPtrs
.begin(), 42));
402 this->expectValues(this->V
, this->testArray(42));
404 this->V
.insert(this->V
.end(),
405 std::next(this->TestPtrs
.begin(), 5),
406 std::next(this->TestPtrs
.begin(), 13));
407 this->V
.insert(this->V
.begin(),
408 std::next(this->TestPtrs
.begin(), 0),
409 std::next(this->TestPtrs
.begin(), 3));
410 this->V
.insert(std::next(this->V
.begin(), 2),
411 std::next(this->TestPtrs
.begin(), 2),
412 std::next(this->TestPtrs
.begin(), 4));
413 this->V
.erase(std::next(this->V
.begin(), 4));
414 this->V
.insert(std::next(this->V
.begin(), 4),
415 std::next(this->TestPtrs
.begin(), 4),
416 std::next(this->TestPtrs
.begin(), 5));
417 this->expectValues(this->V
, this->testArray(13));
422 TEST(TinyPtrVectorTest
, SingleEltCtorTest
) {
424 TinyPtrVector
<int *> V(&v
);
426 EXPECT_TRUE(V
.size() == 1);
427 EXPECT_FALSE(V
.empty());
428 EXPECT_TRUE(V
.front() == &v
);
431 TEST(TinyPtrVectorTest
, ArrayRefCtorTest
) {
433 std::vector
<int *> data
;
435 for (unsigned i
= 0, e
= 128; i
!= e
; ++i
) {
436 data_array
[i
] = 324 - int(i
);
437 data
.push_back(&data_array
[i
]);
440 TinyPtrVector
<int *> V(data
);
441 EXPECT_TRUE(V
.size() == 128);
442 EXPECT_FALSE(V
.empty());
443 for (unsigned i
= 0, e
= 128; i
!= e
; ++i
) {
444 EXPECT_TRUE(V
[i
] == data
[i
]);
448 TEST(TinyPtrVectorTest
, MutableArrayRefTest
) {
450 std::vector
<int *> data
;
452 for (unsigned i
= 0, e
= 128; i
!= e
; ++i
) {
453 data_array
[i
] = 324 - int(i
);
454 data
.push_back(&data_array
[i
]);
457 TinyPtrVector
<int *> V(data
);
458 EXPECT_TRUE(V
.size() == 128);
459 EXPECT_FALSE(V
.empty());
461 MutableArrayRef
<int *> mut_array
= V
;
462 for (unsigned i
= 0, e
= 128; i
!= e
; ++i
) {
463 EXPECT_TRUE(mut_array
[i
] == data
[i
]);
464 mut_array
[i
] = 324 + mut_array
[i
];
465 EXPECT_TRUE(mut_array
[i
] == (324 + data
[i
]));