Bug 1139217 - Make js::HashSet<T> work with move-only T types; r=luke

This commit is contained in:
Nick Fitzgerald 2015-03-03 17:54:00 +01:00
Родитель 938b6f9559
Коммит 57951abfec
2 изменённых файлов: 51 добавлений и 1 удалений

Просмотреть файл

@ -1352,7 +1352,8 @@ class HashTable : private AllocPolicy
for (Entry *src = oldTable, *end = src + oldCap; src < end; ++src) {
if (src->isLive()) {
HashNumber hn = src->getKeyHash();
findFreeEntry(hn).setLive(hn, mozilla::Move(src->get()));
findFreeEntry(hn).setLive(
hn, mozilla::Move(const_cast<typename Entry::NonConstT&>(src->get())));
src->destroy();
}
}

Просмотреть файл

@ -287,3 +287,52 @@ BEGIN_TEST(testHashRekeyManualRemoval)
return true;
}
END_TEST(testHashRekeyManualRemoval)
// A type that is not copyable, only movable.
struct MoveOnlyType {
uint32_t val;
explicit MoveOnlyType(uint32_t val) : val(val) { }
MoveOnlyType(MoveOnlyType &&rhs) {
val = rhs.val;
}
MoveOnlyType &operator=(MoveOnlyType &&rhs) {
MOZ_ASSERT(&rhs != this);
this->~MoveOnlyType();
new(this) MoveOnlyType(mozilla::Move(rhs));
return *this;
}
struct HashPolicy {
typedef MoveOnlyType Lookup;
static js::HashNumber hash(const Lookup &lookup) {
return lookup.val;
}
static bool match(const MoveOnlyType &existing, const Lookup &lookup) {
return existing.val == lookup.val;
}
};
private:
MoveOnlyType(const MoveOnlyType &) = delete;
MoveOnlyType& operator=(const MoveOnlyType &) = delete;
};
BEGIN_TEST(testHashSetOfMoveOnlyType)
{
typedef js::HashSet<MoveOnlyType, MoveOnlyType::HashPolicy, js::SystemAllocPolicy> Set;
Set set;
set.init();
MoveOnlyType a(1);
set.put(mozilla::Move(a)); // This shouldn't generate a compiler error.
return true;
}
END_TEST(testHashSetOfMoveOnlyType)