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.
24 // This specialization is a direct copy of HashMap, with overloaded functions
25 // to allow for lookup by pointer instead of RefPtr, avoiding ref-count churn.
27 // FIXME: Is there a better way to do this that doesn't just copy HashMap?
29 template<typename T
, typename MappedArg
, typename HashArg
, typename KeyTraitsArg
, typename MappedTraitsArg
>
30 class HashMap
<RefPtr
<T
>, MappedArg
, HashArg
, KeyTraitsArg
, MappedTraitsArg
> {
32 typedef KeyTraitsArg KeyTraits
;
33 typedef MappedTraitsArg MappedTraits
;
34 typedef PairBaseHashTraits
<KeyTraits
, MappedTraits
> ValueTraits
;
37 typedef typename
KeyTraits::TraitType KeyType
;
38 typedef T
* RawKeyType
;
39 typedef typename
MappedTraits::TraitType MappedType
;
40 typedef typename
ValueTraits::TraitType ValueType
;
43 typedef HashArg HashFunctions
;
45 typedef typename HashKeyStorageTraits
<HashFunctions
, KeyTraits
>::Hash StorageHashFunctions
;
47 typedef typename HashKeyStorageTraits
<HashFunctions
, KeyTraits
>::Traits KeyStorageTraits
;
48 typedef typename
MappedTraits::StorageTraits MappedStorageTraits
;
49 typedef PairHashTraits
<KeyStorageTraits
, MappedStorageTraits
> ValueStorageTraits
;
51 typedef typename
KeyStorageTraits::TraitType KeyStorageType
;
52 typedef typename
MappedStorageTraits::TraitType MappedStorageType
;
53 typedef typename
ValueStorageTraits::TraitType ValueStorageType
;
55 typedef HashTable
<KeyStorageType
, ValueStorageType
, PairFirstExtractor
<ValueStorageType
>,
56 StorageHashFunctions
, ValueStorageTraits
, KeyStorageTraits
> HashTableType
;
59 typedef HashTableIteratorAdapter
<HashTableType
, ValueType
> iterator
;
60 typedef HashTableConstIteratorAdapter
<HashTableType
, ValueType
> const_iterator
;
63 HashMap(const HashMap
&);
64 HashMap
& operator=(const HashMap
&);
73 // iterators iterate over pairs of keys and values
76 const_iterator
begin() const;
77 const_iterator
end() const;
79 iterator
find(const KeyType
&);
80 iterator
find(RawKeyType
);
81 const_iterator
find(const KeyType
&) const;
82 const_iterator
find(RawKeyType
) const;
83 bool contains(const KeyType
&) const;
84 bool contains(RawKeyType
) const;
85 MappedType
get(const KeyType
&) const;
86 MappedType
get(RawKeyType
) const;
88 // replaces value but not key if key is already present
89 // return value is a pair of the iterator to the key location,
90 // and a boolean that's true if a new value was actually added
91 pair
<iterator
, bool> set(const KeyType
&, const MappedType
&);
92 pair
<iterator
, bool> set(RawKeyType
, const MappedType
&);
94 // does nothing if key is already present
95 // return value is a pair of the iterator to the key location,
96 // and a boolean that's true if a new value was actually added
97 pair
<iterator
, bool> add(const KeyType
&, const MappedType
&);
98 pair
<iterator
, bool> add(RawKeyType
, const MappedType
&);
100 void remove(const KeyType
&);
101 void remove(RawKeyType
);
102 void remove(iterator
);
105 MappedType
take(const KeyType
&); // efficient combination of get with remove
106 MappedType
take(RawKeyType
); // efficient combination of get with remove
109 pair
<iterator
, bool> inlineAdd(const KeyType
&, const MappedType
&);
110 pair
<iterator
, bool> inlineAdd(RawKeyType
, const MappedType
&);
114 HashTableType m_impl
;
117 template<typename T
, typename U
, typename V
, typename W
, typename X
>
118 inline void HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::refAll()
120 HashTableRefCounter
<HashTableType
, ValueTraits
>::refAll(m_impl
);
123 template<typename T
, typename U
, typename V
, typename W
, typename X
>
124 inline void HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::derefAll()
126 HashTableRefCounter
<HashTableType
, ValueTraits
>::derefAll(m_impl
);
129 template<typename T
, typename U
, typename V
, typename W
, typename X
>
130 inline HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::HashMap()
134 template<typename T
, typename U
, typename V
, typename W
, typename X
>
135 inline HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::HashMap(const HashMap
& other
)
136 : m_impl(other
.m_impl
)
141 template<typename T
, typename U
, typename V
, typename W
, typename X
>
142 inline HashMap
<RefPtr
<T
>, U
, V
, W
, X
>& HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::operator=(const HashMap
& other
)
149 template<typename T
, typename U
, typename V
, typename W
, typename X
>
150 inline void HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::swap(HashMap
& other
)
152 m_impl
.swap(other
.m_impl
);
155 template<typename T
, typename U
, typename V
, typename W
, typename X
>
156 inline HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::~HashMap()
161 template<typename T
, typename U
, typename V
, typename W
, typename X
>
162 inline int HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::size() const
164 return m_impl
.size();
167 template<typename T
, typename U
, typename V
, typename W
, typename X
>
168 inline int HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::capacity() const
170 return m_impl
.capacity();
173 template<typename T
, typename U
, typename V
, typename W
, typename X
>
174 inline bool HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::isEmpty() const
176 return m_impl
.isEmpty();
179 template<typename T
, typename U
, typename V
, typename W
, typename X
>
180 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::begin()
182 return m_impl
.begin();
185 template<typename T
, typename U
, typename V
, typename W
, typename X
>
186 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::end()
191 template<typename T
, typename U
, typename V
, typename W
, typename X
>
192 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::const_iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::begin() const
194 return m_impl
.begin();
197 template<typename T
, typename U
, typename V
, typename W
, typename X
>
198 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::const_iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::end() const
203 template<typename T
, typename U
, typename V
, typename W
, typename X
>
204 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::find(const KeyType
& key
)
206 return m_impl
.find(*(const KeyStorageType
*)&key
);
209 template<typename T
, typename U
, typename V
, typename W
, typename X
>
210 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::find(RawKeyType key
)
212 return m_impl
.find(*(const KeyStorageType
*)&key
);
215 template<typename T
, typename U
, typename V
, typename W
, typename X
>
216 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::const_iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::find(const KeyType
& key
) const
218 return m_impl
.find(*(const KeyStorageType
*)&key
);
221 template<typename T
, typename U
, typename V
, typename W
, typename X
>
222 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::const_iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::find(RawKeyType key
) const
224 return m_impl
.find(*(const KeyStorageType
*)&key
);
227 template<typename T
, typename U
, typename V
, typename W
, typename X
>
228 inline bool HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::contains(const KeyType
& key
) const
230 return m_impl
.contains(*(const KeyStorageType
*)&key
);
233 template<typename T
, typename U
, typename V
, typename W
, typename X
>
234 inline bool HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::contains(RawKeyType key
) const
236 return m_impl
.contains(*(const KeyStorageType
*)&key
);
239 template<typename T
, typename U
, typename V
, typename W
, typename X
>
240 inline pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
241 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::inlineAdd(const KeyType
& key
, const MappedType
& mapped
)
243 const bool canReplaceDeletedKey
= !KeyTraits::needsDestruction
|| KeyStorageTraits::needsDestruction
;
244 typedef HashMapTranslator
<canReplaceDeletedKey
, ValueType
, ValueTraits
, ValueStorageTraits
, HashFunctions
> TranslatorType
;
245 return m_impl
.template add
<KeyType
, MappedType
, TranslatorType
>(key
, mapped
);
248 template<typename T
, typename U
, typename V
, typename W
, typename X
>
249 inline pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
250 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::inlineAdd(RawKeyType key
, const MappedType
& mapped
)
252 return inlineAdd(*(const KeyType
*)&key
, mapped
);
255 template<typename T
, typename U
, typename V
, typename W
, typename X
>
256 pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
257 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::set(const KeyType
& key
, const MappedType
& mapped
)
259 pair
<iterator
, bool> result
= inlineAdd(key
, mapped
);
261 // add call above didn't change anything, so set the mapped value
262 result
.first
->second
= mapped
;
266 template<typename T
, typename U
, typename V
, typename W
, typename X
>
267 pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
268 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::set(RawKeyType key
, const MappedType
& mapped
)
270 pair
<iterator
, bool> result
= inlineAdd(key
, mapped
);
272 // add call above didn't change anything, so set the mapped value
273 result
.first
->second
= mapped
;
277 template<typename T
, typename U
, typename V
, typename W
, typename X
>
278 pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
279 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::add(const KeyType
& key
, const MappedType
& mapped
)
281 return inlineAdd(key
, mapped
);
284 template<typename T
, typename U
, typename V
, typename W
, typename X
>
285 pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
286 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::add(RawKeyType key
, const MappedType
& mapped
)
288 return inlineAdd(key
, mapped
);
291 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
292 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType
293 HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::get(const KeyType
& key
) const
295 if (m_impl
.isEmpty())
296 return MappedTraits::emptyValue();
297 ValueStorageType
* entry
= const_cast<HashTableType
&>(m_impl
).lookup(*(const KeyStorageType
*)&key
);
299 return MappedTraits::emptyValue();
300 return ((ValueType
*)entry
)->second
;
303 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
304 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType
305 HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::get(RawKeyType key
) const
307 if (m_impl
.isEmpty())
308 return MappedTraits::emptyValue();
309 ValueStorageType
* entry
= const_cast<HashTableType
&>(m_impl
).lookup(*(const KeyStorageType
*)&key
);
311 return MappedTraits::emptyValue();
312 return ((ValueType
*)entry
)->second
;
315 template<typename T
, typename U
, typename V
, typename W
, typename X
>
316 inline void HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::remove(iterator it
)
318 if (it
.m_impl
== m_impl
.end())
320 m_impl
.checkTableConsistency();
321 RefCounter
<ValueTraits
, ValueStorageTraits
>::deref(*it
.m_impl
);
322 m_impl
.removeWithoutEntryConsistencyCheck(it
.m_impl
);
325 template<typename T
, typename U
, typename V
, typename W
, typename X
>
326 inline void HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::remove(const KeyType
& key
)
331 template<typename T
, typename U
, typename V
, typename W
, typename X
>
332 inline void HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::remove(RawKeyType key
)
337 template<typename T
, typename U
, typename V
, typename W
, typename X
>
338 inline void HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::clear()
344 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
345 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType
346 HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::take(const KeyType
& key
)
348 // This can probably be made more efficient to avoid ref/deref churn.
349 iterator it
= find(key
);
351 return MappedTraits::emptyValue();
352 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType result
= it
->second
;
357 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
358 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType
359 HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::take(RawKeyType key
)
361 // This can probably be made more efficient to avoid ref/deref churn.
362 iterator it
= find(key
);
364 return MappedTraits::emptyValue();
365 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType result
= it
->second
;