Bug 1913111 - mfbt: Add HashTable::swap. r=glandium
I'm replacing a usage of Vector with HashMap, and I need the equivalent of Vector::swap for HashMap. Differential Revision: https://phabricator.services.mozilla.com/D231455
This commit is contained in:
@@ -180,6 +180,9 @@ class HashMap {
|
||||
HashMap(HashMap&& aRhs) = default;
|
||||
HashMap& operator=(HashMap&& aRhs) = default;
|
||||
|
||||
// Swap the contents of this hash map with another.
|
||||
void swap(HashMap& aOther) { mImpl.swap(aOther.mImpl); }
|
||||
|
||||
// -- Status and sizing ----------------------------------------------------
|
||||
|
||||
// The map's current generation.
|
||||
@@ -477,6 +480,9 @@ class HashSet {
|
||||
HashSet(HashSet&& aRhs) = default;
|
||||
HashSet& operator=(HashSet&& aRhs) = default;
|
||||
|
||||
// Swap the contents of this hash set with another.
|
||||
void swap(HashSet& aOther) { mImpl.swap(aOther.mImpl); }
|
||||
|
||||
// -- Status and sizing ----------------------------------------------------
|
||||
|
||||
// The set's current generation.
|
||||
@@ -1558,6 +1564,29 @@ class HashTable : private AllocPolicy {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(HashTable& aOther) {
|
||||
ReentrancyGuard g1(*this);
|
||||
ReentrancyGuard g2(aOther);
|
||||
|
||||
// Manual swap of generation because it's a bitfield
|
||||
uint64_t generation = mGen;
|
||||
mGen = aOther.mGen;
|
||||
aOther.mGen = generation;
|
||||
|
||||
// Manual swap of hashShift because it's a bitfield
|
||||
uint64_t hashShift = mHashShift;
|
||||
mHashShift = aOther.mHashShift;
|
||||
aOther.mHashShift = hashShift;
|
||||
|
||||
std::swap(mTable, aOther.mTable);
|
||||
std::swap(mEntryCount, aOther.mEntryCount);
|
||||
std::swap(mRemovedCount, aOther.mRemovedCount);
|
||||
#ifdef DEBUG
|
||||
std::swap(mMutationCount, aOther.mMutationCount);
|
||||
std::swap(mEntered, aOther.mEntered);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
void moveFrom(HashTable& aRhs) {
|
||||
mGen = aRhs.mGen;
|
||||
|
||||
@@ -32,6 +32,42 @@ void TestMoveConstructor() {
|
||||
MOZ_RELEASE_ASSERT(!map.count());
|
||||
}
|
||||
|
||||
void CheckSwapMap1(const mozilla::HashMap<int, int>& map1) {
|
||||
MOZ_RELEASE_ASSERT(map1.count() == 2);
|
||||
MOZ_RELEASE_ASSERT(!map1.empty());
|
||||
MOZ_RELEASE_ASSERT(!map1.lookup(3));
|
||||
MOZ_RELEASE_ASSERT(!map1.lookup(4));
|
||||
MOZ_RELEASE_ASSERT(map1.lookup(1)->value() == 10);
|
||||
MOZ_RELEASE_ASSERT(map1.lookup(2)->value() == 20);
|
||||
}
|
||||
|
||||
void CheckSwapMap2(const mozilla::HashMap<int, int>& map2) {
|
||||
MOZ_RELEASE_ASSERT(map2.count() == 2);
|
||||
MOZ_RELEASE_ASSERT(!map2.empty());
|
||||
MOZ_RELEASE_ASSERT(!map2.lookup(1));
|
||||
MOZ_RELEASE_ASSERT(!map2.lookup(2));
|
||||
MOZ_RELEASE_ASSERT(map2.lookup(3)->value() == 30);
|
||||
MOZ_RELEASE_ASSERT(map2.lookup(4)->value() == 40);
|
||||
}
|
||||
|
||||
void TestSwap() {
|
||||
using namespace mozilla;
|
||||
|
||||
HashMap<int, int> map1;
|
||||
MOZ_RELEASE_ASSERT(map1.putNew(1, 10));
|
||||
MOZ_RELEASE_ASSERT(map1.putNew(2, 20));
|
||||
CheckSwapMap1(map1);
|
||||
|
||||
HashMap<int, int> map2;
|
||||
MOZ_RELEASE_ASSERT(map2.putNew(3, 30));
|
||||
MOZ_RELEASE_ASSERT(map2.putNew(4, 40));
|
||||
CheckSwapMap2(map2);
|
||||
|
||||
map1.swap(map2);
|
||||
CheckSwapMap2(map1);
|
||||
CheckSwapMap1(map2);
|
||||
}
|
||||
|
||||
enum SimpleEnum { SIMPLE_1, SIMPLE_2 };
|
||||
|
||||
enum class ClassEnum : int {
|
||||
|
||||
Reference in New Issue
Block a user