From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- xpcom/glue/nsClassHashtable.h | 140 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 xpcom/glue/nsClassHashtable.h (limited to 'xpcom/glue/nsClassHashtable.h') diff --git a/xpcom/glue/nsClassHashtable.h b/xpcom/glue/nsClassHashtable.h new file mode 100644 index 000000000..53ca5676b --- /dev/null +++ b/xpcom/glue/nsClassHashtable.h @@ -0,0 +1,140 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsClassHashtable_h__ +#define nsClassHashtable_h__ + +#include "mozilla/Move.h" +#include "nsBaseHashtable.h" +#include "nsHashKeys.h" +#include "nsAutoPtr.h" + +/** + * templated hashtable class maps keys to C++ object pointers. + * See nsBaseHashtable for complete declaration. + * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h + * for a complete specification. + * @param Class the class-type being wrapped + * @see nsInterfaceHashtable, nsClassHashtable + */ +template +class nsClassHashtable + : public nsBaseHashtable, T*> +{ +public: + typedef typename KeyClass::KeyType KeyType; + typedef T* UserDataType; + typedef nsBaseHashtable, T*> base_type; + + using base_type::IsEmpty; + + nsClassHashtable() {} + explicit nsClassHashtable(uint32_t aInitLength) + : nsBaseHashtable, T*>(aInitLength) + { + } + + /** + * Looks up aKey in the hash table. If it doesn't exist a new object of + * KeyClass will be created (using the arguments provided) and then returned. + */ + template + UserDataType LookupOrAdd(KeyType aKey, Args&&... aConstructionArgs); + + /** + * @copydoc nsBaseHashtable::Get + * @param aData if the key doesn't exist, pData will be set to nullptr. + */ + bool Get(KeyType aKey, UserDataType* aData) const; + + /** + * @copydoc nsBaseHashtable::Get + * @returns nullptr if the key is not present. + */ + UserDataType Get(KeyType aKey) const; + + /** + * Remove the entry for the given key from the hashtable and return it in + * aOut. If the key is not in the hashtable, aOut's pointer is set to + * nullptr. + * + * Normally, an entry is deleted when it's removed from an nsClassHashtable, + * but this function transfers ownership of the entry back to the caller + * through aOut -- the entry will be deleted when aOut goes out of scope. + * + * @param aKey the key to get and remove from the hashtable + */ + void RemoveAndForget(KeyType aKey, nsAutoPtr& aOut); +}; + +// +// nsClassHashtable definitions +// + +template +template +T* +nsClassHashtable::LookupOrAdd(KeyType aKey, + Args&&... aConstructionArgs) +{ + typename base_type::EntryType* ent = this->PutEntry(aKey); + if (!ent->mData) { + ent->mData = new T(mozilla::Forward(aConstructionArgs)...); + } + return ent->mData; +} + +template +bool +nsClassHashtable::Get(KeyType aKey, T** aRetVal) const +{ + typename base_type::EntryType* ent = this->GetEntry(aKey); + + if (ent) { + if (aRetVal) { + *aRetVal = ent->mData; + } + + return true; + } + + if (aRetVal) { + *aRetVal = nullptr; + } + + return false; +} + +template +T* +nsClassHashtable::Get(KeyType aKey) const +{ + typename base_type::EntryType* ent = this->GetEntry(aKey); + if (!ent) { + return nullptr; + } + + return ent->mData; +} + +template +void +nsClassHashtable::RemoveAndForget(KeyType aKey, nsAutoPtr& aOut) +{ + aOut = nullptr; + + typename base_type::EntryType* ent = this->GetEntry(aKey); + if (!ent) { + return; + } + + // Transfer ownership from ent->mData into aOut. + aOut = mozilla::Move(ent->mData); + + this->Remove(aKey); +} + +#endif // nsClassHashtable_h__ -- cgit v1.2.3