Bug 1617542 - Make nsRefPtrHashtable::Put accept a RefPtr rvalue. r=froydnj

Differential Revision: https://phabricator.services.mozilla.com/D63838

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Simon Giesecke 2020-02-24 16:15:48 +00:00
Родитель 24ebaad98d
Коммит 51d21f99d6
2 изменённых файлов: 77 добавлений и 3 удалений

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

@ -58,6 +58,15 @@ class nsRefPtrHashtable
MOZ_MUST_USE bool Put(KeyType aKey, already_AddRefed<PtrType> aData,
const mozilla::fallible_t&);
template <typename U,
typename = std::enable_if_t<std::is_base_of_v<PtrType, U>>>
void Put(KeyType aKey, RefPtr<U>&& aData);
template <typename U,
typename = std::enable_if_t<std::is_base_of_v<PtrType, U>>>
MOZ_MUST_USE bool Put(KeyType aKey, RefPtr<U>&& aData,
const mozilla::fallible_t&);
/**
* Remove the entry associated with aKey (if any), optionally _moving_ its
* current value into *aData, thereby avoiding calls to AddRef and Release.
@ -148,14 +157,28 @@ PtrType* nsRefPtrHashtable<KeyClass, PtrType>::GetWeak(KeyType aKey,
template <class KeyClass, class PtrType>
void nsRefPtrHashtable<KeyClass, PtrType>::Put(
KeyType aKey, already_AddRefed<PtrType> aData) {
Put(aKey, RefPtr<PtrType>{aData});
}
template <class KeyClass, class PtrType>
bool nsRefPtrHashtable<KeyClass, PtrType>::Put(KeyType aKey,
already_AddRefed<PtrType> aData,
const mozilla::fallible_t&) {
return Put(aKey, RefPtr<PtrType>{aData}, mozilla::fallible);
}
template <class KeyClass, class PtrType>
template <typename U, typename>
void nsRefPtrHashtable<KeyClass, PtrType>::Put(KeyType aKey,
RefPtr<U>&& aData) {
if (!Put(aKey, std::move(aData), mozilla::fallible)) {
NS_ABORT_OOM(this->mTable.EntrySize() * this->mTable.EntryCount());
}
}
template <class KeyClass, class PtrType>
bool nsRefPtrHashtable<KeyClass, PtrType>::Put(KeyType aKey,
already_AddRefed<PtrType> aData,
template <typename U, typename>
bool nsRefPtrHashtable<KeyClass, PtrType>::Put(KeyType aKey, RefPtr<U>&& aData,
const mozilla::fallible_t&) {
typename base_type::EntryType* ent = this->PutEntry(aKey, mozilla::fallible);
@ -163,7 +186,7 @@ bool nsRefPtrHashtable<KeyClass, PtrType>::Put(KeyType aKey,
return false;
}
ent->SetData(aData);
ent->SetData(std::move(aData));
return true;
}

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

@ -9,6 +9,7 @@
#include "nsDataHashtable.h"
#include "nsInterfaceHashtable.h"
#include "nsClassHashtable.h"
#include "nsRefPtrHashtable.h"
#include "nsCOMPtr.h"
#include "nsISupports.h"
@ -37,6 +38,21 @@ class TestUniChar // for nsClassHashtable
uint32_t mWord;
};
class TestUniCharRefCounted // for nsRefPtrHashtable
{
public:
NS_INLINE_DECL_REFCOUNTING(TestUniCharRefCounted);
explicit TestUniCharRefCounted(uint32_t aWord) { mWord = aWord; }
uint32_t GetChar() const { return mWord; }
private:
~TestUniCharRefCounted() = default;
uint32_t mWord;
};
struct EntityNode {
const char* mStr; // never owns buffer
uint32_t mUnicode;
@ -657,3 +673,38 @@ TEST(Hashtables, ClassHashtable_LookupForAdd)
}
ASSERT_TRUE(0 == EntToUniClass.Count());
}
TEST(Hashtables, RefPtrHashtable)
{
// check a RefPtr-hashtable
nsRefPtrHashtable<nsCStringHashKey, TestUniCharRefCounted> EntToUniClass(
ENTITY_COUNT);
for (auto& entity : gEntities) {
EntToUniClass.Put(
nsDependentCString(entity.mStr),
mozilla::MakeRefPtr<TestUniCharRefCounted>(entity.mUnicode));
}
TestUniCharRefCounted* myChar;
for (auto& entity : gEntities) {
ASSERT_TRUE(EntToUniClass.Get(nsDependentCString(entity.mStr), &myChar));
}
ASSERT_FALSE(EntToUniClass.Get(NS_LITERAL_CSTRING("xxxx"), &myChar));
uint32_t count = 0;
for (auto iter = EntToUniClass.Iter(); !iter.Done(); iter.Next()) {
count++;
}
ASSERT_EQ(count, ENTITY_COUNT);
EntToUniClass.Clear();
count = 0;
for (auto iter = EntToUniClass.Iter(); !iter.Done(); iter.Next()) {
count++;
}
ASSERT_EQ(count, uint32_t(0));
}