llvm.org GIT mirror llvm / 2945a32
SmallPtrSet: Provide a more efficient implementation of swap than the default triple-copy std::swap. This currently assumes that both sets have the same SmallSize to keep the implementation simple, a limitation that can be lifted if someone cares. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152143 91177308-0d34-0410-b5e6-96231b3b80d8 Benjamin Kramer 8 years ago
3 changed file(s) with 138 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
136136
137137 void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT.
138138 protected:
139 /// swap - Swaps the elements of two sets.
140 /// Note: This method assumes that both sets have the same small size.
141 void swap(SmallPtrSetImpl &RHS);
142
139143 void CopyFrom(const SmallPtrSetImpl &RHS);
140144 };
141145
286290 return *this;
287291 }
288292
293 /// swap - Swaps the elements of two sets.
294 void swap(SmallPtrSet &RHS) {
295 SmallPtrSetImpl::swap(RHS);
296 }
289297 };
290298
291299 }
292300
301 namespace std {
302 /// Implement std::swap in terms of SmallPtrSet swap.
303 template
304 inline void swap(llvm::SmallPtrSet &LHS, llvm::SmallPtrSet &RHS) {
305 LHS.swap(RHS);
306 }
307 }
308
293309 #endif
1313
1414 #include "llvm/ADT/SmallPtrSet.h"
1515 #include "llvm/Support/MathExtras.h"
16 #include
1617 #include
1718
1819 using namespace llvm;
222223 NumTombstones = RHS.NumTombstones;
223224 }
224225
226 void SmallPtrSetImpl::swap(SmallPtrSetImpl &RHS) {
227 if (this == &RHS) return;
228
229 // We can only avoid copying elements if neither set is small.
230 if (!this->isSmall() && !RHS.isSmall()) {
231 std::swap(this->CurArray, RHS.CurArray);
232 std::swap(this->CurArraySize, RHS.CurArraySize);
233 std::swap(this->NumElements, RHS.NumElements);
234 std::swap(this->NumTombstones, RHS.NumTombstones);
235 return;
236 }
237
238 // FIXME: From here on we assume that both sets have the same small size.
239
240 // If only RHS is small, copy the small elements into LHS and move the pointer
241 // from LHS to RHS.
242 if (!this->isSmall() && RHS.isSmall()) {
243 std::copy(RHS.SmallArray, RHS.SmallArray+RHS.NumElements, this->SmallArray);
244 std::swap(this->NumElements, RHS.NumElements);
245 std::swap(this->CurArraySize, RHS.CurArraySize);
246 RHS.CurArray = this->CurArray;
247 RHS.NumTombstones = this->NumTombstones;
248 this->CurArray = this->SmallArray;
249 this->NumTombstones = 0;
250 return;
251 }
252
253 // If only LHS is small, copy the small elements into RHS and move the pointer
254 // from RHS to LHS.
255 if (this->isSmall() && !RHS.isSmall()) {
256 std::copy(this->SmallArray, this->SmallArray+this->NumElements,
257 RHS.SmallArray);
258 std::swap(RHS.NumElements, this->NumElements);
259 std::swap(RHS.CurArraySize, this->CurArraySize);
260 this->CurArray = RHS.CurArray;
261 this->NumTombstones = RHS.NumTombstones;
262 RHS.CurArray = RHS.SmallArray;
263 RHS.NumTombstones = 0;
264 return;
265 }
266
267 // Both a small, just swap the small elements.
268 assert(this->isSmall() && RHS.isSmall());
269 assert(this->CurArraySize == RHS.CurArraySize);
270 unsigned MaxElems = std::max(this->NumElements, RHS.NumElements);
271 std::swap_ranges(this->SmallArray, this->SmallArray+MaxElems, RHS.SmallArray);
272 std::swap(this->NumElements, RHS.NumElements);
273 }
274
225275 SmallPtrSetImpl::~SmallPtrSetImpl() {
226276 if (!isSmall())
227277 free(CurArray);
0 //===- llvm/unittest/ADT/SmallPtrSetTest.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 // SmallPtrSet unit tests.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "gtest/gtest.h"
14 #include "llvm/ADT/SmallPtrSet.h"
15
16 using namespace llvm;
17
18 // SmallPtrSet swapping test.
19 TEST(SmallPtrSetTest, SwapTest) {
20 int buf[10];
21
22 SmallPtrSet a;
23 SmallPtrSet b;
24
25 a.insert(&buf[0]);
26 a.insert(&buf[1]);
27 b.insert(&buf[2]);
28
29 std::swap(a, b);
30
31 EXPECT_EQ(1U, a.size());
32 EXPECT_EQ(2U, b.size());
33 EXPECT_TRUE(a.count(&buf[2]));
34 EXPECT_TRUE(b.count(&buf[0]));
35 EXPECT_TRUE(b.count(&buf[1]));
36
37 b.insert(&buf[3]);
38 std::swap(a, b);
39
40 EXPECT_EQ(3U, a.size());
41 EXPECT_EQ(1U, b.size());
42 EXPECT_TRUE(a.count(&buf[0]));
43 EXPECT_TRUE(a.count(&buf[1]));
44 EXPECT_TRUE(a.count(&buf[3]));
45 EXPECT_TRUE(b.count(&buf[2]));
46
47 std::swap(a, b);
48
49 EXPECT_EQ(1U, a.size());
50 EXPECT_EQ(3U, b.size());
51 EXPECT_TRUE(a.count(&buf[2]));
52 EXPECT_TRUE(b.count(&buf[0]));
53 EXPECT_TRUE(b.count(&buf[1]));
54 EXPECT_TRUE(b.count(&buf[3]));
55
56 a.insert(&buf[4]);
57 a.insert(&buf[5]);
58 a.insert(&buf[6]);
59
60 std::swap(b, a);
61
62 EXPECT_EQ(3U, a.size());
63 EXPECT_EQ(4U, b.size());
64 EXPECT_TRUE(b.count(&buf[2]));
65 EXPECT_TRUE(b.count(&buf[4]));
66 EXPECT_TRUE(b.count(&buf[5]));
67 EXPECT_TRUE(b.count(&buf[6]));
68 EXPECT_TRUE(a.count(&buf[0]));
69 EXPECT_TRUE(a.count(&buf[1]));
70 EXPECT_TRUE(a.count(&buf[3]));
71 }