diff --git a/xpcom/glue/nsBaseHashtable.h b/xpcom/glue/nsBaseHashtable.h index a892ca3a48e..94cf2511dd3 100644 --- a/xpcom/glue/nsBaseHashtable.h +++ b/xpcom/glue/nsBaseHashtable.h @@ -162,6 +162,7 @@ public: /** * enumerate entries in the hashtable, without allowing changes + * WARNING: this function is deprecated. Please use Iterator instead. * @param aEnumFunc enumeration callback * @param aUserArg passed unchanged to the EnumReadFunction */ @@ -196,8 +197,9 @@ public: void* aUserArg); /** - * enumerate entries in the hashtable, allowing changes. This - * functions write-locks the hashtable. + * enumerate entries in the hashtable, allowing changes. + * WARNING: this function is deprecated. Please use Iterator and/or + * MutatingIterator instead. * @param aEnumFunc enumeration callback * @param aUserArg passed unchanged to the EnumFunction */ @@ -218,6 +220,47 @@ public: return n; } + // This is an iterator that also allows entry removal. Example usage: + // + // for (auto iter = table.Iter(); !iter.Done(); iter.Next()) { + // const KeyType key = iter.GetKey(); + // const UserDataType data = iter.GetUserData(); + // // or + // const DataType& data = iter.GetData(); + // // ... do stuff with |key| and/or |data| ... + // // ... possibly call iter.Remove() once ... + // } + // + class Iterator : public PLDHashTable::Iterator + { + public: + typedef PLDHashTable::Iterator Base; + + explicit Iterator(nsBaseHashtable* aTable) : Base(&aTable->mTable) {} + Iterator(Iterator&& aOther) : Base(aOther.mTable) {} + ~Iterator() {} + + KeyType GetKey() const { return static_cast(Get())->GetKey(); } + UserDataType GetUserData() const + { + return static_cast(Get())->mData; + } + DataType& GetData() const { return static_cast(Get())->mData; } + + private: + Iterator() = delete; + Iterator(const Iterator&) = delete; + Iterator& operator=(const Iterator&) = delete; + Iterator& operator=(const Iterator&&) = delete; + }; + + Iterator Iter() { return Iterator(this); } + + Iterator ConstIter() const + { + return Iterator(const_cast(this)); + } + /** * reset the hashtable, removing all entries */ diff --git a/xpcom/glue/nsTHashtable.h b/xpcom/glue/nsTHashtable.h index 48246ea540d..61b78df4008 100644 --- a/xpcom/glue/nsTHashtable.h +++ b/xpcom/glue/nsTHashtable.h @@ -205,6 +205,7 @@ public: * a PL_DHASH_REMOVE return value from |aEnumFunc|, the table may be shrunk * at the end. Use RawRemoveEntry() instead if you wish to remove an entry * without possibly shrinking the table. + * WARNING: this function is deprecated. Please use Iterator instead. * @param enumFunc the Enumerator function to call * @param userArg a pointer to pass to the * Enumerator function @@ -227,6 +228,39 @@ public: return n; } + // 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 : public PLDHashTable::Iterator + { + public: + typedef PLDHashTable::Iterator Base; + + explicit Iterator(nsTHashtable* aTable) : Base(&aTable->mTable) {} + Iterator(Iterator&& aOther) : Base(aOther.mTable) {} + ~Iterator() {} + + EntryType* Get() const { return static_cast(Base::Get()); } + + private: + Iterator() = delete; + Iterator(const Iterator&) = delete; + Iterator& operator=(const Iterator&) = delete; + Iterator& operator=(const Iterator&&) = delete; + }; + + Iterator Iter() { return Iterator(this); } + + Iterator ConstIter() const + { + return Iterator(const_cast(this)); + } + /** * Remove all entries, return hashtable to "pristine" state. It's * conceptually the same as calling the destructor and then re-calling the