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.
23 // This specialization is a direct copy of HashMap, with overloaded functions
24 // to allow for lookup by pointer instead of RefPtr, avoiding ref-count churn.
26 // FIXME: Find a better way that doesn't require an entire copy of the HashMap template.
28 template<typename RawKeyType
, typename ValueType
, typename ValueTraits
, typename HashFunctions
>
29 struct RefPtrHashMapRawKeyTranslator
{
30 typedef typename
ValueType::first_type KeyType
;
31 typedef typename
ValueType::second_type MappedType
;
32 typedef typename
ValueTraits::FirstTraits KeyTraits
;
33 typedef typename
ValueTraits::SecondTraits MappedTraits
;
35 static unsigned hash(RawKeyType key
) { return HashFunctions::hash(key
); }
36 static bool equal(const KeyType
& a
, RawKeyType b
) { return HashFunctions::equal(a
, b
); }
37 static void translate(ValueType
& location
, RawKeyType key
, const MappedType
& mapped
)
40 location
.second
= mapped
;
44 template<typename T
, typename MappedArg
, typename HashArg
, typename KeyTraitsArg
, typename MappedTraitsArg
>
45 class HashMap
<RefPtr
<T
>, MappedArg
, HashArg
, KeyTraitsArg
, MappedTraitsArg
> : public FastAllocBase
{
47 typedef KeyTraitsArg KeyTraits
;
48 typedef MappedTraitsArg MappedTraits
;
49 typedef PairHashTraits
<KeyTraits
, MappedTraits
> ValueTraits
;
52 typedef typename
KeyTraits::TraitType KeyType
;
53 typedef T
* RawKeyType
;
54 typedef typename
MappedTraits::TraitType MappedType
;
55 typedef typename
ValueTraits::TraitType ValueType
;
58 typedef HashArg HashFunctions
;
60 typedef HashTable
<KeyType
, ValueType
, PairFirstExtractor
<ValueType
>,
61 HashFunctions
, ValueTraits
, KeyTraits
> HashTableType
;
63 typedef RefPtrHashMapRawKeyTranslator
<RawKeyType
, ValueType
, ValueTraits
, HashFunctions
>
67 typedef HashTableIteratorAdapter
<HashTableType
, ValueType
> iterator
;
68 typedef HashTableConstIteratorAdapter
<HashTableType
, ValueType
> const_iterator
;
76 // iterators iterate over pairs of keys and values
79 const_iterator
begin() const;
80 const_iterator
end() const;
82 iterator
find(const KeyType
&);
83 iterator
find(RawKeyType
);
84 const_iterator
find(const KeyType
&) const;
85 const_iterator
find(RawKeyType
) const;
86 bool contains(const KeyType
&) const;
87 bool contains(RawKeyType
) const;
88 MappedType
get(const KeyType
&) const;
89 MappedType
get(RawKeyType
) const;
90 MappedType
inlineGet(RawKeyType
) const;
92 // replaces value but not key if key is already present
93 // return value is a pair of the iterator to the key location,
94 // and a boolean that's true if a new value was actually added
95 pair
<iterator
, bool> set(const KeyType
&, const MappedType
&);
96 pair
<iterator
, bool> set(RawKeyType
, const MappedType
&);
98 // does nothing if key is already present
99 // return value is a pair of the iterator to the key location,
100 // and a boolean that's true if a new value was actually added
101 pair
<iterator
, bool> add(const KeyType
&, const MappedType
&);
102 pair
<iterator
, bool> add(RawKeyType
, const MappedType
&);
104 void remove(const KeyType
&);
105 void remove(RawKeyType
);
106 void remove(iterator
);
109 MappedType
take(const KeyType
&); // efficient combination of get with remove
110 MappedType
take(RawKeyType
); // efficient combination of get with remove
113 pair
<iterator
, bool> inlineAdd(const KeyType
&, const MappedType
&);
114 pair
<iterator
, bool> inlineAdd(RawKeyType
, const MappedType
&);
116 HashTableType m_impl
;
119 template<typename T
, typename U
, typename V
, typename W
, typename X
>
120 inline void HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::swap(HashMap
& other
)
122 m_impl
.swap(other
.m_impl
);
125 template<typename T
, typename U
, typename V
, typename W
, typename X
>
126 inline int HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::size() const
128 return m_impl
.size();
131 template<typename T
, typename U
, typename V
, typename W
, typename X
>
132 inline int HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::capacity() const
134 return m_impl
.capacity();
137 template<typename T
, typename U
, typename V
, typename W
, typename X
>
138 inline bool HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::isEmpty() const
140 return m_impl
.isEmpty();
143 template<typename T
, typename U
, typename V
, typename W
, typename X
>
144 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::begin()
146 return m_impl
.begin();
149 template<typename T
, typename U
, typename V
, typename W
, typename X
>
150 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::end()
155 template<typename T
, typename U
, typename V
, typename W
, typename X
>
156 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::const_iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::begin() const
158 return m_impl
.begin();
161 template<typename T
, typename U
, typename V
, typename W
, typename X
>
162 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::const_iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::end() const
167 template<typename T
, typename U
, typename V
, typename W
, typename X
>
168 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::find(const KeyType
& key
)
170 return m_impl
.find(key
);
173 template<typename T
, typename U
, typename V
, typename W
, typename X
>
174 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::find(RawKeyType key
)
176 return m_impl
.template find
<RawKeyType
, RawKeyTranslator
>(key
);
179 template<typename T
, typename U
, typename V
, typename W
, typename X
>
180 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::const_iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::find(const KeyType
& key
) const
182 return m_impl
.find(key
);
185 template<typename T
, typename U
, typename V
, typename W
, typename X
>
186 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::const_iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::find(RawKeyType key
) const
188 return m_impl
.template find
<RawKeyType
, RawKeyTranslator
>(key
);
191 template<typename T
, typename U
, typename V
, typename W
, typename X
>
192 inline bool HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::contains(const KeyType
& key
) const
194 return m_impl
.contains(key
);
197 template<typename T
, typename U
, typename V
, typename W
, typename X
>
198 inline bool HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::contains(RawKeyType key
) const
200 return m_impl
.template contains
<RawKeyType
, RawKeyTranslator
>(key
);
203 template<typename T
, typename U
, typename V
, typename W
, typename X
>
204 inline pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
205 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::inlineAdd(const KeyType
& key
, const MappedType
& mapped
)
207 typedef HashMapTranslator
<ValueType
, ValueTraits
, HashFunctions
> TranslatorType
;
208 return m_impl
.template add
<KeyType
, MappedType
, TranslatorType
>(key
, mapped
);
211 template<typename T
, typename U
, typename V
, typename W
, typename X
>
212 inline pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
213 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::inlineAdd(RawKeyType key
, const MappedType
& mapped
)
215 return m_impl
.template add
<RawKeyType
, MappedType
, RawKeyTranslator
>(key
, mapped
);
218 template<typename T
, typename U
, typename V
, typename W
, typename X
>
219 pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
220 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::set(const KeyType
& key
, const MappedType
& mapped
)
222 pair
<iterator
, bool> result
= inlineAdd(key
, mapped
);
223 if (!result
.second
) {
224 // add call above didn't change anything, so set the mapped value
225 result
.first
->second
= mapped
;
230 template<typename T
, typename U
, typename V
, typename W
, typename X
>
231 pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
232 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::set(RawKeyType key
, const MappedType
& mapped
)
234 pair
<iterator
, bool> result
= inlineAdd(key
, mapped
);
235 if (!result
.second
) {
236 // add call above didn't change anything, so set the mapped value
237 result
.first
->second
= mapped
;
242 template<typename T
, typename U
, typename V
, typename W
, typename X
>
243 pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
244 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::add(const KeyType
& key
, const MappedType
& mapped
)
246 return inlineAdd(key
, mapped
);
249 template<typename T
, typename U
, typename V
, typename W
, typename X
>
250 pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
251 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::add(RawKeyType key
, const MappedType
& mapped
)
253 return inlineAdd(key
, mapped
);
256 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
257 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType
258 HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::get(const KeyType
& key
) const
260 ValueType
* entry
= const_cast<HashTableType
&>(m_impl
).lookup(key
);
262 return MappedTraits::emptyValue();
263 return entry
->second
;
266 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
267 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType
268 inline HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::inlineGet(RawKeyType key
) const
270 ValueType
* entry
= const_cast<HashTableType
&>(m_impl
).template lookup
<RawKeyType
, RawKeyTranslator
>(key
);
272 return MappedTraits::emptyValue();
273 return entry
->second
;
276 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
277 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType
278 HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::get(RawKeyType key
) const
280 return inlineGet(key
);
283 template<typename T
, typename U
, typename V
, typename W
, typename X
>
284 inline void HashMap
<RefPtr
<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
<RefPtr
<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
<RefPtr
<T
>, U
, V
, W
, X
>::remove(RawKeyType key
)
304 template<typename T
, typename U
, typename V
, typename W
, typename X
>
305 inline void HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::clear()
310 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
311 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType
312 HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::take(const KeyType
& key
)
314 // This can probably be made more efficient to avoid ref/deref churn.
315 iterator it
= find(key
);
317 return MappedTraits::emptyValue();
318 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType result
= it
->second
;
323 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
324 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType
325 HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::take(RawKeyType key
)
327 // This can probably be made more efficient to avoid ref/deref churn.
328 iterator it
= find(key
);
330 return MappedTraits::emptyValue();
331 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType result
= it
->second
;