]>
Commit | Line | Data |
---|---|---|
b37bf2e1 | 1 | /* |
9dae56ea | 2 | * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
b37bf2e1 A |
3 | * |
4 | * This library is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU Library General Public | |
6 | * License as published by the Free Software Foundation; either | |
7 | * version 2 of the License, or (at your option) any later version. | |
8 | * | |
9 | * This library is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | * Library General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU Library General Public License | |
15 | * along with this library; see the file COPYING.LIB. If not, write to | |
16 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
17 | * Boston, MA 02110-1301, USA. | |
18 | * | |
19 | */ | |
20 | ||
21 | #ifndef WTF_HashMap_h | |
22 | #define WTF_HashMap_h | |
23 | ||
24 | #include "HashTable.h" | |
25 | ||
26 | namespace WTF { | |
27 | ||
28 | template<typename PairType> struct PairFirstExtractor; | |
29 | ||
30 | template<typename KeyArg, typename MappedArg, typename HashArg = typename DefaultHash<KeyArg>::Hash, | |
31 | typename KeyTraitsArg = HashTraits<KeyArg>, typename MappedTraitsArg = HashTraits<MappedArg> > | |
32 | class HashMap { | |
33 | private: | |
34 | typedef KeyTraitsArg KeyTraits; | |
35 | typedef MappedTraitsArg MappedTraits; | |
9dae56ea | 36 | typedef PairHashTraits<KeyTraits, MappedTraits> ValueTraits; |
b37bf2e1 A |
37 | |
38 | public: | |
39 | typedef typename KeyTraits::TraitType KeyType; | |
40 | typedef typename MappedTraits::TraitType MappedType; | |
41 | typedef typename ValueTraits::TraitType ValueType; | |
42 | ||
43 | private: | |
44 | typedef HashArg HashFunctions; | |
45 | ||
9dae56ea A |
46 | typedef HashTable<KeyType, ValueType, PairFirstExtractor<ValueType>, |
47 | HashFunctions, ValueTraits, KeyTraits> HashTableType; | |
b37bf2e1 A |
48 | |
49 | public: | |
50 | typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator; | |
51 | typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator; | |
52 | ||
b37bf2e1 A |
53 | void swap(HashMap&); |
54 | ||
55 | int size() const; | |
56 | int capacity() const; | |
57 | bool isEmpty() const; | |
58 | ||
59 | // iterators iterate over pairs of keys and values | |
60 | iterator begin(); | |
61 | iterator end(); | |
62 | const_iterator begin() const; | |
63 | const_iterator end() const; | |
64 | ||
65 | iterator find(const KeyType&); | |
66 | const_iterator find(const KeyType&) const; | |
67 | bool contains(const KeyType&) const; | |
68 | MappedType get(const KeyType&) const; | |
69 | ||
70 | // replaces value but not key if key is already present | |
71 | // return value is a pair of the iterator to the key location, | |
72 | // and a boolean that's true if a new value was actually added | |
73 | pair<iterator, bool> set(const KeyType&, const MappedType&); | |
74 | ||
75 | // does nothing if key is already present | |
76 | // return value is a pair of the iterator to the key location, | |
77 | // and a boolean that's true if a new value was actually added | |
78 | pair<iterator, bool> add(const KeyType&, const MappedType&); | |
79 | ||
80 | void remove(const KeyType&); | |
81 | void remove(iterator); | |
82 | void clear(); | |
83 | ||
84 | MappedType take(const KeyType&); // efficient combination of get with remove | |
85 | ||
86 | private: | |
87 | pair<iterator, bool> inlineAdd(const KeyType&, const MappedType&); | |
b37bf2e1 A |
88 | |
89 | HashTableType m_impl; | |
90 | }; | |
91 | ||
92 | template<typename PairType> struct PairFirstExtractor { | |
93 | static const typename PairType::first_type& extract(const PairType& p) { return p.first; } | |
94 | }; | |
95 | ||
9dae56ea A |
96 | template<typename ValueType, typename ValueTraits, typename HashFunctions> |
97 | struct HashMapTranslator { | |
b37bf2e1 A |
98 | typedef typename ValueType::first_type KeyType; |
99 | typedef typename ValueType::second_type MappedType; | |
b37bf2e1 A |
100 | |
101 | static unsigned hash(const KeyType& key) { return HashFunctions::hash(key); } | |
9dae56ea A |
102 | static bool equal(const KeyType& a, const KeyType& b) { return HashFunctions::equal(a, b); } |
103 | static void translate(ValueType& location, const KeyType& key, const MappedType& mapped) | |
b37bf2e1 | 104 | { |
9dae56ea A |
105 | location.first = key; |
106 | location.second = mapped; | |
b37bf2e1 A |
107 | } |
108 | }; | |
109 | ||
b37bf2e1 A |
110 | template<typename T, typename U, typename V, typename W, typename X> |
111 | inline void HashMap<T, U, V, W, X>::swap(HashMap& other) | |
112 | { | |
113 | m_impl.swap(other.m_impl); | |
114 | } | |
115 | ||
b37bf2e1 A |
116 | template<typename T, typename U, typename V, typename W, typename X> |
117 | inline int HashMap<T, U, V, W, X>::size() const | |
118 | { | |
119 | return m_impl.size(); | |
120 | } | |
121 | ||
122 | template<typename T, typename U, typename V, typename W, typename X> | |
123 | inline int HashMap<T, U, V, W, X>::capacity() const | |
124 | { | |
125 | return m_impl.capacity(); | |
126 | } | |
127 | ||
128 | template<typename T, typename U, typename V, typename W, typename X> | |
129 | inline bool HashMap<T, U, V, W, X>::isEmpty() const | |
130 | { | |
131 | return m_impl.isEmpty(); | |
132 | } | |
133 | ||
134 | template<typename T, typename U, typename V, typename W, typename X> | |
135 | inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::begin() | |
136 | { | |
137 | return m_impl.begin(); | |
138 | } | |
139 | ||
140 | template<typename T, typename U, typename V, typename W, typename X> | |
141 | inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::end() | |
142 | { | |
143 | return m_impl.end(); | |
144 | } | |
145 | ||
146 | template<typename T, typename U, typename V, typename W, typename X> | |
147 | inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::begin() const | |
148 | { | |
149 | return m_impl.begin(); | |
150 | } | |
151 | ||
152 | template<typename T, typename U, typename V, typename W, typename X> | |
153 | inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::end() const | |
154 | { | |
155 | return m_impl.end(); | |
156 | } | |
157 | ||
158 | template<typename T, typename U, typename V, typename W, typename X> | |
159 | inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::find(const KeyType& key) | |
160 | { | |
9dae56ea | 161 | return m_impl.find(key); |
b37bf2e1 A |
162 | } |
163 | ||
164 | template<typename T, typename U, typename V, typename W, typename X> | |
165 | inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::find(const KeyType& key) const | |
166 | { | |
9dae56ea | 167 | return m_impl.find(key); |
b37bf2e1 A |
168 | } |
169 | ||
170 | template<typename T, typename U, typename V, typename W, typename X> | |
171 | inline bool HashMap<T, U, V, W, X>::contains(const KeyType& key) const | |
172 | { | |
9dae56ea | 173 | return m_impl.contains(key); |
b37bf2e1 A |
174 | } |
175 | ||
176 | template<typename T, typename U, typename V, typename W, typename X> | |
177 | inline pair<typename HashMap<T, U, V, W, X>::iterator, bool> | |
178 | HashMap<T, U, V, W, X>::inlineAdd(const KeyType& key, const MappedType& mapped) | |
179 | { | |
9dae56ea | 180 | typedef HashMapTranslator<ValueType, ValueTraits, HashFunctions> TranslatorType; |
b37bf2e1 A |
181 | return m_impl.template add<KeyType, MappedType, TranslatorType>(key, mapped); |
182 | } | |
183 | ||
184 | template<typename T, typename U, typename V, typename W, typename X> | |
185 | pair<typename HashMap<T, U, V, W, X>::iterator, bool> | |
186 | HashMap<T, U, V, W, X>::set(const KeyType& key, const MappedType& mapped) | |
187 | { | |
188 | pair<iterator, bool> result = inlineAdd(key, mapped); | |
9dae56ea | 189 | if (!result.second) { |
b37bf2e1 A |
190 | // add call above didn't change anything, so set the mapped value |
191 | result.first->second = mapped; | |
9dae56ea | 192 | } |
b37bf2e1 A |
193 | return result; |
194 | } | |
195 | ||
196 | template<typename T, typename U, typename V, typename W, typename X> | |
197 | pair<typename HashMap<T, U, V, W, X>::iterator, bool> | |
198 | HashMap<T, U, V, W, X>::add(const KeyType& key, const MappedType& mapped) | |
199 | { | |
200 | return inlineAdd(key, mapped); | |
201 | } | |
202 | ||
203 | template<typename T, typename U, typename V, typename W, typename MappedTraits> | |
204 | typename HashMap<T, U, V, W, MappedTraits>::MappedType | |
205 | HashMap<T, U, V, W, MappedTraits>::get(const KeyType& key) const | |
206 | { | |
9dae56ea | 207 | ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key); |
b37bf2e1 A |
208 | if (!entry) |
209 | return MappedTraits::emptyValue(); | |
9dae56ea | 210 | return entry->second; |
b37bf2e1 A |
211 | } |
212 | ||
213 | template<typename T, typename U, typename V, typename W, typename X> | |
214 | inline void HashMap<T, U, V, W, X>::remove(iterator it) | |
215 | { | |
216 | if (it.m_impl == m_impl.end()) | |
217 | return; | |
218 | m_impl.checkTableConsistency(); | |
b37bf2e1 A |
219 | m_impl.removeWithoutEntryConsistencyCheck(it.m_impl); |
220 | } | |
221 | ||
222 | template<typename T, typename U, typename V, typename W, typename X> | |
223 | inline void HashMap<T, U, V, W, X>::remove(const KeyType& key) | |
224 | { | |
225 | remove(find(key)); | |
226 | } | |
227 | ||
228 | template<typename T, typename U, typename V, typename W, typename X> | |
229 | inline void HashMap<T, U, V, W, X>::clear() | |
230 | { | |
b37bf2e1 A |
231 | m_impl.clear(); |
232 | } | |
233 | ||
234 | template<typename T, typename U, typename V, typename W, typename MappedTraits> | |
235 | typename HashMap<T, U, V, W, MappedTraits>::MappedType | |
236 | HashMap<T, U, V, W, MappedTraits>::take(const KeyType& key) | |
237 | { | |
238 | // This can probably be made more efficient to avoid ref/deref churn. | |
239 | iterator it = find(key); | |
240 | if (it == end()) | |
241 | return MappedTraits::emptyValue(); | |
242 | typename HashMap<T, U, V, W, MappedTraits>::MappedType result = it->second; | |
243 | remove(it); | |
244 | return result; | |
245 | } | |
246 | ||
247 | template<typename T, typename U, typename V, typename W, typename X> | |
248 | bool operator==(const HashMap<T, U, V, W, X>& a, const HashMap<T, U, V, W, X>& b) | |
249 | { | |
250 | if (a.size() != b.size()) | |
251 | return false; | |
252 | ||
253 | typedef typename HashMap<T, U, V, W, X>::const_iterator const_iterator; | |
254 | ||
255 | const_iterator end = a.end(); | |
256 | const_iterator notFound = b.end(); | |
257 | for (const_iterator it = a.begin(); it != end; ++it) { | |
258 | const_iterator bPos = b.find(it->first); | |
259 | if (bPos == notFound || it->second != bPos->second) | |
260 | return false; | |
261 | } | |
262 | ||
263 | return true; | |
264 | } | |
265 | ||
266 | template<typename T, typename U, typename V, typename W, typename X> | |
267 | inline bool operator!=(const HashMap<T, U, V, W, X>& a, const HashMap<T, U, V, W, X>& b) | |
268 | { | |
269 | return !(a == b); | |
270 | } | |
271 | ||
272 | template<typename MappedType, typename HashTableType> | |
273 | void deleteAllPairSeconds(HashTableType& collection) | |
274 | { | |
275 | typedef typename HashTableType::const_iterator iterator; | |
276 | iterator end = collection.end(); | |
277 | for (iterator it = collection.begin(); it != end; ++it) | |
9dae56ea | 278 | delete it->second; |
b37bf2e1 A |
279 | } |
280 | ||
281 | template<typename T, typename U, typename V, typename W, typename X> | |
282 | inline void deleteAllValues(const HashMap<T, U, V, W, X>& collection) | |
283 | { | |
284 | deleteAllPairSeconds<typename HashMap<T, U, V, W, X>::MappedType>(collection); | |
285 | } | |
286 | ||
287 | template<typename KeyType, typename HashTableType> | |
288 | void deleteAllPairFirsts(HashTableType& collection) | |
289 | { | |
290 | typedef typename HashTableType::const_iterator iterator; | |
291 | iterator end = collection.end(); | |
292 | for (iterator it = collection.begin(); it != end; ++it) | |
9dae56ea | 293 | delete it->first; |
b37bf2e1 A |
294 | } |
295 | ||
296 | template<typename T, typename U, typename V, typename W, typename X> | |
297 | inline void deleteAllKeys(const HashMap<T, U, V, W, X>& collection) | |
298 | { | |
299 | deleteAllPairFirsts<typename HashMap<T, U, V, W, X>::KeyType>(collection); | |
300 | } | |
301 | ||
302 | template<typename T, typename U, typename V, typename W, typename X, typename Y> | |
303 | inline void copyKeysToVector(const HashMap<T, U, V, W, X>& collection, Y& vector) | |
304 | { | |
305 | typedef typename HashMap<T, U, V, W, X>::const_iterator::Keys iterator; | |
306 | ||
307 | vector.resize(collection.size()); | |
308 | ||
309 | iterator it = collection.begin().keys(); | |
310 | iterator end = collection.end().keys(); | |
311 | for (unsigned i = 0; it != end; ++it, ++i) | |
312 | vector[i] = *it; | |
313 | } | |
314 | ||
315 | template<typename T, typename U, typename V, typename W, typename X, typename Y> | |
316 | inline void copyValuesToVector(const HashMap<T, U, V, W, X>& collection, Y& vector) | |
317 | { | |
318 | typedef typename HashMap<T, U, V, W, X>::const_iterator::Values iterator; | |
319 | ||
320 | vector.resize(collection.size()); | |
321 | ||
322 | iterator it = collection.begin().values(); | |
323 | iterator end = collection.end().values(); | |
324 | for (unsigned i = 0; it != end; ++it, ++i) | |
325 | vector[i] = *it; | |
326 | } | |
327 | ||
328 | } // namespace WTF | |
329 | ||
330 | using WTF::HashMap; | |
331 | ||
332 | #include "RefPtrHashMap.h" | |
333 | ||
334 | #endif /* WTF_HashMap_h */ |