Impressum nsTHashtable.h
Interaktion und PortierbarkeitC
/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// See the comment at the top of mfbt/HashTable.h for a comparison between // PLDHashTable and mozilla::HashTable.
nsTHashtableIteratorBase& operator=(nsTHashtableIteratorBase&& aOther) { // User-defined because the move assignment operator is deleted in // PLDHashtable::Iterator. returnoperator=(static_cast<const nsTHashtableIteratorBase&>(aOther));
}
nsTHashtableIteratorBase(const nsTHashtableIteratorBase& aOther)
: mIterator{aOther.mIterator.Clone()} {}
nsTHashtableIteratorBase& operator=(const nsTHashtableIteratorBase& aOther) { // Since PLDHashTable::Iterator has no assignment operator, we destroy and // recreate mIterator.
mIterator.~Iterator(); new (&mIterator) PLDHashTable::Iterator(aOther.mIterator.Clone()); return *this;
}
// STL-style iterators to allow the use in range-based for loops, e.g. template <typename T> class nsTHashtableEntryIterator : public nsTHashtableIteratorBase { friendclass nsTHashtable<std::remove_const_t<T>>;
public: using iterator_category = std::forward_iterator_tag; using value_type = T; using difference_type = int32_t; using pointer = value_type*; using reference = value_type&;
using iterator_type = nsTHashtableEntryIterator; using const_iterator_type = nsTHashtableEntryIterator<const T>;
using nsTHashtableIteratorBase::nsTHashtableIteratorBase;
template <typename EntryType> class nsTHashtableKeyIterator : public nsTHashtableIteratorBase { friendclass nsTHashtable<EntryType>;
public: using iterator_category = std::forward_iterator_tag; using value_type = const std::decay_t<typename EntryType::KeyType>; using difference_type = int32_t; using pointer = value_type*; using reference = value_type&;
using iterator_type = nsTHashtableKeyIterator; using const_iterator_type = nsTHashtableKeyIterator;
using nsTHashtableIteratorBase::nsTHashtableIteratorBase;
template <typename EntryType> class nsTHashtableKeyRange { public: using IteratorType = nsTHashtableKeyIterator<EntryType>; using iterator = IteratorType;
// Helper type which wraps the access to EntryType::ALLOW_MEMMOVE. This is done // to ensure that the MOZ_NEEDS_MEMMOVABLE_TYPE attribute is applied to the // entry if we're going to use FixedSizeEntryMover, performing extra // compile-time checks against the use of non-memmoveable types. template <class EntryType, bool = EntryType::ALLOW_MEMMOVE> struct MOZ_NEEDS_MEMMOVABLE_TYPE CheckAllowMemmove : std::true_type {}; template <class EntryType> struct CheckAllowMemmove<EntryType, false> : std::false_type {};
// Like PLDHashTable::MoveEntryStub, but specialized for fixed N (i.e. the size // of the entries in the hashtable). Saves a memory read to figure out the size // from the table and gives the compiler the opportunity to inline the memcpy. // // We define this outside of nsTHashtable so only one copy exists for every N, // rather than separate copies for every EntryType used with nsTHashtable. template <size_t N> staticvoid FixedSizeEntryMover(PLDHashTable*, const PLDHashEntryHdr* aFrom,
PLDHashEntryHdr* aTo) {
memcpy(aTo, aFrom, N);
}
} // namespace detail
/** *abaseclassfortemplatedhashtables. * *Clientswillrarelyneedtousethisclassdirectly.Checkthederived *classesfirst,toseeiftheywillmeetyourneeds. * *@paramEntryTypethetemplatedentry-typeclassthatismanagedbythe *hashtable.<code>EntryType</code>mustextendthefollowingdeclaration, *and<strong>mustnotdeclareanyvirtualfunctionsorderivefromclasses *withvirtualfunctions.</strong>Anyvtablepointerwouldbreakthe *PLDHashTablecode. *<pre>classEntryType:publicPLDHashEntryHdr *{ *public:orfriendnsTHashtable<EntryType>; *// KeyType is what we use when Get()ing or Put()ing this entry *// this should either be a simple datatype (uint32_t, nsISupports*) or *// a const reference (const nsAString&) *typedefsomethingKeyType; *// KeyTypePointer is the pointer-version of KeyType, because *// PLDHashTable.h requires keys to cast to <code>const void*</code> *typedefconstsomething*KeyTypePointer; * *EntryType(KeyTypePointeraKey); * *// A copy or C++11 Move constructor must be defined, even if *// AllowMemMove() == true, otherwise you will cause link errors. *EntryType(constEntryType&aEnt);// Either this... *EntryType(EntryType&&aEnt);// ...or this * *// the destructor must be defined... or you will cause link errors! *~EntryType(); * *// KeyEquals(): does this entry match this key? *boolKeyEquals(KeyTypePointeraKey)const; * *// KeyToPointer(): Convert KeyType to KeyTypePointer *staticKeyTypePointerKeyToPointer(KeyTypeaKey); * *// HashKey(): calculate the hash number *staticPLDHashNumberHashKey(KeyTypePointeraKey); * *// ALLOW_MEMMOVE can we move this class with memmove(), or do we have *// to use the copy constructor? *enum{ALLOW_MEMMOVE=true/false}; *}</pre> * *@seensInterfaceHashtable *@seensClassHashtable *@seensTHashMap *@author"BenjaminSmedberg<bsmedberg@covad.net>"
*/
template <class EntryType> class MOZ_NEEDS_NO_VTABLE_TYPE nsTHashtable { typedef mozilla::fallible_t fallible_t;
static_assert(std::is_pointer_v<typename EntryType::KeyTypePointer>, "KeyTypePointer should be a pointer");
public: // Separate constructors instead of default aInitLength parameter since // otherwise the default no-arg constructor isn't found.
constexpr nsTHashtable()
: mTable(&sOps, sizeof(EntryType), PLDHashTable::kDefaultInitialLength) {} explicit nsTHashtable(uint32_t aInitLength)
: mTable(&sOps, sizeof(EntryType), aInitLength) {}
// This is an iterator that also allows entry removal. Example usage: // // for (auto iter = table.Iter(); !iter.Done(); iter.Next()) { // Entry* entry = iter.Get(); // // ... do stuff with |entry| ... // // ... possibly call iter.Remove() once ... // } // class Iterator final : public ConstIterator { public: using ConstIterator::ConstIterator;
private: // copy constructor, not implemented
nsTHashtable(nsTHashtable<EntryType>& aToCopy) = delete;
static constexpr PLDHashTableOps sOps{
.hashKey = s_HashKey,
.matchEntry = s_MatchEntry, // We intentionally indirect the access of ALLOW_MEMMOVE through // CheckAllowMemmove to perform some additional static analysis.
.moveEntry = ::detail::CheckAllowMemmove<EntryType>::value
? ::detail::FixedSizeEntryMover<sizeof(EntryType)>
: s_CopyEntry, // Simplify hashtable clearing in case our entries are trivially // destructible.
.clearEntry =
std::is_trivially_destructible_v<EntryType> ? nullptr : s_ClearEntry, // We don't use a generic initEntry hook because we want to allow // initialization of data members defined in derived classes directly // in the entry constructor (for example when a member can't be // default constructed).
.initEntry = nullptr};
// We play games with reinterpret_cast'ing between these two classes, so // try to ensure that playing said games is reasonable.
static_assert(sizeof(nsPtrHashKey<T>) == sizeof(::detail::VoidPtrHashKey), "hash keys must be the same size");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.