2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
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.
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.
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.
24 #include "HashTable.h"
28 template<typename PairType
> struct PairFirstExtractor
;
30 template<typename KeyArg
, typename MappedArg
, typename HashArg
= typename DefaultHash
<KeyArg
>::Hash
,
31 typename KeyTraitsArg
= HashTraits
<KeyArg
>, typename MappedTraitsArg
= HashTraits
<MappedArg
> >
33 WTF_MAKE_FAST_ALLOCATED
;
35 typedef KeyTraitsArg KeyTraits
;
36 typedef MappedTraitsArg MappedTraits
;
37 typedef PairHashTraits
<KeyTraits
, MappedTraits
> ValueTraits
;
40 typedef typename
KeyTraits::TraitType KeyType
;
41 typedef typename
MappedTraits::TraitType MappedType
;
42 typedef typename
ValueTraits::TraitType ValueType
;
45 typedef HashArg HashFunctions
;
47 typedef HashTable
<KeyType
, ValueType
, PairFirstExtractor
<ValueType
>,
48 HashFunctions
, ValueTraits
, KeyTraits
> HashTableType
;
51 typedef HashTableIteratorAdapter
<HashTableType
, ValueType
> iterator
;
52 typedef HashTableConstIteratorAdapter
<HashTableType
, ValueType
> const_iterator
;
60 // iterators iterate over pairs of keys and values
63 const_iterator
begin() const;
64 const_iterator
end() const;
66 iterator
find(const KeyType
&);
67 const_iterator
find(const KeyType
&) const;
68 bool contains(const KeyType
&) const;
69 MappedType
get(const KeyType
&) const;
71 // replaces value but not key if key is already present
72 // return value is a pair of the iterator to the key location,
73 // and a boolean that's true if a new value was actually added
74 pair
<iterator
, bool> set(const KeyType
&, const MappedType
&);
76 // does nothing if key is already present
77 // return value is a pair of the iterator to the key location,
78 // and a boolean that's true if a new value was actually added
79 pair
<iterator
, bool> add(const KeyType
&, const MappedType
&);
81 void remove(const KeyType
&);
82 void remove(iterator
);
85 MappedType
take(const KeyType
&); // efficient combination of get with remove
87 // An alternate version of find() that finds the object by hashing and comparing
88 // with some other type, to avoid the cost of type conversion. HashTranslator
89 // must have the following function members:
90 // static unsigned hash(const T&);
91 // static bool equal(const ValueType&, const T&);
92 template<typename T
, typename HashTranslator
> iterator
find(const T
&);
93 template<typename T
, typename HashTranslator
> const_iterator
find(const T
&) const;
94 template<typename T
, typename HashTranslator
> bool contains(const T
&) const;
96 // An alternate version of add() that finds the object by hashing and comparing
97 // with some other type, to avoid the cost of type conversion if the object is already
98 // in the table. HashTranslator must have the following function members:
99 // static unsigned hash(const T&);
100 // static bool equal(const ValueType&, const T&);
101 // static translate(ValueType&, const T&, unsigned hashCode);
102 template<typename T
, typename HashTranslator
> pair
<iterator
, bool> add(const T
&, const MappedType
&);
104 void checkConsistency() const;
107 pair
<iterator
, bool> inlineAdd(const KeyType
&, const MappedType
&);
109 HashTableType m_impl
;
112 template<typename PairType
> struct PairFirstExtractor
{
113 static const typename
PairType::first_type
& extract(const PairType
& p
) { return p
.first
; }
116 template<typename ValueType
, typename ValueTraits
, typename HashFunctions
>
117 struct HashMapTranslator
{
118 typedef typename
ValueType::first_type KeyType
;
119 typedef typename
ValueType::second_type MappedType
;
121 static unsigned hash(const KeyType
& key
) { return HashFunctions::hash(key
); }
122 static bool equal(const KeyType
& a
, const KeyType
& b
) { return HashFunctions::equal(a
, b
); }
123 static void translate(ValueType
& location
, const KeyType
& key
, const MappedType
& mapped
)
125 location
.first
= key
;
126 location
.second
= mapped
;
130 template<typename ValueType
, typename ValueTraits
, typename T
, typename Translator
>
131 struct HashMapTranslatorAdapter
{
132 typedef typename
ValueType::first_type KeyType
;
133 typedef typename
ValueType::second_type MappedType
;
135 static unsigned hash(const T
& key
) { return Translator::hash(key
); }
136 static bool equal(const KeyType
& a
, const T
& b
) { return Translator::equal(a
, b
); }
137 static void translate(ValueType
& location
, const T
& key
, const MappedType
& mapped
, unsigned hashCode
)
139 Translator::translate(location
.first
, key
, hashCode
);
140 location
.second
= mapped
;
144 template<typename T
, typename U
, typename V
, typename W
, typename X
>
145 inline void HashMap
<T
, U
, V
, W
, X
>::swap(HashMap
& other
)
147 m_impl
.swap(other
.m_impl
);
150 template<typename T
, typename U
, typename V
, typename W
, typename X
>
151 inline int HashMap
<T
, U
, V
, W
, X
>::size() const
153 return m_impl
.size();
156 template<typename T
, typename U
, typename V
, typename W
, typename X
>
157 inline int HashMap
<T
, U
, V
, W
, X
>::capacity() const
159 return m_impl
.capacity();
162 template<typename T
, typename U
, typename V
, typename W
, typename X
>
163 inline bool HashMap
<T
, U
, V
, W
, X
>::isEmpty() const
165 return m_impl
.isEmpty();
168 template<typename T
, typename U
, typename V
, typename W
, typename X
>
169 inline typename HashMap
<T
, U
, V
, W
, X
>::iterator HashMap
<T
, U
, V
, W
, X
>::begin()
171 return m_impl
.begin();
174 template<typename T
, typename U
, typename V
, typename W
, typename X
>
175 inline typename HashMap
<T
, U
, V
, W
, X
>::iterator HashMap
<T
, U
, V
, W
, X
>::end()
180 template<typename T
, typename U
, typename V
, typename W
, typename X
>
181 inline typename HashMap
<T
, U
, V
, W
, X
>::const_iterator HashMap
<T
, U
, V
, W
, X
>::begin() const
183 return m_impl
.begin();
186 template<typename T
, typename U
, typename V
, typename W
, typename X
>
187 inline typename HashMap
<T
, U
, V
, W
, X
>::const_iterator HashMap
<T
, U
, V
, W
, X
>::end() const
192 template<typename T
, typename U
, typename V
, typename W
, typename X
>
193 inline typename HashMap
<T
, U
, V
, W
, X
>::iterator HashMap
<T
, U
, V
, W
, X
>::find(const KeyType
& key
)
195 return m_impl
.find(key
);
198 template<typename T
, typename U
, typename V
, typename W
, typename X
>
199 inline typename HashMap
<T
, U
, V
, W
, X
>::const_iterator HashMap
<T
, U
, V
, W
, X
>::find(const KeyType
& key
) const
201 return m_impl
.find(key
);
204 template<typename T
, typename U
, typename V
, typename W
, typename X
>
205 inline bool HashMap
<T
, U
, V
, W
, X
>::contains(const KeyType
& key
) const
207 return m_impl
.contains(key
);
210 template<typename T
, typename U
, typename V
, typename W
, typename X
>
211 template<typename TYPE
, typename HashTranslator
>
212 inline typename HashMap
<T
, U
, V
, W
, X
>::iterator
213 HashMap
<T
, U
, V
, W
, X
>::find(const TYPE
& value
)
215 typedef HashMapTranslatorAdapter
<ValueType
, ValueTraits
, TYPE
, HashTranslator
> Adapter
;
216 return m_impl
.template find
<TYPE
, Adapter
>(value
);
219 template<typename T
, typename U
, typename V
, typename W
, typename X
>
220 template<typename TYPE
, typename HashTranslator
>
221 inline typename HashMap
<T
, U
, V
, W
, X
>::const_iterator
222 HashMap
<T
, U
, V
, W
, X
>::find(const TYPE
& value
) const
224 typedef HashMapTranslatorAdapter
<ValueType
, ValueTraits
, TYPE
, HashTranslator
> Adapter
;
225 return m_impl
.template find
<TYPE
, Adapter
>(value
);
228 template<typename T
, typename U
, typename V
, typename W
, typename X
>
229 template<typename TYPE
, typename HashTranslator
>
231 HashMap
<T
, U
, V
, W
, X
>::contains(const TYPE
& value
) const
233 typedef HashMapTranslatorAdapter
<ValueType
, ValueTraits
, TYPE
, HashTranslator
> Adapter
;
234 return m_impl
.template contains
<TYPE
, Adapter
>(value
);
237 template<typename T
, typename U
, typename V
, typename W
, typename X
>
238 inline pair
<typename HashMap
<T
, U
, V
, W
, X
>::iterator
, bool>
239 HashMap
<T
, U
, V
, W
, X
>::inlineAdd(const KeyType
& key
, const MappedType
& mapped
)
241 typedef HashMapTranslator
<ValueType
, ValueTraits
, HashFunctions
> TranslatorType
;
242 return m_impl
.template add
<KeyType
, MappedType
, TranslatorType
>(key
, mapped
);
245 template<typename T
, typename U
, typename V
, typename W
, typename X
>
246 pair
<typename HashMap
<T
, U
, V
, W
, X
>::iterator
, bool>
247 HashMap
<T
, U
, V
, W
, X
>::set(const KeyType
& key
, const MappedType
& mapped
)
249 pair
<iterator
, bool> result
= inlineAdd(key
, mapped
);
250 if (!result
.second
) {
251 // add call above didn't change anything, so set the mapped value
252 result
.first
->second
= mapped
;
257 template<typename T
, typename U
, typename V
, typename W
, typename X
>
258 template<typename TYPE
, typename HashTranslator
>
259 pair
<typename HashMap
<T
, U
, V
, W
, X
>::iterator
, bool>
260 HashMap
<T
, U
, V
, W
, X
>::add(const TYPE
& key
, const MappedType
& value
)
262 typedef HashMapTranslatorAdapter
<ValueType
, ValueTraits
, TYPE
, HashTranslator
> Adapter
;
263 return m_impl
.template addPassingHashCode
<TYPE
, MappedType
, Adapter
>(key
, value
);
266 template<typename T
, typename U
, typename V
, typename W
, typename X
>
267 pair
<typename HashMap
<T
, U
, V
, W
, X
>::iterator
, bool>
268 HashMap
<T
, U
, V
, W
, X
>::add(const KeyType
& key
, const MappedType
& mapped
)
270 return inlineAdd(key
, mapped
);
273 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
274 typename HashMap
<T
, U
, V
, W
, MappedTraits
>::MappedType
275 HashMap
<T
, U
, V
, W
, MappedTraits
>::get(const KeyType
& key
) const
277 ValueType
* entry
= const_cast<HashTableType
&>(m_impl
).lookup(key
);
279 return MappedTraits::emptyValue();
280 return entry
->second
;
283 template<typename T
, typename U
, typename V
, typename W
, typename X
>
284 inline void HashMap
<T
, U
, V
, W
, X
>::remove(iterator it
)
286 if (it
.m_impl
== m_impl
.end())
288 m_impl
.internalCheckTableConsistency();
289 m_impl
.removeWithoutEntryConsistencyCheck(it
.m_impl
);
292 template<typename T
, typename U
, typename V
, typename W
, typename X
>
293 inline void HashMap
<T
, U
, V
, W
, X
>::remove(const KeyType
& key
)
298 template<typename T
, typename U
, typename V
, typename W
, typename X
>
299 inline void HashMap
<T
, U
, V
, W
, X
>::clear()
304 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
305 typename HashMap
<T
, U
, V
, W
, MappedTraits
>::MappedType
306 HashMap
<T
, U
, V
, W
, MappedTraits
>::take(const KeyType
& key
)
308 // This can probably be made more efficient to avoid ref/deref churn.
309 iterator it
= find(key
);
311 return MappedTraits::emptyValue();
312 typename HashMap
<T
, U
, V
, W
, MappedTraits
>::MappedType result
= it
->second
;
317 template<typename T
, typename U
, typename V
, typename W
, typename X
>
318 inline void HashMap
<T
, U
, V
, W
, X
>::checkConsistency() const
320 m_impl
.checkTableConsistency();
324 template<typename T
, typename U
, typename V
, typename W
, typename X
>
325 bool operator==(const HashMap
<T
, U
, V
, W
, X
>& a
, const HashMap
<T
, U
, V
, W
, X
>& b
)
327 if (a
.size() != b
.size())
330 typedef typename HashMap
<T
, U
, V
, W
, X
>::const_iterator const_iterator
;
332 const_iterator end
= a
.end();
333 const_iterator notFound
= b
.end();
334 for (const_iterator it
= a
.begin(); it
!= end
; ++it
) {
335 const_iterator bPos
= b
.find(it
->first
);
336 if (bPos
== notFound
|| it
->second
!= bPos
->second
)
343 template<typename T
, typename U
, typename V
, typename W
, typename X
>
344 inline bool operator!=(const HashMap
<T
, U
, V
, W
, X
>& a
, const HashMap
<T
, U
, V
, W
, X
>& b
)
349 template<typename MappedType
, typename HashTableType
>
350 void deleteAllPairSeconds(HashTableType
& collection
)
352 typedef typename
HashTableType::const_iterator iterator
;
353 iterator end
= collection
.end();
354 for (iterator it
= collection
.begin(); it
!= end
; ++it
)
358 template<typename T
, typename U
, typename V
, typename W
, typename X
>
359 inline void deleteAllValues(const HashMap
<T
, U
, V
, W
, X
>& collection
)
361 deleteAllPairSeconds
<typename HashMap
<T
, U
, V
, W
, X
>::MappedType
>(collection
);
364 template<typename KeyType
, typename HashTableType
>
365 void deleteAllPairFirsts(HashTableType
& collection
)
367 typedef typename
HashTableType::const_iterator iterator
;
368 iterator end
= collection
.end();
369 for (iterator it
= collection
.begin(); it
!= end
; ++it
)
373 template<typename T
, typename U
, typename V
, typename W
, typename X
>
374 inline void deleteAllKeys(const HashMap
<T
, U
, V
, W
, X
>& collection
)
376 deleteAllPairFirsts
<typename HashMap
<T
, U
, V
, W
, X
>::KeyType
>(collection
);
379 template<typename T
, typename U
, typename V
, typename W
, typename X
, typename Y
>
380 inline void copyKeysToVector(const HashMap
<T
, U
, V
, W
, X
>& collection
, Y
& vector
)
382 typedef typename HashMap
<T
, U
, V
, W
, X
>::const_iterator::Keys iterator
;
384 vector
.resize(collection
.size());
386 iterator it
= collection
.begin().keys();
387 iterator end
= collection
.end().keys();
388 for (unsigned i
= 0; it
!= end
; ++it
, ++i
)
392 template<typename T
, typename U
, typename V
, typename W
, typename X
, typename Y
>
393 inline void copyValuesToVector(const HashMap
<T
, U
, V
, W
, X
>& collection
, Y
& vector
)
395 typedef typename HashMap
<T
, U
, V
, W
, X
>::const_iterator::Values iterator
;
397 vector
.resize(collection
.size());
399 iterator it
= collection
.begin().values();
400 iterator end
= collection
.end().values();
401 for (unsigned i
= 0; it
!= end
; ++it
, ++i
)
409 #include "RefPtrHashMap.h"
411 #endif /* WTF_HashMap_h */