]> git.saurik.com Git - apple/javascriptcore.git/blob - wtf/HashSet.h
JavaScriptCore-466.1.6.tar.gz
[apple/javascriptcore.git] / wtf / HashSet.h
1 // -*- mode: c++; c-basic-offset: 4 -*-
2 /*
3 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
4 *
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.
9 *
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.
14 *
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.
19 *
20 */
21
22 #ifndef WTF_HashSet_h
23 #define WTF_HashSet_h
24
25 #include "HashTable.h"
26
27 namespace WTF {
28
29 template<typename T> struct IdentityExtractor;
30
31 template<typename Value, typename HashFunctions, typename Traits> class HashSet;
32 template<typename Value, typename HashFunctions, typename Traits>
33 void deleteAllValues(const HashSet<Value, HashFunctions, Traits>&);
34
35 template<typename ValueArg, typename HashArg = typename DefaultHash<ValueArg>::Hash,
36 typename TraitsArg = HashTraits<ValueArg> > class HashSet {
37 private:
38 typedef HashArg HashFunctions;
39 typedef TraitsArg ValueTraits;
40
41 typedef typename HashKeyStorageTraits<HashFunctions, ValueTraits>::Hash StorageHashFunctions;
42
43 typedef typename HashKeyStorageTraits<HashFunctions, ValueTraits>::Traits StorageTraits;
44 typedef typename StorageTraits::TraitType StorageType;
45
46 typedef HashTable<StorageType, StorageType, IdentityExtractor<StorageType>,
47 StorageHashFunctions, StorageTraits, StorageTraits> HashTableType;
48
49 public:
50 typedef typename ValueTraits::TraitType ValueType;
51 typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator;
52 typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator;
53
54 HashSet();
55 HashSet(const HashSet&);
56 HashSet& operator=(const HashSet&);
57 ~HashSet();
58
59 void swap(HashSet&);
60
61 int size() const;
62 int capacity() const;
63 bool isEmpty() const;
64
65 iterator begin();
66 iterator end();
67 const_iterator begin() const;
68 const_iterator end() const;
69
70 iterator find(const ValueType&);
71 const_iterator find(const ValueType&) const;
72 bool contains(const ValueType&) const;
73
74 // the return value is a pair of an interator to the new value's location,
75 // and a bool that is true if an new entry was added
76 pair<iterator, bool> add(const ValueType&);
77
78 // a special version of add() that finds the object by hashing and comparing
79 // with some other type, to avoid the cost of type conversion if the object is already
80 // in the table. HashTranslator should have the following methods:
81 // static unsigned hash(const T&);
82 // static bool equal(const ValueType&, const T&);
83 // static translate(ValueType&, const T&, unsigned hashCode);
84 template<typename T, typename HashTranslator> pair<iterator, bool> add(const T&);
85
86 void remove(const ValueType&);
87 void remove(iterator);
88 void clear();
89
90 private:
91 void refAll();
92 void derefAll();
93
94 friend void deleteAllValues<>(const HashSet&);
95
96 HashTableType m_impl;
97 };
98
99 template<typename T> struct IdentityExtractor {
100 static const T& extract(const T& t) { return t; }
101 };
102
103 template<bool canReplaceDeletedValue, typename ValueType, typename ValueTraits, typename StorageTraits, typename HashFunctions>
104 struct HashSetTranslator;
105
106 template<typename ValueType, typename ValueTraits, typename StorageTraits, typename HashFunctions>
107 struct HashSetTranslator<true, ValueType, ValueTraits, StorageTraits, HashFunctions> {
108 typedef typename StorageTraits::TraitType StorageType;
109 static unsigned hash(const ValueType& key) { return HashFunctions::hash(key); }
110 static bool equal(const StorageType& a, const ValueType& b) { return HashFunctions::equal(*(const ValueType*)&a, b); }
111 static void translate(StorageType& location, const ValueType& key, const ValueType&)
112 {
113 Assigner<ValueTraits::needsRef, ValueType, StorageType, ValueTraits>::assign(key, location);
114 }
115 };
116
117 template<typename ValueType, typename ValueTraits, typename StorageTraits, typename HashFunctions>
118 struct HashSetTranslator<false, ValueType, ValueTraits, StorageTraits, HashFunctions> {
119 typedef typename StorageTraits::TraitType StorageType;
120 static unsigned hash(const ValueType& key) { return HashFunctions::hash(key); }
121 static bool equal(const StorageType& a, const ValueType& b) { return HashFunctions::equal(*(const ValueType*)&a, b); }
122 static void translate(StorageType& location, const ValueType& key, const ValueType&)
123 {
124 if (location == StorageTraits::deletedValue())
125 location = StorageTraits::emptyValue();
126 Assigner<ValueTraits::needsRef, ValueType, StorageType, ValueTraits>::assign(key, location);
127 }
128 };
129
130 template<bool canReplaceDeletedValue, typename ValueType, typename StorageTraits, typename T, typename Translator>
131 struct HashSetTranslatorAdapter;
132
133 template<typename ValueType, typename StorageTraits, typename T, typename Translator>
134 struct HashSetTranslatorAdapter<true, ValueType, StorageTraits, T, Translator> {
135 typedef typename StorageTraits::TraitType StorageType;
136 static unsigned hash(const T& key) { return Translator::hash(key); }
137 static bool equal(const StorageType& a, const T& b) { return Translator::equal(*(const ValueType*)&a, b); }
138 static void translate(StorageType& location, const T& key, const T&, unsigned hashCode)
139 {
140 Translator::translate(*(ValueType*)&location, key, hashCode);
141 }
142 };
143
144 template<typename ValueType, typename StorageTraits, typename T, typename Translator>
145 struct HashSetTranslatorAdapter<false, ValueType, StorageTraits, T, Translator> {
146 typedef typename StorageTraits::TraitType StorageType;
147 static unsigned hash(const T& key) { return Translator::hash(key); }
148 static bool equal(const StorageType& a, const T& b) { return Translator::equal(*(const ValueType*)&a, b); }
149 static void translate(StorageType& location, const T& key, const T&, unsigned hashCode)
150 {
151 if (location == StorageTraits::deletedValue())
152 location = StorageTraits::emptyValue();
153 Translator::translate(*(ValueType*)&location, key, hashCode);
154 }
155 };
156
157 template<typename T, typename U, typename V>
158 inline void HashSet<T, U, V>::refAll()
159 {
160 HashTableRefCounter<HashTableType, ValueTraits>::refAll(m_impl);
161 }
162
163 template<typename T, typename U, typename V>
164 inline void HashSet<T, U, V>::derefAll()
165 {
166 HashTableRefCounter<HashTableType, ValueTraits>::derefAll(m_impl);
167 }
168
169 template<typename T, typename U, typename V>
170 inline HashSet<T, U, V>::HashSet()
171 {
172 }
173
174 template<typename T, typename U, typename V>
175 inline HashSet<T, U, V>::HashSet(const HashSet& other)
176 : m_impl(other.m_impl)
177 {
178 refAll();
179 }
180
181 template<typename T, typename U, typename V>
182 inline HashSet<T, U, V>& HashSet<T, U, V>::operator=(const HashSet& other)
183 {
184 HashSet tmp(other);
185 swap(tmp);
186 return *this;
187 }
188
189 template<typename T, typename U, typename V>
190 inline void HashSet<T, U, V>::swap(HashSet& other)
191 {
192 m_impl.swap(other.m_impl);
193 }
194
195 template<typename T, typename U, typename V>
196 inline HashSet<T, U, V>::~HashSet()
197 {
198 derefAll();
199 }
200
201 template<typename T, typename U, typename V>
202 inline int HashSet<T, U, V>::size() const
203 {
204 return m_impl.size();
205 }
206
207 template<typename T, typename U, typename V>
208 inline int HashSet<T, U, V>::capacity() const
209 {
210 return m_impl.capacity();
211 }
212
213 template<typename T, typename U, typename V>
214 inline bool HashSet<T, U, V>::isEmpty() const
215 {
216 return m_impl.isEmpty();
217 }
218
219 template<typename T, typename U, typename V>
220 inline typename HashSet<T, U, V>::iterator HashSet<T, U, V>::begin()
221 {
222 return m_impl.begin();
223 }
224
225 template<typename T, typename U, typename V>
226 inline typename HashSet<T, U, V>::iterator HashSet<T, U, V>::end()
227 {
228 return m_impl.end();
229 }
230
231 template<typename T, typename U, typename V>
232 inline typename HashSet<T, U, V>::const_iterator HashSet<T, U, V>::begin() const
233 {
234 return m_impl.begin();
235 }
236
237 template<typename T, typename U, typename V>
238 inline typename HashSet<T, U, V>::const_iterator HashSet<T, U, V>::end() const
239 {
240 return m_impl.end();
241 }
242
243 template<typename T, typename U, typename V>
244 inline typename HashSet<T, U, V>::iterator HashSet<T, U, V>::find(const ValueType& value)
245 {
246 return m_impl.find(*(const StorageType*)&value);
247 }
248
249 template<typename T, typename U, typename V>
250 inline typename HashSet<T, U, V>::const_iterator HashSet<T, U, V>::find(const ValueType& value) const
251 {
252 return m_impl.find(*(const StorageType*)&value);
253 }
254
255 template<typename T, typename U, typename V>
256 inline bool HashSet<T, U, V>::contains(const ValueType& value) const
257 {
258 return m_impl.contains(*(const StorageType*)&value);
259 }
260
261 template<typename T, typename U, typename V>
262 pair<typename HashSet<T, U, V>::iterator, bool> HashSet<T, U, V>::add(const ValueType &value)
263 {
264 const bool canReplaceDeletedValue = !ValueTraits::needsDestruction || StorageTraits::needsDestruction;
265 typedef HashSetTranslator<canReplaceDeletedValue, ValueType, ValueTraits, StorageTraits, HashFunctions> Translator;
266 return m_impl.template add<ValueType, ValueType, Translator>(value, value);
267 }
268
269 template<typename Value, typename HashFunctions, typename Traits>
270 template<typename T, typename Translator>
271 pair<typename HashSet<Value, HashFunctions, Traits>::iterator, bool>
272 HashSet<Value, HashFunctions, Traits>::add(const T& value)
273 {
274 const bool canReplaceDeletedValue = !ValueTraits::needsDestruction || StorageTraits::needsDestruction;
275 typedef HashSetTranslatorAdapter<canReplaceDeletedValue, ValueType, StorageTraits, T, Translator> Adapter;
276 return m_impl.template addPassingHashCode<T, T, Adapter>(value, value);
277 }
278
279 template<typename T, typename U, typename V>
280 inline void HashSet<T, U, V>::remove(iterator it)
281 {
282 if (it.m_impl == m_impl.end())
283 return;
284 m_impl.checkTableConsistency();
285 RefCounter<ValueTraits, StorageTraits>::deref(*it.m_impl);
286 m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
287 }
288
289 template<typename T, typename U, typename V>
290 inline void HashSet<T, U, V>::remove(const ValueType& value)
291 {
292 remove(find(value));
293 }
294
295 template<typename T, typename U, typename V>
296 inline void HashSet<T, U, V>::clear()
297 {
298 derefAll();
299 m_impl.clear();
300 }
301
302 template<typename ValueType, typename HashTableType>
303 void deleteAllValues(HashTableType& collection)
304 {
305 typedef typename HashTableType::const_iterator iterator;
306 iterator end = collection.end();
307 for (iterator it = collection.begin(); it != end; ++it)
308 delete *(ValueType*)&*it;
309 }
310
311 template<typename T, typename U, typename V>
312 inline void deleteAllValues(const HashSet<T, U, V>& collection)
313 {
314 deleteAllValues<typename HashSet<T, U, V>::ValueType>(collection.m_impl);
315 }
316
317 template<typename T, typename U, typename V, typename W>
318 inline void copyToVector(const HashSet<T, U, V>& collection, W& vector)
319 {
320 typedef typename HashSet<T, U, V>::const_iterator iterator;
321
322 vector.resize(collection.size());
323
324 iterator it = collection.begin();
325 iterator end = collection.end();
326 for (unsigned i = 0; it != end; ++it, ++i)
327 vector[i] = *it;
328 }
329
330 } // namespace WTF
331
332 using WTF::HashSet;
333
334 #endif /* WTF_HashSet_h */