mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-14 07:31:53 +00:00
Add a copy constructor to StringMap
There is code under review that requires StringMap to have a copy constructor, and this makes StringMap more consistent with our other containers (like DenseMap) that have copy constructors. Differential Revision: http://reviews.llvm.org/D18506 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@264906 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dfdada0adb
commit
f5526fc013
@ -89,7 +89,8 @@ protected:
|
||||
/// table, returning it. If the key is not in the table, this returns null.
|
||||
StringMapEntryBase *RemoveKey(StringRef Key);
|
||||
|
||||
private:
|
||||
/// Allocate the table with the specified number of buckets and otherwise
|
||||
/// setup the map as empty.
|
||||
void init(unsigned Size);
|
||||
|
||||
public:
|
||||
@ -244,7 +245,39 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
// FIXME: Implement copy operations if/when they're needed.
|
||||
StringMap(const StringMap &RHS) :
|
||||
StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))),
|
||||
Allocator(RHS.Allocator) {
|
||||
if (RHS.empty())
|
||||
return;
|
||||
|
||||
// Allocate TheTable of the same size as RHS's TheTable, and set the
|
||||
// sentinel appropriately (and NumBuckets).
|
||||
init(RHS.NumBuckets);
|
||||
unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1),
|
||||
*RHSHashTable = (unsigned *)(RHS.TheTable + NumBuckets + 1);
|
||||
|
||||
NumItems = RHS.NumItems;
|
||||
NumTombstones = RHS.NumTombstones;
|
||||
for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
|
||||
MapEntryTy *Bucket = ((MapEntryTy**) RHS.TheTable)[I];
|
||||
if (!Bucket || Bucket == getTombstoneVal()) {
|
||||
TheTable[I] = Bucket;
|
||||
continue;
|
||||
}
|
||||
|
||||
TheTable[I] = MapEntryTy::Create(Bucket->getKey(), Allocator,
|
||||
Bucket->getValue());
|
||||
HashTable[I] = RHSHashTable[I];
|
||||
}
|
||||
|
||||
// Note that here we've copied everything from the RHS into this object,
|
||||
// tombstones included. We could, instead, have re-probed for each key to
|
||||
// instantiate this new object without any tombstone buckets. The
|
||||
// assumption here is that items are rarely deleted from most StringMaps,
|
||||
// and so tombstones are rare, so the cost of re-probing for all inputs is
|
||||
// not worthwhile.
|
||||
}
|
||||
|
||||
AllocatorTy &getAllocator() { return Allocator; }
|
||||
const AllocatorTy &getAllocator() const { return Allocator; }
|
||||
|
@ -157,6 +157,33 @@ TEST_F(StringMapTest, SmallFullMapTest) {
|
||||
EXPECT_EQ(5, Map.lookup("funf"));
|
||||
}
|
||||
|
||||
TEST_F(StringMapTest, CopyCtorTest) {
|
||||
llvm::StringMap<int> Map;
|
||||
|
||||
Map["eins"] = 1;
|
||||
Map["zwei"] = 2;
|
||||
Map["drei"] = 3;
|
||||
Map.erase("drei");
|
||||
Map.erase("eins");
|
||||
Map["veir"] = 4;
|
||||
Map["funf"] = 5;
|
||||
|
||||
EXPECT_EQ(3u, Map.size());
|
||||
EXPECT_EQ(0, Map.lookup("eins"));
|
||||
EXPECT_EQ(2, Map.lookup("zwei"));
|
||||
EXPECT_EQ(0, Map.lookup("drei"));
|
||||
EXPECT_EQ(4, Map.lookup("veir"));
|
||||
EXPECT_EQ(5, Map.lookup("funf"));
|
||||
|
||||
llvm::StringMap<int> Map2(Map);
|
||||
EXPECT_EQ(3u, Map2.size());
|
||||
EXPECT_EQ(0, Map2.lookup("eins"));
|
||||
EXPECT_EQ(2, Map2.lookup("zwei"));
|
||||
EXPECT_EQ(0, Map2.lookup("drei"));
|
||||
EXPECT_EQ(4, Map2.lookup("veir"));
|
||||
EXPECT_EQ(5, Map2.lookup("funf"));
|
||||
}
|
||||
|
||||
// A more complex iteration test.
|
||||
TEST_F(StringMapTest, IterationTest) {
|
||||
bool visited[100];
|
||||
|
Loading…
Reference in New Issue
Block a user