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"
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
*>
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
)
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;
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,
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.
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
;
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
>
75 ImplCycleCollectionUnlink(nsRefPtrHashtable
<K
, T
>& aField
)
80 template<typename K
, typename T
>
82 ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback
& aCallback
,
83 nsRefPtrHashtable
<K
, T
>& aField
,
87 nsBaseHashtableCCTraversalData
userData(aCallback
, aName
, aFlags
);
89 aField
.EnumerateRead(ImplCycleCollectionTraverse_EnumFunc
<typename
K::KeyType
, T
*>,
94 // nsRefPtrHashtable definitions
97 template<class KeyClass
, class RefPtr
>
99 nsRefPtrHashtable
<KeyClass
, RefPtr
>::Get(KeyType aKey
,
100 UserDataType
* aRefPtr
) const
102 typename
base_type::EntryType
* ent
= this->GetEntry(aKey
);
106 *aRefPtr
= ent
->mData
;
108 NS_IF_ADDREF(*aRefPtr
);
114 // if the key doesn't exist, set *aRefPtr to null
115 // so that it is a valid XPCOM getter
123 template<class KeyClass
, class RefPtr
>
125 nsRefPtrHashtable
<KeyClass
, RefPtr
>::GetWeak(KeyType aKey
, bool* aFound
) const
127 typename
base_type::EntryType
* ent
= this->GetEntry(aKey
);
137 // Key does not exist, return nullptr and set aFound to false
145 template<class KeyClass
, class RefPtr
>
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
>
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
);
172 template<class KeyClass
, class RefPtr
>
174 nsRefPtrHashtable
<KeyClass
, RefPtr
>::Remove(KeyType aKey
,
175 UserDataType
* aRefPtr
)
178 typename
base_type::EntryType
* ent
= this->GetEntry(aKey
);
181 ent
->mData
.forget(aRefPtr
);
186 // If the key doesn't exist, set *aRefPtr to null
187 // so that it is a valid XPCOM getter.
192 #endif // nsRefPtrHashtable_h__