1 // -*- mode: c++; c-basic-offset: 4 -*-
3 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
25 #include "HashTable.h"
29 template<typename PairType
> struct PairFirstExtractor
;
31 template<typename KeyArg
, typename MappedArg
, typename HashArg
= typename DefaultHash
<KeyArg
>::Hash
,
32 typename KeyTraitsArg
= HashTraits
<KeyArg
>, typename MappedTraitsArg
= HashTraits
<MappedArg
> >
35 typedef KeyTraitsArg KeyTraits
;
36 typedef MappedTraitsArg MappedTraits
;
37 typedef PairBaseHashTraits
<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 typename HashKeyStorageTraits
<HashFunctions
, KeyTraits
>::Hash StorageHashFunctions
;
49 typedef typename HashKeyStorageTraits
<HashFunctions
, KeyTraits
>::Traits KeyStorageTraits
;
50 typedef typename
MappedTraits::StorageTraits MappedStorageTraits
;
51 typedef PairHashTraits
<KeyStorageTraits
, MappedStorageTraits
> ValueStorageTraits
;
53 typedef typename
KeyStorageTraits::TraitType KeyStorageType
;
54 typedef typename
MappedStorageTraits::TraitType MappedStorageType
;
55 typedef typename
ValueStorageTraits::TraitType ValueStorageType
;
57 typedef HashTable
<KeyStorageType
, ValueStorageType
, PairFirstExtractor
<ValueStorageType
>,
58 StorageHashFunctions
, ValueStorageTraits
, KeyStorageTraits
> HashTableType
;
61 typedef HashTableIteratorAdapter
<HashTableType
, ValueType
> iterator
;
62 typedef HashTableConstIteratorAdapter
<HashTableType
, ValueType
> const_iterator
;
65 HashMap(const HashMap
&);
66 HashMap
& operator=(const HashMap
&);
75 // iterators iterate over pairs of keys and values
78 const_iterator
begin() const;
79 const_iterator
end() const;
81 iterator
find(const KeyType
&);
82 const_iterator
find(const KeyType
&) const;
83 bool contains(const KeyType
&) const;
84 MappedType
get(const KeyType
&) const;
86 // replaces value but not key if key is already present
87 // return value is a pair of the iterator to the key location,
88 // and a boolean that's true if a new value was actually added
89 pair
<iterator
, bool> set(const KeyType
&, const MappedType
&);
91 // does nothing if key is already present
92 // return value is a pair of the iterator to the key location,
93 // and a boolean that's true if a new value was actually added
94 pair
<iterator
, bool> add(const KeyType
&, const MappedType
&);
96 void remove(const KeyType
&);
97 void remove(iterator
);
100 MappedType
take(const KeyType
&); // efficient combination of get with remove
103 pair
<iterator
, bool> inlineAdd(const KeyType
&, const MappedType
&);
107 HashTableType m_impl
;
110 template<typename PairType
> struct PairFirstExtractor
{
111 static const typename
PairType::first_type
& extract(const PairType
& p
) { return p
.first
; }
114 template<bool canReplaceDeletedKey
, typename ValueType
, typename ValueTraits
, typename ValueStorageTraits
, typename HashFunctions
>
115 struct HashMapTranslator
;
117 template<typename ValueType
, typename ValueTraits
, typename ValueStorageTraits
, typename HashFunctions
>
118 struct HashMapTranslator
<true, ValueType
, ValueTraits
, ValueStorageTraits
, HashFunctions
> {
119 typedef typename
ValueType::first_type KeyType
;
120 typedef typename
ValueType::second_type MappedType
;
121 typedef typename
ValueStorageTraits::TraitType ValueStorageType
;
122 typedef typename
ValueStorageTraits::FirstTraits KeyStorageTraits
;
123 typedef typename
KeyStorageTraits::TraitType KeyStorageType
;
124 typedef typename
ValueStorageTraits::SecondTraits MappedStorageTraits
;
125 typedef typename
MappedStorageTraits::TraitType MappedStorageType
;
126 typedef typename
ValueTraits::FirstTraits KeyTraits
;
127 typedef typename
ValueTraits::SecondTraits MappedTraits
;
129 static unsigned hash(const KeyType
& key
) { return HashFunctions::hash(key
); }
130 static bool equal(const KeyStorageType
& a
, const KeyType
& b
) { return HashFunctions::equal(*(KeyType
*)&a
, b
); }
131 static void translate(ValueStorageType
& location
, const KeyType
& key
, const MappedType
& mapped
)
133 Assigner
<KeyTraits::needsRef
, KeyType
, KeyStorageType
, KeyTraits
>::assign(key
, location
.first
);
134 Assigner
<MappedTraits::needsRef
, MappedType
, MappedStorageType
, MappedTraits
>::assign(mapped
, location
.second
);
138 template<typename ValueType
, typename ValueTraits
, typename ValueStorageTraits
, typename HashFunctions
>
139 struct HashMapTranslator
<false, ValueType
, ValueTraits
, ValueStorageTraits
, HashFunctions
> {
140 typedef typename
ValueType::first_type KeyType
;
141 typedef typename
ValueType::second_type MappedType
;
142 typedef typename
ValueStorageTraits::TraitType ValueStorageType
;
143 typedef typename
ValueStorageTraits::FirstTraits KeyStorageTraits
;
144 typedef typename
KeyStorageTraits::TraitType KeyStorageType
;
145 typedef typename
ValueStorageTraits::SecondTraits MappedStorageTraits
;
146 typedef typename
MappedStorageTraits::TraitType MappedStorageType
;
147 typedef typename
ValueTraits::FirstTraits KeyTraits
;
148 typedef typename
ValueTraits::SecondTraits MappedTraits
;
150 static unsigned hash(const KeyType
& key
) { return HashFunctions::hash(key
); }
151 static bool equal(const KeyStorageType
& a
, const KeyType
& b
) { return HashFunctions::equal(*(KeyType
*)&a
, b
); }
152 static void translate(ValueStorageType
& location
, const KeyType
& key
, const MappedType
& mapped
)
154 if (location
.first
== KeyStorageTraits::deletedValue())
155 location
.first
= KeyStorageTraits::emptyValue();
156 Assigner
<KeyTraits::needsRef
, KeyType
, KeyStorageType
, KeyTraits
>::assign(key
, location
.first
);
157 Assigner
<MappedTraits::needsRef
, MappedType
, MappedStorageType
, MappedTraits
>::assign(mapped
, location
.second
);
161 template<typename T
, typename U
, typename V
, typename W
, typename X
>
162 inline void HashMap
<T
, U
, V
, W
, X
>::refAll()
164 HashTableRefCounter
<HashTableType
, ValueTraits
>::refAll(m_impl
);
167 template<typename T
, typename U
, typename V
, typename W
, typename X
>
168 inline void HashMap
<T
, U
, V
, W
, X
>::derefAll()
170 HashTableRefCounter
<HashTableType
, ValueTraits
>::derefAll(m_impl
);
173 template<typename T
, typename U
, typename V
, typename W
, typename X
>
174 inline HashMap
<T
, U
, V
, W
, X
>::HashMap()
178 template<typename T
, typename U
, typename V
, typename W
, typename X
>
179 inline HashMap
<T
, U
, V
, W
, X
>::HashMap(const HashMap
& other
)
180 : m_impl(other
.m_impl
)
185 template<typename T
, typename U
, typename V
, typename W
, typename X
>
186 inline HashMap
<T
, U
, V
, W
, X
>& HashMap
<T
, U
, V
, W
, X
>::operator=(const HashMap
& other
)
193 template<typename T
, typename U
, typename V
, typename W
, typename X
>
194 inline void HashMap
<T
, U
, V
, W
, X
>::swap(HashMap
& other
)
196 m_impl
.swap(other
.m_impl
);
199 template<typename T
, typename U
, typename V
, typename W
, typename X
>
200 inline HashMap
<T
, U
, V
, W
, X
>::~HashMap()
205 template<typename T
, typename U
, typename V
, typename W
, typename X
>
206 inline int HashMap
<T
, U
, V
, W
, X
>::size() const
208 return m_impl
.size();
211 template<typename T
, typename U
, typename V
, typename W
, typename X
>
212 inline int HashMap
<T
, U
, V
, W
, X
>::capacity() const
214 return m_impl
.capacity();
217 template<typename T
, typename U
, typename V
, typename W
, typename X
>
218 inline bool HashMap
<T
, U
, V
, W
, X
>::isEmpty() const
220 return m_impl
.isEmpty();
223 template<typename T
, typename U
, typename V
, typename W
, typename X
>
224 inline typename HashMap
<T
, U
, V
, W
, X
>::iterator HashMap
<T
, U
, V
, W
, X
>::begin()
226 return m_impl
.begin();
229 template<typename T
, typename U
, typename V
, typename W
, typename X
>
230 inline typename HashMap
<T
, U
, V
, W
, X
>::iterator HashMap
<T
, U
, V
, W
, X
>::end()
235 template<typename T
, typename U
, typename V
, typename W
, typename X
>
236 inline typename HashMap
<T
, U
, V
, W
, X
>::const_iterator HashMap
<T
, U
, V
, W
, X
>::begin() const
238 return m_impl
.begin();
241 template<typename T
, typename U
, typename V
, typename W
, typename X
>
242 inline typename HashMap
<T
, U
, V
, W
, X
>::const_iterator HashMap
<T
, U
, V
, W
, X
>::end() const
247 template<typename T
, typename U
, typename V
, typename W
, typename X
>
248 inline typename HashMap
<T
, U
, V
, W
, X
>::iterator HashMap
<T
, U
, V
, W
, X
>::find(const KeyType
& key
)
250 return m_impl
.find(*(const KeyStorageType
*)&key
);
253 template<typename T
, typename U
, typename V
, typename W
, typename X
>
254 inline typename HashMap
<T
, U
, V
, W
, X
>::const_iterator HashMap
<T
, U
, V
, W
, X
>::find(const KeyType
& key
) const
256 return m_impl
.find(*(const KeyStorageType
*)&key
);
259 template<typename T
, typename U
, typename V
, typename W
, typename X
>
260 inline bool HashMap
<T
, U
, V
, W
, X
>::contains(const KeyType
& key
) const
262 return m_impl
.contains(*(const KeyStorageType
*)&key
);
265 template<typename T
, typename U
, typename V
, typename W
, typename X
>
266 inline pair
<typename HashMap
<T
, U
, V
, W
, X
>::iterator
, bool>
267 HashMap
<T
, U
, V
, W
, X
>::inlineAdd(const KeyType
& key
, const MappedType
& mapped
)
269 const bool canReplaceDeletedKey
= !KeyTraits::needsDestruction
|| KeyStorageTraits::needsDestruction
;
270 typedef HashMapTranslator
<canReplaceDeletedKey
, ValueType
, ValueTraits
, ValueStorageTraits
, HashFunctions
> TranslatorType
;
271 return m_impl
.template add
<KeyType
, MappedType
, TranslatorType
>(key
, mapped
);
274 template<typename T
, typename U
, typename V
, typename W
, typename X
>
275 pair
<typename HashMap
<T
, U
, V
, W
, X
>::iterator
, bool>
276 HashMap
<T
, U
, V
, W
, X
>::set(const KeyType
& key
, const MappedType
& mapped
)
278 pair
<iterator
, bool> result
= inlineAdd(key
, mapped
);
280 // add call above didn't change anything, so set the mapped value
281 result
.first
->second
= mapped
;
285 template<typename T
, typename U
, typename V
, typename W
, typename X
>
286 pair
<typename HashMap
<T
, U
, V
, W
, X
>::iterator
, bool>
287 HashMap
<T
, U
, V
, W
, X
>::add(const KeyType
& key
, const MappedType
& mapped
)
289 return inlineAdd(key
, mapped
);
292 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
293 typename HashMap
<T
, U
, V
, W
, MappedTraits
>::MappedType
294 HashMap
<T
, U
, V
, W
, MappedTraits
>::get(const KeyType
& key
) const
296 if (m_impl
.isEmpty())
297 return MappedTraits::emptyValue();
298 ValueStorageType
* entry
= const_cast<HashTableType
&>(m_impl
).lookup(*(const KeyStorageType
*)&key
);
300 return MappedTraits::emptyValue();
301 return ((ValueType
*)entry
)->second
;
304 template<typename T
, typename U
, typename V
, typename W
, typename X
>
305 inline void HashMap
<T
, U
, V
, W
, X
>::remove(iterator it
)
307 if (it
.m_impl
== m_impl
.end())
309 m_impl
.checkTableConsistency();
310 RefCounter
<ValueTraits
, ValueStorageTraits
>::deref(*it
.m_impl
);
311 m_impl
.removeWithoutEntryConsistencyCheck(it
.m_impl
);
314 template<typename T
, typename U
, typename V
, typename W
, typename X
>
315 inline void HashMap
<T
, U
, V
, W
, X
>::remove(const KeyType
& key
)
320 template<typename T
, typename U
, typename V
, typename W
, typename X
>
321 inline void HashMap
<T
, U
, V
, W
, X
>::clear()
327 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
328 typename HashMap
<T
, U
, V
, W
, MappedTraits
>::MappedType
329 HashMap
<T
, U
, V
, W
, MappedTraits
>::take(const KeyType
& key
)
331 // This can probably be made more efficient to avoid ref/deref churn.
332 iterator it
= find(key
);
334 return MappedTraits::emptyValue();
335 typename HashMap
<T
, U
, V
, W
, MappedTraits
>::MappedType result
= it
->second
;
340 template<typename T
, typename U
, typename V
, typename W
, typename X
>
341 bool operator==(const HashMap
<T
, U
, V
, W
, X
>& a
, const HashMap
<T
, U
, V
, W
, X
>& b
)
343 if (a
.size() != b
.size())
346 typedef typename HashMap
<T
, U
, V
, W
, X
>::const_iterator const_iterator
;
348 const_iterator end
= a
.end();
349 const_iterator notFound
= b
.end();
350 for (const_iterator it
= a
.begin(); it
!= end
; ++it
) {
351 const_iterator bPos
= b
.find(it
->first
);
352 if (bPos
== notFound
|| it
->second
!= bPos
->second
)
359 template<typename T
, typename U
, typename V
, typename W
, typename X
>
360 inline bool operator!=(const HashMap
<T
, U
, V
, W
, X
>& a
, const HashMap
<T
, U
, V
, W
, X
>& b
)
365 template<typename MappedType
, typename HashTableType
>
366 void deleteAllPairSeconds(HashTableType
& collection
)
368 typedef typename
HashTableType::const_iterator iterator
;
369 iterator end
= collection
.end();
370 for (iterator it
= collection
.begin(); it
!= end
; ++it
)
371 delete *(MappedType
*)&it
->second
;
374 template<typename T
, typename U
, typename V
, typename W
, typename X
>
375 inline void deleteAllValues(const HashMap
<T
, U
, V
, W
, X
>& collection
)
377 deleteAllPairSeconds
<typename HashMap
<T
, U
, V
, W
, X
>::MappedType
>(collection
);
380 template<typename KeyType
, typename HashTableType
>
381 void deleteAllPairFirsts(HashTableType
& collection
)
383 typedef typename
HashTableType::const_iterator iterator
;
384 iterator end
= collection
.end();
385 for (iterator it
= collection
.begin(); it
!= end
; ++it
)
386 delete *(KeyType
*)&it
->first
;
389 template<typename T
, typename U
, typename V
, typename W
, typename X
>
390 inline void deleteAllKeys(const HashMap
<T
, U
, V
, W
, X
>& collection
)
392 deleteAllPairFirsts
<typename HashMap
<T
, U
, V
, W
, X
>::KeyType
>(collection
);
395 template<typename T
, typename U
, typename V
, typename W
, typename X
, typename Y
>
396 inline void copyKeysToVector(const HashMap
<T
, U
, V
, W
, X
>& collection
, Y
& vector
)
398 typedef typename HashMap
<T
, U
, V
, W
, X
>::const_iterator::Keys iterator
;
400 vector
.resize(collection
.size());
402 iterator it
= collection
.begin().keys();
403 iterator end
= collection
.end().keys();
404 for (unsigned i
= 0; it
!= end
; ++it
, ++i
)
408 template<typename T
, typename U
, typename V
, typename W
, typename X
, typename Y
>
409 inline void copyValuesToVector(const HashMap
<T
, U
, V
, W
, X
>& collection
, Y
& vector
)
411 typedef typename HashMap
<T
, U
, V
, W
, X
>::const_iterator::Values iterator
;
413 vector
.resize(collection
.size());
415 iterator it
= collection
.begin().values();
416 iterator end
= collection
.end().values();
417 for (unsigned i
= 0; it
!= end
; ++it
, ++i
)
425 #include "RefPtrHashMap.h"
427 #endif /* WTF_HashMap_h */