1 //===- llvm/unittest/ADT/SmallPtrSetTest.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 // SmallPtrSet unit tests.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/ADT/SmallPtrSet.h"
14 #include "llvm/ADT/PointerIntPair.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/Support/PointerLikeTypeTraits.h"
17 #include "gmock/gmock.h"
18 #include "gtest/gtest.h"
21 using testing::UnorderedElementsAre
;
23 TEST(SmallPtrSetTest
, Assignment
) {
25 for (int i
= 0; i
< 8; ++i
)
28 SmallPtrSet
<int *, 4> s1
= {&buf
[0], &buf
[1]};
29 SmallPtrSet
<int *, 4> s2
;
30 (s2
= s1
).insert(&buf
[2]);
32 // Self assign as well.
33 (s2
= static_cast<SmallPtrSet
<int *, 4> &>(s2
)).insert(&buf
[3]);
36 EXPECT_EQ(4U, s1
.size());
37 for (int i
= 0; i
< 8; ++i
)
39 EXPECT_TRUE(s1
.count(&buf
[i
]));
41 EXPECT_FALSE(s1
.count(&buf
[i
]));
43 // Assign and insert with initializer lists, and ones that contain both
44 // duplicates and out-of-order elements.
45 (s2
= {&buf
[6], &buf
[7], &buf
[6]}).insert({&buf
[5], &buf
[4]});
46 for (int i
= 0; i
< 8; ++i
)
48 EXPECT_FALSE(s2
.count(&buf
[i
]));
50 EXPECT_TRUE(s2
.count(&buf
[i
]));
53 TEST(SmallPtrSetTest
, GrowthTest
) {
56 for(i
=0; i
<8; ++i
) buf
[i
]=0;
59 SmallPtrSet
<int *, 4> s
;
60 typedef SmallPtrSet
<int *, 4>::iterator iter
;
66 EXPECT_EQ(4U, s
.size());
69 for(iter I
=s
.begin(), E
=s
.end(); I
!=E
; ++I
, ++i
)
73 EXPECT_EQ(i
<4?1:0,buf
[i
]);
81 for(iter I
=s
.begin(), E
=s
.end(); I
!=E
; ++I
, ++i
)
88 EXPECT_EQ(4U, s
.size());
91 for(iter I
=s
.begin(), E
=s
.end(); I
!=E
; ++I
, ++i
)
95 EXPECT_EQ(i
<4?3:1,buf
[i
]);
98 for(i
=0; i
<8; ++i
) buf
[i
]=0;
99 for(i
=0; i
<128; ++i
) s
.insert(&buf
[i
%8]); // test repeated entires
100 EXPECT_EQ(8U, s
.size());
101 for(iter I
=s
.begin(), E
=s
.end(); I
!=E
; ++I
, ++i
)
107 TEST(SmallPtrSetTest
, CopyAndMoveTest
) {
109 for (int i
= 0; i
< 8; ++i
)
112 SmallPtrSet
<int *, 4> s1
;
117 EXPECT_EQ(4U, s1
.size());
118 for (int i
= 0; i
< 8; ++i
)
120 EXPECT_TRUE(s1
.count(&buf
[i
]));
122 EXPECT_FALSE(s1
.count(&buf
[i
]));
124 SmallPtrSet
<int *, 4> s2(s1
);
125 EXPECT_EQ(4U, s2
.size());
126 for (int i
= 0; i
< 8; ++i
)
128 EXPECT_TRUE(s2
.count(&buf
[i
]));
130 EXPECT_FALSE(s2
.count(&buf
[i
]));
133 EXPECT_EQ(4U, s1
.size());
134 EXPECT_EQ(4U, s2
.size());
135 for (int i
= 0; i
< 8; ++i
)
137 EXPECT_TRUE(s1
.count(&buf
[i
]));
139 EXPECT_FALSE(s1
.count(&buf
[i
]));
141 SmallPtrSet
<int *, 4> s3(std::move(s1
));
142 EXPECT_EQ(4U, s3
.size());
143 EXPECT_TRUE(s1
.empty());
144 for (int i
= 0; i
< 8; ++i
)
146 EXPECT_TRUE(s3
.count(&buf
[i
]));
148 EXPECT_FALSE(s3
.count(&buf
[i
]));
150 // Move assign into the moved-from object. Also test move of a non-small
157 EXPECT_EQ(8U, s1
.size());
158 EXPECT_TRUE(s3
.empty());
159 for (int i
= 0; i
< 8; ++i
)
160 EXPECT_TRUE(s1
.count(&buf
[i
]));
162 // Copy assign into a moved-from object.
164 EXPECT_EQ(8U, s3
.size());
165 EXPECT_EQ(8U, s1
.size());
166 for (int i
= 0; i
< 8; ++i
)
167 EXPECT_TRUE(s3
.count(&buf
[i
]));
170 TEST(SmallPtrSetTest
, SwapTest
) {
173 SmallPtrSet
<int *, 2> a
;
174 SmallPtrSet
<int *, 2> b
;
180 EXPECT_EQ(2U, a
.size());
181 EXPECT_EQ(1U, b
.size());
182 EXPECT_TRUE(a
.count(&buf
[0]));
183 EXPECT_TRUE(a
.count(&buf
[1]));
184 EXPECT_FALSE(a
.count(&buf
[2]));
185 EXPECT_FALSE(a
.count(&buf
[3]));
186 EXPECT_FALSE(b
.count(&buf
[0]));
187 EXPECT_FALSE(b
.count(&buf
[1]));
188 EXPECT_TRUE(b
.count(&buf
[2]));
189 EXPECT_FALSE(b
.count(&buf
[3]));
193 EXPECT_EQ(1U, a
.size());
194 EXPECT_EQ(2U, b
.size());
195 EXPECT_FALSE(a
.count(&buf
[0]));
196 EXPECT_FALSE(a
.count(&buf
[1]));
197 EXPECT_TRUE(a
.count(&buf
[2]));
198 EXPECT_FALSE(a
.count(&buf
[3]));
199 EXPECT_TRUE(b
.count(&buf
[0]));
200 EXPECT_TRUE(b
.count(&buf
[1]));
201 EXPECT_FALSE(b
.count(&buf
[2]));
202 EXPECT_FALSE(b
.count(&buf
[3]));
207 EXPECT_EQ(3U, a
.size());
208 EXPECT_EQ(1U, b
.size());
209 EXPECT_TRUE(a
.count(&buf
[0]));
210 EXPECT_TRUE(a
.count(&buf
[1]));
211 EXPECT_FALSE(a
.count(&buf
[2]));
212 EXPECT_TRUE(a
.count(&buf
[3]));
213 EXPECT_FALSE(b
.count(&buf
[0]));
214 EXPECT_FALSE(b
.count(&buf
[1]));
215 EXPECT_TRUE(b
.count(&buf
[2]));
216 EXPECT_FALSE(b
.count(&buf
[3]));
220 EXPECT_EQ(1U, a
.size());
221 EXPECT_EQ(3U, b
.size());
222 EXPECT_FALSE(a
.count(&buf
[0]));
223 EXPECT_FALSE(a
.count(&buf
[1]));
224 EXPECT_TRUE(a
.count(&buf
[2]));
225 EXPECT_FALSE(a
.count(&buf
[3]));
226 EXPECT_TRUE(b
.count(&buf
[0]));
227 EXPECT_TRUE(b
.count(&buf
[1]));
228 EXPECT_FALSE(b
.count(&buf
[2]));
229 EXPECT_TRUE(b
.count(&buf
[3]));
237 EXPECT_EQ(3U, a
.size());
238 EXPECT_EQ(4U, b
.size());
239 EXPECT_TRUE(b
.count(&buf
[2]));
240 EXPECT_TRUE(b
.count(&buf
[4]));
241 EXPECT_TRUE(b
.count(&buf
[5]));
242 EXPECT_TRUE(b
.count(&buf
[6]));
243 EXPECT_TRUE(a
.count(&buf
[0]));
244 EXPECT_TRUE(a
.count(&buf
[1]));
245 EXPECT_TRUE(a
.count(&buf
[3]));
248 // Verify that dereferencing and iteration work.
249 TEST(SmallPtrSetTest
, dereferenceAndIterate
) {
250 int Ints
[] = {0, 1, 2, 3, 4, 5, 6, 7};
251 SmallPtrSet
<const int *, 4> S
;
252 for (int &I
: Ints
) {
253 EXPECT_EQ(&I
, *S
.insert(&I
).first
);
254 EXPECT_EQ(&I
, *S
.find(&I
));
257 // Iterate from each and count how many times each element is found.
258 int Found
[sizeof(Ints
)/sizeof(int)] = {0};
260 for (auto F
= S
.find(&I
), E
= S
.end(); F
!= E
; ++F
)
263 // Sort. We should hit the first element just once and the final element N
266 for (auto F
= std::begin(Found
), E
= std::end(Found
); F
!= E
; ++F
)
267 EXPECT_EQ(F
- Found
+ 1, *F
);
270 // Verify that const pointers work for count and find even when the underlying
271 // SmallPtrSet is not for a const pointer type.
272 TEST(SmallPtrSetTest
, ConstTest
) {
273 SmallPtrSet
<int *, 8> IntSet
;
278 EXPECT_EQ(IntSet
.count(B
), 1u);
279 EXPECT_EQ(IntSet
.count(C
), 1u);
280 EXPECT_TRUE(IntSet
.contains(B
));
281 EXPECT_TRUE(IntSet
.contains(C
));
284 // Verify that we automatically get the const version of PointerLikeTypeTraits
285 // filled in for us, even for a non-pointer type
286 using TestPair
= PointerIntPair
<int *, 1>;
288 TEST(SmallPtrSetTest
, ConstNonPtrTest
) {
289 SmallPtrSet
<TestPair
, 8> IntSet
;
291 TestPair
Pair(&A
[0], 1);
293 EXPECT_EQ(IntSet
.count(Pair
), 1u);
294 EXPECT_TRUE(IntSet
.contains(Pair
));
297 // Test equality comparison.
298 TEST(SmallPtrSetTest
, EqualityComparison
) {
300 for (int i
= 0; i
< 3; ++i
)
303 SmallPtrSet
<int *, 1> a
;
307 SmallPtrSet
<int *, 2> b
;
311 SmallPtrSet
<int *, 3> c
;
315 SmallPtrSet
<int *, 4> d
;
318 SmallPtrSet
<int *, 5> e
;
335 TEST(SmallPtrSetTest
, Contains
) {
336 SmallPtrSet
<int *, 2> Set
;
337 int buf
[4] = {0, 11, 22, 11};
338 EXPECT_FALSE(Set
.contains(&buf
[0]));
339 EXPECT_FALSE(Set
.contains(&buf
[1]));
343 EXPECT_TRUE(Set
.contains(&buf
[0]));
344 EXPECT_TRUE(Set
.contains(&buf
[1]));
345 EXPECT_FALSE(Set
.contains(&buf
[3]));
348 EXPECT_TRUE(Set
.contains(&buf
[0]));
349 EXPECT_TRUE(Set
.contains(&buf
[1]));
350 EXPECT_FALSE(Set
.contains(&buf
[3]));
353 EXPECT_TRUE(Set
.contains(&buf
[0]));
354 EXPECT_FALSE(Set
.contains(&buf
[1]));
358 EXPECT_TRUE(Set
.contains(&buf
[0]));
359 EXPECT_TRUE(Set
.contains(&buf
[1]));
360 EXPECT_TRUE(Set
.contains(&buf
[2]));
363 TEST(SmallPtrSetTest
, InsertIterator
) {
364 SmallPtrSet
<int *, 5> Set
;
365 int Vals
[5] = {11, 22, 33, 44, 55};
366 int *Buf
[5] = {&Vals
[0], &Vals
[1], &Vals
[2], &Vals
[3], &Vals
[4]};
369 Set
.insert(Set
.begin(), Ptr
);
371 // Ensure that all of the values were copied into the set.
372 for (const auto *Ptr
: Buf
)
373 EXPECT_TRUE(Set
.contains(Ptr
));
376 TEST(SmallPtrSetTest
, RemoveIf
) {
377 SmallPtrSet
<int *, 5> Set
;
378 int Vals
[6] = {0, 1, 2, 3, 4, 5};
380 // Stay in small regime.
381 Set
.insert(&Vals
[0]);
382 Set
.insert(&Vals
[1]);
383 Set
.insert(&Vals
[2]);
384 Set
.insert(&Vals
[3]);
385 Set
.erase(&Vals
[0]); // Leave a tombstone.
387 // Remove odd elements.
388 bool Removed
= Set
.remove_if([](int *Ptr
) { return *Ptr
% 2 != 0; });
389 // We should only have element 2 left now.
390 EXPECT_TRUE(Removed
);
391 EXPECT_EQ(Set
.size(), 1u);
392 EXPECT_TRUE(Set
.contains(&Vals
[2]));
394 // Switch to big regime.
395 Set
.insert(&Vals
[0]);
396 Set
.insert(&Vals
[1]);
397 Set
.insert(&Vals
[3]);
398 Set
.insert(&Vals
[4]);
399 Set
.insert(&Vals
[5]);
400 Set
.erase(&Vals
[0]); // Leave a tombstone.
402 // Remove odd elements.
403 Removed
= Set
.remove_if([](int *Ptr
) { return *Ptr
% 2 != 0; });
404 // We should only have elements 2 and 4 left now.
405 EXPECT_TRUE(Removed
);
406 EXPECT_EQ(Set
.size(), 2u);
407 EXPECT_TRUE(Set
.contains(&Vals
[2]));
408 EXPECT_TRUE(Set
.contains(&Vals
[4]));
410 Removed
= Set
.remove_if([](int *Ptr
) { return false; });
411 EXPECT_FALSE(Removed
);
414 TEST(SmallPtrSetTest
, Reserve
) {
415 // Check that we don't do anything silly when using reserve().
416 SmallPtrSet
<int *, 4> Set
;
417 int Vals
[8] = {0, 1, 2, 3, 4, 5, 6, 7};
419 Set
.insert(&Vals
[0]);
421 // We shouldn't reallocate when this happens.
423 EXPECT_EQ(Set
.capacity(), 4u);
425 Set
.insert(&Vals
[1]);
426 Set
.insert(&Vals
[2]);
427 Set
.insert(&Vals
[3]);
429 // We shouldn't reallocate this time either.
431 EXPECT_EQ(Set
.capacity(), 4u);
432 EXPECT_EQ(Set
.size(), 4u);
434 UnorderedElementsAre(&Vals
[0], &Vals
[1], &Vals
[2], &Vals
[3]));
436 // Reserving further should lead to a reallocation. And matching the existing
437 // insertion approach, we immediately allocate up to 128 elements.
439 EXPECT_EQ(Set
.capacity(), 128u);
440 EXPECT_EQ(Set
.size(), 4u);
442 UnorderedElementsAre(&Vals
[0], &Vals
[1], &Vals
[2], &Vals
[3]));
444 // And we should be able to insert another two or three elements without
446 Set
.insert(&Vals
[4]);
447 Set
.insert(&Vals
[5]);
449 // Calling a smaller reserve size should have no effect.
451 EXPECT_EQ(Set
.capacity(), 128u);
452 EXPECT_EQ(Set
.size(), 6u);
454 // Reserving zero should have no effect either.
456 EXPECT_EQ(Set
.capacity(), 128u);
457 EXPECT_EQ(Set
.size(), 6u);
458 EXPECT_THAT(Set
, UnorderedElementsAre(&Vals
[0], &Vals
[1], &Vals
[2], &Vals
[3], &Vals
[4], &Vals
[5]));