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/. */
6
7 #ifndef nsClassHashtable_h__
8 #define nsClassHashtable_h__
9
10 #include "mozilla/Move.h"
11 #include "nsBaseHashtable.h"
12 #include "nsHashKeys.h"
13 #include "nsAutoPtr.h"
14
15 /**
16 * templated hashtable class maps keys to C++ object pointers.
17 * See nsBaseHashtable for complete declaration.
18 * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
19 * for a complete specification.
20 * @param Class the class-type being wrapped
21 * @see nsInterfaceHashtable, nsClassHashtable
22 */
23 template<class KeyClass, class T>
24 class nsClassHashtable
25 : public nsBaseHashtable<KeyClass, nsAutoPtr<T>, T*>
26 {
27 public:
28 typedef typename KeyClass::KeyType KeyType;
29 typedef T* UserDataType;
30 typedef nsBaseHashtable<KeyClass, nsAutoPtr<T>, T*> base_type;
31
32 using base_type::IsEmpty;
33
nsClassHashtable()34 nsClassHashtable() {}
nsClassHashtable(uint32_t aInitLength)35 explicit nsClassHashtable(uint32_t aInitLength)
36 : nsBaseHashtable<KeyClass, nsAutoPtr<T>, T*>(aInitLength)
37 {
38 }
39
40 /**
41 * Looks up aKey in the hash table. If it doesn't exist a new object of
42 * KeyClass will be created (using the arguments provided) and then returned.
43 */
44 template<typename... Args>
45 UserDataType LookupOrAdd(KeyType aKey, Args&&... aConstructionArgs);
46
47 /**
48 * @copydoc nsBaseHashtable::Get
49 * @param aData if the key doesn't exist, pData will be set to nullptr.
50 */
51 bool Get(KeyType aKey, UserDataType* aData) const;
52
53 /**
54 * @copydoc nsBaseHashtable::Get
55 * @returns nullptr if the key is not present.
56 */
57 UserDataType Get(KeyType aKey) const;
58
59 /**
60 * Remove the entry for the given key from the hashtable and return it in
61 * aOut. If the key is not in the hashtable, aOut's pointer is set to
62 * nullptr.
63 *
64 * Normally, an entry is deleted when it's removed from an nsClassHashtable,
65 * but this function transfers ownership of the entry back to the caller
66 * through aOut -- the entry will be deleted when aOut goes out of scope.
67 *
68 * @param aKey the key to get and remove from the hashtable
69 */
70 void RemoveAndForget(KeyType aKey, nsAutoPtr<T>& aOut);
71 };
72
73 //
74 // nsClassHashtable definitions
75 //
76
77 template<class KeyClass, class T>
78 template<typename... Args>
79 T*
LookupOrAdd(KeyType aKey,Args &&...aConstructionArgs)80 nsClassHashtable<KeyClass, T>::LookupOrAdd(KeyType aKey,
81 Args&&... aConstructionArgs)
82 {
83 typename base_type::EntryType* ent = this->PutEntry(aKey);
84 if (!ent->mData) {
85 ent->mData = new T(mozilla::Forward<Args>(aConstructionArgs)...);
86 }
87 return ent->mData;
88 }
89
90 template<class KeyClass, class T>
91 bool
Get(KeyType aKey,T ** aRetVal)92 nsClassHashtable<KeyClass, T>::Get(KeyType aKey, T** aRetVal) const
93 {
94 typename base_type::EntryType* ent = this->GetEntry(aKey);
95
96 if (ent) {
97 if (aRetVal) {
98 *aRetVal = ent->mData;
99 }
100
101 return true;
102 }
103
104 if (aRetVal) {
105 *aRetVal = nullptr;
106 }
107
108 return false;
109 }
110
111 template<class KeyClass, class T>
112 T*
Get(KeyType aKey)113 nsClassHashtable<KeyClass, T>::Get(KeyType aKey) const
114 {
115 typename base_type::EntryType* ent = this->GetEntry(aKey);
116 if (!ent) {
117 return nullptr;
118 }
119
120 return ent->mData;
121 }
122
123 template<class KeyClass, class T>
124 void
RemoveAndForget(KeyType aKey,nsAutoPtr<T> & aOut)125 nsClassHashtable<KeyClass, T>::RemoveAndForget(KeyType aKey, nsAutoPtr<T>& aOut)
126 {
127 aOut = nullptr;
128
129 typename base_type::EntryType* ent = this->GetEntry(aKey);
130 if (!ent) {
131 return;
132 }
133
134 // Transfer ownership from ent->mData into aOut.
135 aOut = mozilla::Move(ent->mData);
136
137 this->Remove(aKey);
138 }
139
140 #endif // nsClassHashtable_h__
141