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 T
> struct IdentityExtractor
;
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
>&);
35 template<typename ValueArg
, typename HashArg
= typename DefaultHash
<ValueArg
>::Hash
,
36 typename TraitsArg
= HashTraits
<ValueArg
> > class HashSet
{
38 typedef HashArg HashFunctions
;
39 typedef TraitsArg ValueTraits
;
41 typedef typename HashKeyStorageTraits
<HashFunctions
, ValueTraits
>::Hash StorageHashFunctions
;
43 typedef typename HashKeyStorageTraits
<HashFunctions
, ValueTraits
>::Traits StorageTraits
;
44 typedef typename
StorageTraits::TraitType StorageType
;
46 typedef HashTable
<StorageType
, StorageType
, IdentityExtractor
<StorageType
>,
47 StorageHashFunctions
, StorageTraits
, StorageTraits
> HashTableType
;
50 typedef typename
ValueTraits::TraitType ValueType
;
51 typedef HashTableIteratorAdapter
<HashTableType
, ValueType
> iterator
;
52 typedef HashTableConstIteratorAdapter
<HashTableType
, ValueType
> const_iterator
;
55 HashSet(const HashSet
&);
56 HashSet
& operator=(const HashSet
&);
67 const_iterator
begin() const;
68 const_iterator
end() const;
70 iterator
find(const ValueType
&);
71 const_iterator
find(const ValueType
&) const;
72 bool contains(const ValueType
&) const;
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
&);
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
&);
86 void remove(const ValueType
&);
87 void remove(iterator
);
94 friend void deleteAllValues
<>(const HashSet
&);
99 template<typename T
> struct IdentityExtractor
{
100 static const T
& extract(const T
& t
) { return t
; }
103 template<bool canReplaceDeletedValue
, typename ValueType
, typename ValueTraits
, typename StorageTraits
, typename HashFunctions
>
104 struct HashSetTranslator
;
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
&)
113 Assigner
<ValueTraits::needsRef
, ValueType
, StorageType
, ValueTraits
>::assign(key
, location
);
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
&)
124 if (location
== StorageTraits::deletedValue())
125 location
= StorageTraits::emptyValue();
126 Assigner
<ValueTraits::needsRef
, ValueType
, StorageType
, ValueTraits
>::assign(key
, location
);
130 template<bool canReplaceDeletedValue
, typename ValueType
, typename StorageTraits
, typename T
, typename Translator
>
131 struct HashSetTranslatorAdapter
;
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
)
140 Translator::translate(*(ValueType
*)&location
, key
, hashCode
);
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
)
151 if (location
== StorageTraits::deletedValue())
152 location
= StorageTraits::emptyValue();
153 Translator::translate(*(ValueType
*)&location
, key
, hashCode
);
157 template<typename T
, typename U
, typename V
>
158 inline void HashSet
<T
, U
, V
>::refAll()
160 HashTableRefCounter
<HashTableType
, ValueTraits
>::refAll(m_impl
);
163 template<typename T
, typename U
, typename V
>
164 inline void HashSet
<T
, U
, V
>::derefAll()
166 HashTableRefCounter
<HashTableType
, ValueTraits
>::derefAll(m_impl
);
169 template<typename T
, typename U
, typename V
>
170 inline HashSet
<T
, U
, V
>::HashSet()
174 template<typename T
, typename U
, typename V
>
175 inline HashSet
<T
, U
, V
>::HashSet(const HashSet
& other
)
176 : m_impl(other
.m_impl
)
181 template<typename T
, typename U
, typename V
>
182 inline HashSet
<T
, U
, V
>& HashSet
<T
, U
, V
>::operator=(const HashSet
& other
)
189 template<typename T
, typename U
, typename V
>
190 inline void HashSet
<T
, U
, V
>::swap(HashSet
& other
)
192 m_impl
.swap(other
.m_impl
);
195 template<typename T
, typename U
, typename V
>
196 inline HashSet
<T
, U
, V
>::~HashSet()
201 template<typename T
, typename U
, typename V
>
202 inline int HashSet
<T
, U
, V
>::size() const
204 return m_impl
.size();
207 template<typename T
, typename U
, typename V
>
208 inline int HashSet
<T
, U
, V
>::capacity() const
210 return m_impl
.capacity();
213 template<typename T
, typename U
, typename V
>
214 inline bool HashSet
<T
, U
, V
>::isEmpty() const
216 return m_impl
.isEmpty();
219 template<typename T
, typename U
, typename V
>
220 inline typename HashSet
<T
, U
, V
>::iterator HashSet
<T
, U
, V
>::begin()
222 return m_impl
.begin();
225 template<typename T
, typename U
, typename V
>
226 inline typename HashSet
<T
, U
, V
>::iterator HashSet
<T
, U
, V
>::end()
231 template<typename T
, typename U
, typename V
>
232 inline typename HashSet
<T
, U
, V
>::const_iterator HashSet
<T
, U
, V
>::begin() const
234 return m_impl
.begin();
237 template<typename T
, typename U
, typename V
>
238 inline typename HashSet
<T
, U
, V
>::const_iterator HashSet
<T
, U
, V
>::end() const
243 template<typename T
, typename U
, typename V
>
244 inline typename HashSet
<T
, U
, V
>::iterator HashSet
<T
, U
, V
>::find(const ValueType
& value
)
246 return m_impl
.find(*(const StorageType
*)&value
);
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
252 return m_impl
.find(*(const StorageType
*)&value
);
255 template<typename T
, typename U
, typename V
>
256 inline bool HashSet
<T
, U
, V
>::contains(const ValueType
& value
) const
258 return m_impl
.contains(*(const StorageType
*)&value
);
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
)
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
);
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
)
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
);
279 template<typename T
, typename U
, typename V
>
280 inline void HashSet
<T
, U
, V
>::remove(iterator it
)
282 if (it
.m_impl
== m_impl
.end())
284 m_impl
.checkTableConsistency();
285 RefCounter
<ValueTraits
, StorageTraits
>::deref(*it
.m_impl
);
286 m_impl
.removeWithoutEntryConsistencyCheck(it
.m_impl
);
289 template<typename T
, typename U
, typename V
>
290 inline void HashSet
<T
, U
, V
>::remove(const ValueType
& value
)
295 template<typename T
, typename U
, typename V
>
296 inline void HashSet
<T
, U
, V
>::clear()
302 template<typename ValueType
, typename HashTableType
>
303 void deleteAllValues(HashTableType
& collection
)
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
;
311 template<typename T
, typename U
, typename V
>
312 inline void deleteAllValues(const HashSet
<T
, U
, V
>& collection
)
314 deleteAllValues
<typename HashSet
<T
, U
, V
>::ValueType
>(collection
.m_impl
);
317 template<typename T
, typename U
, typename V
, typename W
>
318 inline void copyToVector(const HashSet
<T
, U
, V
>& collection
, W
& vector
)
320 typedef typename HashSet
<T
, U
, V
>::const_iterator iterator
;
322 vector
.resize(collection
.size());
324 iterator it
= collection
.begin();
325 iterator end
= collection
.end();
326 for (unsigned i
= 0; it
!= end
; ++it
, ++i
)
334 #endif /* WTF_HashSet_h */