Bumping manifests a=b2g-bump
[gecko.git] / xpcom / glue / nsRefPtrHashtable.h
blobdf9227893fdb904a20badfd0c1e5272df1d670a7
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef nsRefPtrHashtable_h__
8 #define nsRefPtrHashtable_h__
10 #include "nsBaseHashtable.h"
11 #include "nsHashKeys.h"
12 #include "nsAutoPtr.h"
14 /**
15 * templated hashtable class maps keys to reference pointers.
16 * See nsBaseHashtable for complete declaration.
17 * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
18 * for a complete specification.
19 * @param RefPtr the reference-type being wrapped
20 * @see nsDataHashtable, nsClassHashtable
22 template<class KeyClass, class RefPtr>
23 class nsRefPtrHashtable
24 : public nsBaseHashtable<KeyClass, nsRefPtr<RefPtr>, RefPtr*>
26 public:
27 typedef typename KeyClass::KeyType KeyType;
28 typedef RefPtr* UserDataType;
29 typedef nsBaseHashtable<KeyClass, nsRefPtr<RefPtr>, RefPtr*> base_type;
31 nsRefPtrHashtable() {}
32 explicit nsRefPtrHashtable(uint32_t aInitLength)
33 : nsBaseHashtable<KeyClass, nsRefPtr<RefPtr>, RefPtr*>(aInitLength)
37 /**
38 * @copydoc nsBaseHashtable::Get
39 * @param aData This is an XPCOM getter, so aData is already_addrefed.
40 * If the key doesn't exist, aData will be set to nullptr.
42 bool Get(KeyType aKey, UserDataType* aData) const;
44 /**
45 * Gets a weak reference to the hashtable entry.
46 * @param aFound If not nullptr, will be set to true if the entry is found,
47 * to false otherwise.
48 * @return The entry, or nullptr if not found. Do not release this pointer!
50 RefPtr* GetWeak(KeyType aKey, bool* aFound = nullptr) const;
52 // Overload Put, rather than overriding it.
53 using base_type::Put;
55 void Put(KeyType aKey, already_AddRefed<RefPtr> aData);
57 MOZ_WARN_UNUSED_RESULT bool Put(KeyType aKey, already_AddRefed<RefPtr> aData,
58 const mozilla::fallible_t&);
60 // Overload Remove, rather than overriding it.
61 using base_type::Remove;
63 /**
64 * Remove the data for the associated key, swapping the current value into
65 * pData, thereby avoiding calls to AddRef and Release.
66 * @param aKey the key to remove from the hashtable
67 * @param aData This is an XPCOM getter, so aData is already_addrefed.
68 * If the key doesn't exist, aData will be set to nullptr. Must be non-null.
70 bool Remove(KeyType aKey, UserDataType* aData);
73 template<typename K, typename T>
74 inline void
75 ImplCycleCollectionUnlink(nsRefPtrHashtable<K, T>& aField)
77 aField.Clear();
80 template<typename K, typename T>
81 inline void
82 ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
83 nsRefPtrHashtable<K, T>& aField,
84 const char* aName,
85 uint32_t aFlags = 0)
87 nsBaseHashtableCCTraversalData userData(aCallback, aName, aFlags);
89 aField.EnumerateRead(ImplCycleCollectionTraverse_EnumFunc<typename K::KeyType, T*>,
90 &userData);
94 // nsRefPtrHashtable definitions
97 template<class KeyClass, class RefPtr>
98 bool
99 nsRefPtrHashtable<KeyClass, RefPtr>::Get(KeyType aKey,
100 UserDataType* aRefPtr) const
102 typename base_type::EntryType* ent = this->GetEntry(aKey);
104 if (ent) {
105 if (aRefPtr) {
106 *aRefPtr = ent->mData;
108 NS_IF_ADDREF(*aRefPtr);
111 return true;
114 // if the key doesn't exist, set *aRefPtr to null
115 // so that it is a valid XPCOM getter
116 if (aRefPtr) {
117 *aRefPtr = nullptr;
120 return false;
123 template<class KeyClass, class RefPtr>
124 RefPtr*
125 nsRefPtrHashtable<KeyClass, RefPtr>::GetWeak(KeyType aKey, bool* aFound) const
127 typename base_type::EntryType* ent = this->GetEntry(aKey);
129 if (ent) {
130 if (aFound) {
131 *aFound = true;
134 return ent->mData;
137 // Key does not exist, return nullptr and set aFound to false
138 if (aFound) {
139 *aFound = false;
142 return nullptr;
145 template<class KeyClass, class RefPtr>
146 void
147 nsRefPtrHashtable<KeyClass, RefPtr>::Put(KeyType aKey,
148 already_AddRefed<RefPtr> aData)
150 if (!Put(aKey, mozilla::Move(aData), mozilla::fallible_t())) {
151 NS_ABORT_OOM(this->mTable.EntrySize() * this->mTable.EntryCount());
155 template<class KeyClass, class RefPtr>
156 bool
157 nsRefPtrHashtable<KeyClass, RefPtr>::Put(KeyType aKey,
158 already_AddRefed<RefPtr> aData,
159 const mozilla::fallible_t&)
161 typename base_type::EntryType* ent = this->PutEntry(aKey);
163 if (!ent) {
164 return false;
167 ent->mData = aData;
169 return true;
172 template<class KeyClass, class RefPtr>
173 bool
174 nsRefPtrHashtable<KeyClass, RefPtr>::Remove(KeyType aKey,
175 UserDataType* aRefPtr)
177 MOZ_ASSERT(aRefPtr);
178 typename base_type::EntryType* ent = this->GetEntry(aKey);
180 if (ent) {
181 ent->mData.forget(aRefPtr);
182 this->Remove(aKey);
183 return true;
186 // If the key doesn't exist, set *aRefPtr to null
187 // so that it is a valid XPCOM getter.
188 *aRefPtr = nullptr;
189 return false;
192 #endif // nsRefPtrHashtable_h__