00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef WTF_HashMap_h
00025 #define WTF_HashMap_h
00026
00027 #include "HashTable.h"
00028
00029 namespace WTF {
00030
00031 template<typename PairType> struct PairFirstExtractor;
00032
00033 template<typename KeyArg, typename MappedArg, typename HashArg = typename DefaultHash<KeyArg>::Hash,
00034 typename KeyTraitsArg = HashTraits<KeyArg>, typename MappedTraitsArg = HashTraits<MappedArg> >
00035 class HashMap {
00036 private:
00037 typedef KeyTraitsArg KeyTraits;
00038 typedef MappedTraitsArg MappedTraits;
00039 typedef PairBaseHashTraits<KeyTraits, MappedTraits> ValueTraits;
00040
00041 public:
00042 typedef typename KeyTraits::TraitType KeyType;
00043 typedef typename MappedTraits::TraitType MappedType;
00044 typedef typename ValueTraits::TraitType ValueType;
00045
00046 private:
00047 typedef HashArg HashFunctions;
00048
00049 typedef typename HashKeyStorageTraits<HashFunctions, KeyTraits>::Hash StorageHashFunctions;
00050
00051 typedef typename HashKeyStorageTraits<HashFunctions, KeyTraits>::Traits KeyStorageTraits;
00052 typedef typename MappedTraits::StorageTraits MappedStorageTraits;
00053 typedef PairHashTraits<KeyStorageTraits, MappedStorageTraits> ValueStorageTraits;
00054
00055 typedef typename KeyStorageTraits::TraitType KeyStorageType;
00056 typedef typename MappedStorageTraits::TraitType MappedStorageType;
00057 typedef typename ValueStorageTraits::TraitType ValueStorageType;
00058
00059 typedef HashTable<KeyStorageType, ValueStorageType, PairFirstExtractor<ValueStorageType>,
00060 StorageHashFunctions, ValueStorageTraits, KeyStorageTraits> HashTableType;
00061
00062 public:
00063 typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator;
00064 typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator;
00065
00066 HashMap();
00067 HashMap(const HashMap&);
00068 HashMap& operator=(const HashMap&);
00069 ~HashMap();
00070
00071 void swap(HashMap&);
00072
00073 int size() const;
00074 int capacity() const;
00075 bool isEmpty() const;
00076
00077
00078 iterator begin();
00079 iterator end();
00080 const_iterator begin() const;
00081 const_iterator end() const;
00082
00083 iterator find(const KeyType&);
00084 const_iterator find(const KeyType&) const;
00085 bool contains(const KeyType&) const;
00086 MappedType get(const KeyType&) const;
00087
00088
00089
00090
00091 pair<iterator, bool> set(const KeyType&, const MappedType&);
00092
00093
00094
00095
00096 pair<iterator, bool> add(const KeyType&, const MappedType&);
00097
00098 void remove(const KeyType&);
00099 void remove(iterator it);
00100 void clear();
00101
00102 private:
00103 pair<iterator, bool> inlineAdd(const KeyType&, const MappedType&);
00104 void refAll();
00105 void derefAll();
00106
00107 HashTableType m_impl;
00108 };
00109
00110 template<typename PairType> struct PairFirstExtractor {
00111 static const typename PairType::first_type& extract(const PairType& p) { return p.first; }
00112 };
00113
00114 template<bool canReplaceDeletedKey, typename ValueType, typename ValueTraits, typename ValueStorageTraits, typename HashFunctions>
00115 struct HashMapTranslator;
00116
00117 template<typename ValueType, typename ValueTraits, typename ValueStorageTraits, typename HashFunctions>
00118 struct HashMapTranslator<true, ValueType, ValueTraits, ValueStorageTraits, HashFunctions> {
00119 typedef typename ValueType::first_type KeyType;
00120 typedef typename ValueType::second_type MappedType;
00121 typedef typename ValueStorageTraits::TraitType ValueStorageType;
00122 typedef typename ValueStorageTraits::FirstTraits KeyStorageTraits;
00123 typedef typename KeyStorageTraits::TraitType KeyStorageType;
00124 typedef typename ValueStorageTraits::SecondTraits MappedStorageTraits;
00125 typedef typename MappedStorageTraits::TraitType MappedStorageType;
00126 typedef typename ValueTraits::FirstTraits KeyTraits;
00127 typedef typename ValueTraits::SecondTraits MappedTraits;
00128
00129 static unsigned hash(const KeyType& key) { return HashFunctions::hash(key); }
00130 static bool equal(const KeyStorageType& a, const KeyType& b) { return HashFunctions::equal(*(KeyType*)&a, b); }
00131 static void translate(ValueStorageType& location, const KeyType& key, const MappedType& mapped, unsigned)
00132 {
00133 Assigner<KeyTraits::needsRef, KeyType, KeyStorageType, KeyTraits>::assign(key, location.first);
00134 Assigner<MappedTraits::needsRef, MappedType, MappedStorageType, MappedTraits>::assign(mapped, location.second);
00135 }
00136 };
00137
00138 template<typename ValueType, typename ValueTraits, typename ValueStorageTraits, typename HashFunctions>
00139 struct HashMapTranslator<false, ValueType, ValueTraits, ValueStorageTraits, HashFunctions> {
00140 typedef typename ValueType::first_type KeyType;
00141 typedef typename ValueType::second_type MappedType;
00142 typedef typename ValueStorageTraits::TraitType ValueStorageType;
00143 typedef typename ValueStorageTraits::FirstTraits KeyStorageTraits;
00144 typedef typename KeyStorageTraits::TraitType KeyStorageType;
00145 typedef typename ValueStorageTraits::SecondTraits MappedStorageTraits;
00146 typedef typename MappedStorageTraits::TraitType MappedStorageType;
00147 typedef typename ValueTraits::FirstTraits KeyTraits;
00148 typedef typename ValueTraits::SecondTraits MappedTraits;
00149
00150 static unsigned hash(const KeyType& key) { return HashFunctions::hash(key); }
00151 static bool equal(const KeyStorageType& a, const KeyType& b) { return HashFunctions::equal(*(KeyType*)&a, b); }
00152 static void translate(ValueStorageType& location, const KeyType& key, const MappedType& mapped, unsigned)
00153 {
00154 if (location.first == KeyStorageTraits::deletedValue())
00155 location.first = KeyStorageTraits::emptyValue();
00156 Assigner<KeyTraits::needsRef, KeyType, KeyStorageType, KeyTraits>::assign(key, location.first);
00157 Assigner<MappedTraits::needsRef, MappedType, MappedStorageType, MappedTraits>::assign(mapped, location.second);
00158 }
00159 };
00160
00161 template<typename T, typename U, typename V, typename W, typename X>
00162 inline void HashMap<T, U, V, W, X>::refAll()
00163 {
00164 HashTableRefCounter<HashTableType, ValueTraits>::refAll(m_impl);
00165 }
00166
00167 template<typename T, typename U, typename V, typename W, typename X>
00168 inline void HashMap<T, U, V, W, X>::derefAll()
00169 {
00170 HashTableRefCounter<HashTableType, ValueTraits>::derefAll(m_impl);
00171 }
00172
00173 template<typename T, typename U, typename V, typename W, typename X>
00174 inline HashMap<T, U, V, W, X>::HashMap()
00175 {
00176 }
00177
00178 template<typename T, typename U, typename V, typename W, typename X>
00179 inline HashMap<T, U, V, W, X>::HashMap(const HashMap& other)
00180 : m_impl(other.m_impl)
00181 {
00182 refAll();
00183 }
00184
00185 template<typename T, typename U, typename V, typename W, typename X>
00186 inline HashMap<T, U, V, W, X>& HashMap<T, U, V, W, X>::operator=(const HashMap& other)
00187 {
00188 HashMap tmp(other);
00189 swap(tmp);
00190 return *this;
00191 }
00192
00193 template<typename T, typename U, typename V, typename W, typename X>
00194 inline void HashMap<T, U, V, W, X>::swap(HashMap& other)
00195 {
00196 m_impl.swap(other.m_impl);
00197 }
00198
00199 template<typename T, typename U, typename V, typename W, typename X>
00200 inline HashMap<T, U, V, W, X>::~HashMap()
00201 {
00202 derefAll();
00203 }
00204
00205 template<typename T, typename U, typename V, typename W, typename X>
00206 inline int HashMap<T, U, V, W, X>::size() const
00207 {
00208 return m_impl.size();
00209 }
00210
00211 template<typename T, typename U, typename V, typename W, typename X>
00212 inline int HashMap<T, U, V, W, X>::capacity() const
00213 {
00214 return m_impl.capacity();
00215 }
00216
00217 template<typename T, typename U, typename V, typename W, typename X>
00218 inline bool HashMap<T, U, V, W, X>::isEmpty() const
00219 {
00220 return m_impl.isEmpty();
00221 }
00222
00223 template<typename T, typename U, typename V, typename W, typename X>
00224 inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::begin()
00225 {
00226 return m_impl.begin();
00227 }
00228
00229 template<typename T, typename U, typename V, typename W, typename X>
00230 inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::end()
00231 {
00232 return m_impl.end();
00233 }
00234
00235 template<typename T, typename U, typename V, typename W, typename X>
00236 inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::begin() const
00237 {
00238 return m_impl.begin();
00239 }
00240
00241 template<typename T, typename U, typename V, typename W, typename X>
00242 inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::end() const
00243 {
00244 return m_impl.end();
00245 }
00246
00247 template<typename T, typename U, typename V, typename W, typename X>
00248 inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::find(const KeyType& key)
00249 {
00250 return m_impl.find(*(const KeyStorageType*)&key);
00251 }
00252
00253 template<typename T, typename U, typename V, typename W, typename X>
00254 inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::find(const KeyType& key) const
00255 {
00256 return m_impl.find(*(const KeyStorageType*)&key);
00257 }
00258
00259 template<typename T, typename U, typename V, typename W, typename X>
00260 inline bool HashMap<T, U, V, W, X>::contains(const KeyType& key) const
00261 {
00262 return m_impl.contains(*(const KeyStorageType*)&key);
00263 }
00264
00265 template<typename T, typename U, typename V, typename W, typename X>
00266 inline pair<typename HashMap<T, U, V, W, X>::iterator, bool>
00267 HashMap<T, U, V, W, X>::inlineAdd(const KeyType& key, const MappedType& mapped)
00268 {
00269 const bool canReplaceDeletedKey = !KeyTraits::needsDestruction || KeyStorageTraits::needsDestruction;
00270 typedef HashMapTranslator<canReplaceDeletedKey, ValueType, ValueTraits, ValueStorageTraits, HashFunctions> TranslatorType;
00271 return m_impl.template add<KeyType, MappedType, TranslatorType>(key, mapped);
00272 }
00273
00274 template<typename T, typename U, typename V, typename W, typename X>
00275 pair<typename HashMap<T, U, V, W, X>::iterator, bool>
00276 HashMap<T, U, V, W, X>::set(const KeyType& key, const MappedType& mapped)
00277 {
00278 pair<iterator, bool> result = inlineAdd(key, mapped);
00279 if (!result.second)
00280
00281 result.first->second = mapped;
00282 return result;
00283 }
00284
00285 template<typename T, typename U, typename V, typename W, typename X>
00286 pair<typename HashMap<T, U, V, W, X>::iterator, bool>
00287 HashMap<T, U, V, W, X>::add(const KeyType& key, const MappedType& mapped)
00288 {
00289 return inlineAdd(key, mapped);
00290 }
00291
00292 template<typename T, typename U, typename V, typename W, typename MappedTraits>
00293 inline typename HashMap<T, U, V, W, MappedTraits>::MappedType
00294 HashMap<T, U, V, W, MappedTraits>::get(const KeyType& key) const
00295 {
00296 const_iterator it = find(key);
00297 if (it == end())
00298 return MappedTraits::emptyValue();
00299 return it->second;
00300 }
00301
00302 template<typename T, typename U, typename V, typename W, typename X>
00303 inline void HashMap<T, U, V, W, X>::remove(iterator it)
00304 {
00305 if (it.m_impl == m_impl.end())
00306 return;
00307 RefCounter<ValueTraits, ValueStorageTraits>::deref(*it.m_impl);
00308 m_impl.remove(it.m_impl);
00309 }
00310
00311 template<typename T, typename U, typename V, typename W, typename X>
00312 inline void HashMap<T, U, V, W, X>::remove(const KeyType& key)
00313 {
00314 remove(find(key));
00315 }
00316
00317 template<typename T, typename U, typename V, typename W, typename X>
00318 inline void HashMap<T, U, V, W, X>::clear()
00319 {
00320 derefAll();
00321 m_impl.clear();
00322 }
00323
00324 template<typename T, typename U, typename V, typename W, typename X>
00325 bool operator==(const HashMap<T, U, V, W, X>& a, const HashMap<T, U, V, W, X>& b)
00326 {
00327 if (a.size() != b.size())
00328 return false;
00329
00330 typedef typename HashMap<T, U, V, W, X>::const_iterator const_iterator;
00331
00332 const_iterator end = a.end();
00333 const_iterator notFound = b.end();
00334 for (const_iterator it = a.begin(); it != end; ++it) {
00335 const_iterator bPos = b.find(it->first);
00336 if (bPos == notFound || it->second != bPos->second)
00337 return false;
00338 }
00339
00340 return true;
00341 }
00342
00343 template<typename T, typename U, typename V, typename W, typename X>
00344 inline bool operator!=(const HashMap<T, U, V, W, X>& a, const HashMap<T, U, V, W, X>& b)
00345 {
00346 return !(a == b);
00347 }
00348
00349 template<typename MappedType, typename HashTableType>
00350 void deleteAllPairSeconds(HashTableType& collection)
00351 {
00352 typedef typename HashTableType::const_iterator iterator;
00353 iterator end = collection.end();
00354 for (iterator it = collection.begin(); it != end; ++it)
00355 delete *(MappedType*)&it->second;
00356 }
00357
00358 template<typename T, typename U, typename V, typename W, typename X>
00359 inline void deleteAllValues(const HashMap<T, U, V, W, X>& collection)
00360 {
00361 deleteAllPairSeconds<typename HashMap<T, U, V, W, X>::MappedType>(collection);
00362 }
00363
00364 template<typename KeyType, typename HashTableType>
00365 void deleteAllPairFirsts(HashTableType& collection)
00366 {
00367 typedef typename HashTableType::const_iterator iterator;
00368 iterator end = collection.end();
00369 for (iterator it = collection.begin(); it != end; ++it)
00370 delete *(KeyType*)&it->first;
00371 }
00372
00373 template<typename T, typename U, typename V, typename W, typename X>
00374 inline void deleteAllKeys(const HashMap<T, U, V, W, X>& collection)
00375 {
00376 deleteAllPairFirsts<typename HashMap<T, U, V, W, X>::KeyType>(collection);
00377 }
00378
00379 }
00380
00381 using WTF::HashMap;
00382
00383 #endif