| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "wtf/HashTable.h" | 24 #include "wtf/HashTable.h" |
| 25 #include "wtf/PartitionAllocator.h" | 25 #include "wtf/PartitionAllocator.h" |
| 26 | 26 |
| 27 namespace WTF { | 27 namespace WTF { |
| 28 | 28 |
| 29 struct IdentityExtractor; | 29 struct IdentityExtractor; |
| 30 | 30 |
| 31 // Note: empty or deleted values are not allowed, using them may lead to | 31 // Note: empty or deleted values are not allowed, using them may lead to |
| 32 // undefined behavior. For pointer valuess this means that null pointers are | 32 // undefined behavior. For pointer valuess this means that null pointers are |
| 33 // not allowed unless you supply custom traits. | 33 // not allowed unless you supply custom traits. |
| 34 template < | 34 template <typename ValueArg, |
| 35 typename ValueArg, | 35 typename HashArg = typename DefaultHash<ValueArg>::Hash, |
| 36 typename HashArg = typename DefaultHash<ValueArg>::Hash, | 36 typename TraitsArg = HashTraits<ValueArg>, |
| 37 typename TraitsArg = HashTraits<ValueArg>, | 37 typename Allocator = PartitionAllocator> |
| 38 typename Allocator = PartitionAllocator> | |
| 39 class HashSet { | 38 class HashSet { |
| 40 WTF_USE_ALLOCATOR(HashSet, Allocator); | 39 WTF_USE_ALLOCATOR(HashSet, Allocator); |
| 41 private: | 40 |
| 42 typedef HashArg HashFunctions; | 41 private: |
| 43 typedef TraitsArg ValueTraits; | 42 typedef HashArg HashFunctions; |
| 44 typedef typename ValueTraits::PeekInType ValuePeekInType; | 43 typedef TraitsArg ValueTraits; |
| 45 typedef typename ValueTraits::PassInType ValuePassInType; | 44 typedef typename ValueTraits::PeekInType ValuePeekInType; |
| 46 typedef typename ValueTraits::PassOutType ValuePassOutType; | 45 typedef typename ValueTraits::PassInType ValuePassInType; |
| 47 | 46 typedef typename ValueTraits::PassOutType ValuePassOutType; |
| 48 public: | 47 |
| 49 typedef typename ValueTraits::TraitType ValueType; | 48 public: |
| 50 | 49 typedef typename ValueTraits::TraitType ValueType; |
| 51 private: | 50 |
| 52 typedef HashTable<ValueType, ValueType, IdentityExtractor, | 51 private: |
| 53 HashFunctions, ValueTraits, ValueTraits, Allocator> HashTableType; | 52 typedef HashTable<ValueType, |
| 54 | 53 ValueType, |
| 55 public: | 54 IdentityExtractor, |
| 56 typedef HashTableConstIteratorAdapter<HashTableType, ValueTraits> iterator; | 55 HashFunctions, |
| 57 typedef HashTableConstIteratorAdapter<HashTableType, ValueTraits> const_iter
ator; | 56 ValueTraits, |
| 58 typedef typename HashTableType::AddResult AddResult; | 57 ValueTraits, |
| 59 | 58 Allocator> |
| 60 void swap(HashSet& ref) | 59 HashTableType; |
| 61 { | 60 |
| 62 m_impl.swap(ref.m_impl); | 61 public: |
| 63 } | 62 typedef HashTableConstIteratorAdapter<HashTableType, ValueTraits> iterator; |
| 64 | 63 typedef HashTableConstIteratorAdapter<HashTableType, ValueTraits> |
| 65 void swap(typename Allocator::template OtherType<HashSet>::Type other) | 64 const_iterator; |
| 66 { | 65 typedef typename HashTableType::AddResult AddResult; |
| 67 HashSet& ref = Allocator::getOther(other); | 66 |
| 68 m_impl.swap(ref.m_impl); | 67 void swap(HashSet& ref) { m_impl.swap(ref.m_impl); } |
| 69 } | 68 |
| 70 | 69 void swap(typename Allocator::template OtherType<HashSet>::Type other) { |
| 71 unsigned size() const; | 70 HashSet& ref = Allocator::getOther(other); |
| 72 unsigned capacity() const; | 71 m_impl.swap(ref.m_impl); |
| 73 bool isEmpty() const; | 72 } |
| 74 | 73 |
| 75 void reserveCapacityForSize(unsigned size) | 74 unsigned size() const; |
| 76 { | 75 unsigned capacity() const; |
| 77 m_impl.reserveCapacityForSize(size); | 76 bool isEmpty() const; |
| 78 } | 77 |
| 79 | 78 void reserveCapacityForSize(unsigned size) { |
| 80 iterator begin() const; | 79 m_impl.reserveCapacityForSize(size); |
| 81 iterator end() const; | 80 } |
| 82 | 81 |
| 83 iterator find(ValuePeekInType) const; | 82 iterator begin() const; |
| 84 bool contains(ValuePeekInType) const; | 83 iterator end() const; |
| 85 | 84 |
| 86 // An alternate version of find() that finds the object by hashing and | 85 iterator find(ValuePeekInType) const; |
| 87 // comparing with some other type, to avoid the cost of type | 86 bool contains(ValuePeekInType) const; |
| 88 // conversion. HashTranslator must have the following function members: | 87 |
| 89 // static unsigned hash(const T&); | 88 // An alternate version of find() that finds the object by hashing and |
| 90 // static bool equal(const ValueType&, const T&); | 89 // comparing with some other type, to avoid the cost of type |
| 91 template <typename HashTranslator, typename T> iterator find(const T&) const
; | 90 // conversion. HashTranslator must have the following function members: |
| 92 template <typename HashTranslator, typename T> bool contains(const T&) const
; | 91 // static unsigned hash(const T&); |
| 93 | 92 // static bool equal(const ValueType&, const T&); |
| 94 // The return value is a pair of an iterator to the new value's location, | 93 template <typename HashTranslator, typename T> |
| 95 // and a bool that is true if an new entry was added. | 94 iterator find(const T&) const; |
| 96 AddResult add(ValuePassInType); | 95 template <typename HashTranslator, typename T> |
| 97 | 96 bool contains(const T&) const; |
| 98 // An alternate version of add() that finds the object by hashing and | 97 |
| 99 // comparing with some other type, to avoid the cost of type conversion if | 98 // The return value is a pair of an iterator to the new value's location, |
| 100 // the object is already in the table. HashTranslator must have the | 99 // and a bool that is true if an new entry was added. |
| 101 // following function members: | 100 AddResult add(ValuePassInType); |
| 102 // static unsigned hash(const T&); | 101 |
| 103 // static bool equal(const ValueType&, const T&); | 102 // An alternate version of add() that finds the object by hashing and |
| 104 // static translate(ValueType&, const T&, unsigned hashCode); | 103 // comparing with some other type, to avoid the cost of type conversion if |
| 105 template <typename HashTranslator, typename T> AddResult add(const T&); | 104 // the object is already in the table. HashTranslator must have the |
| 106 | 105 // following function members: |
| 107 void remove(ValuePeekInType); | 106 // static unsigned hash(const T&); |
| 108 void remove(iterator); | 107 // static bool equal(const ValueType&, const T&); |
| 109 void clear(); | 108 // static translate(ValueType&, const T&, unsigned hashCode); |
| 110 template <typename Collection> | 109 template <typename HashTranslator, typename T> |
| 111 void removeAll(const Collection& toBeRemoved) { WTF::removeAll(*this, toBeRe
moved); } | 110 AddResult add(const T&); |
| 112 | 111 |
| 113 static bool isValidValue(ValuePeekInType); | 112 void remove(ValuePeekInType); |
| 114 | 113 void remove(iterator); |
| 115 ValuePassOutType take(iterator); | 114 void clear(); |
| 116 ValuePassOutType take(ValuePeekInType); | 115 template <typename Collection> |
| 117 ValuePassOutType takeAny(); | 116 void removeAll(const Collection& toBeRemoved) { |
| 118 | 117 WTF::removeAll(*this, toBeRemoved); |
| 119 template <typename VisitorDispatcher> | 118 } |
| 120 void trace(VisitorDispatcher visitor) { m_impl.trace(visitor); } | 119 |
| 121 | 120 static bool isValidValue(ValuePeekInType); |
| 122 private: | 121 |
| 123 HashTableType m_impl; | 122 ValuePassOutType take(iterator); |
| 123 ValuePassOutType take(ValuePeekInType); |
| 124 ValuePassOutType takeAny(); |
| 125 |
| 126 template <typename VisitorDispatcher> |
| 127 void trace(VisitorDispatcher visitor) { |
| 128 m_impl.trace(visitor); |
| 129 } |
| 130 |
| 131 private: |
| 132 HashTableType m_impl; |
| 124 }; | 133 }; |
| 125 | 134 |
| 126 struct IdentityExtractor { | 135 struct IdentityExtractor { |
| 127 STATIC_ONLY(IdentityExtractor); | 136 STATIC_ONLY(IdentityExtractor); |
| 128 template <typename T> | 137 template <typename T> |
| 129 static const T& extract(const T& t) { return t; } | 138 static const T& extract(const T& t) { |
| 139 return t; |
| 140 } |
| 130 }; | 141 }; |
| 131 | 142 |
| 132 template <typename Translator> | 143 template <typename Translator> |
| 133 struct HashSetTranslatorAdapter { | 144 struct HashSetTranslatorAdapter { |
| 134 STATIC_ONLY(HashSetTranslatorAdapter); | 145 STATIC_ONLY(HashSetTranslatorAdapter); |
| 135 template <typename T> static unsigned hash(const T& key) { return Translator
::hash(key); } | 146 template <typename T> |
| 136 template <typename T, typename U> static bool equal(const T& a, const U& b)
{ return Translator::equal(a, b); } | 147 static unsigned hash(const T& key) { |
| 137 template <typename T, typename U> static void translate(T& location, const U
& key, const U&, unsigned hashCode) | 148 return Translator::hash(key); |
| 138 { | 149 } |
| 139 Translator::translate(location, key, hashCode); | 150 template <typename T, typename U> |
| 140 } | 151 static bool equal(const T& a, const U& b) { |
| 141 }; | 152 return Translator::equal(a, b); |
| 142 | 153 } |
| 143 template <typename T, typename U, typename V, typename W> | 154 template <typename T, typename U> |
| 144 inline unsigned HashSet<T, U, V, W>::size() const | 155 static void translate(T& location, |
| 145 { | 156 const U& key, |
| 146 return m_impl.size(); | 157 const U&, |
| 147 } | 158 unsigned hashCode) { |
| 148 | 159 Translator::translate(location, key, hashCode); |
| 149 template <typename T, typename U, typename V, typename W> | 160 } |
| 150 inline unsigned HashSet<T, U, V, W>::capacity() const | 161 }; |
| 151 { | 162 |
| 152 return m_impl.capacity(); | 163 template <typename T, typename U, typename V, typename W> |
| 153 } | 164 inline unsigned HashSet<T, U, V, W>::size() const { |
| 154 | 165 return m_impl.size(); |
| 155 template <typename T, typename U, typename V, typename W> | 166 } |
| 156 inline bool HashSet<T, U, V, W>::isEmpty() const | 167 |
| 157 { | 168 template <typename T, typename U, typename V, typename W> |
| 158 return m_impl.isEmpty(); | 169 inline unsigned HashSet<T, U, V, W>::capacity() const { |
| 159 } | 170 return m_impl.capacity(); |
| 160 | 171 } |
| 161 template <typename T, typename U, typename V, typename W> | 172 |
| 162 inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::begin() const | 173 template <typename T, typename U, typename V, typename W> |
| 163 { | 174 inline bool HashSet<T, U, V, W>::isEmpty() const { |
| 164 return m_impl.begin(); | 175 return m_impl.isEmpty(); |
| 165 } | 176 } |
| 166 | 177 |
| 167 template <typename T, typename U, typename V, typename W> | 178 template <typename T, typename U, typename V, typename W> |
| 168 inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::end() const | 179 inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::begin() |
| 169 { | 180 const { |
| 170 return m_impl.end(); | 181 return m_impl.begin(); |
| 171 } | 182 } |
| 172 | 183 |
| 173 template <typename T, typename U, typename V, typename W> | 184 template <typename T, typename U, typename V, typename W> |
| 174 inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::find(ValuePee
kInType value) const | 185 inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::end() const { |
| 175 { | 186 return m_impl.end(); |
| 176 return m_impl.find(value); | 187 } |
| 177 } | 188 |
| 178 | 189 template <typename T, typename U, typename V, typename W> |
| 179 template <typename Value, typename HashFunctions, typename Traits, typename Allo
cator> | 190 inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::find( |
| 180 inline bool HashSet<Value, HashFunctions, Traits, Allocator>::contains(ValuePeek
InType value) const | 191 ValuePeekInType value) const { |
| 181 { | 192 return m_impl.find(value); |
| 182 return m_impl.contains(value); | 193 } |
| 183 } | 194 |
| 184 | 195 template <typename Value, |
| 185 template <typename Value, typename HashFunctions, typename Traits, typename Allo
cator> | 196 typename HashFunctions, |
| 197 typename Traits, |
| 198 typename Allocator> |
| 199 inline bool HashSet<Value, HashFunctions, Traits, Allocator>::contains( |
| 200 ValuePeekInType value) const { |
| 201 return m_impl.contains(value); |
| 202 } |
| 203 |
| 204 template <typename Value, |
| 205 typename HashFunctions, |
| 206 typename Traits, |
| 207 typename Allocator> |
| 186 template <typename HashTranslator, typename T> | 208 template <typename HashTranslator, typename T> |
| 187 typename HashSet<Value, HashFunctions, Traits, Allocator>::iterator | 209 typename HashSet<Value, HashFunctions, Traits, Allocator>:: |
| 188 inline HashSet<Value, HashFunctions, Traits, Allocator>::find(const T& value) co
nst | 210 iterator inline HashSet<Value, HashFunctions, Traits, Allocator>::find( |
| 189 { | 211 const T& value) const { |
| 190 return m_impl.template find<HashSetTranslatorAdapter<HashTranslator>>(value)
; | 212 return m_impl.template find<HashSetTranslatorAdapter<HashTranslator>>(value); |
| 191 } | 213 } |
| 192 | 214 |
| 193 template <typename Value, typename HashFunctions, typename Traits, typename Allo
cator> | 215 template <typename Value, |
| 216 typename HashFunctions, |
| 217 typename Traits, |
| 218 typename Allocator> |
| 194 template <typename HashTranslator, typename T> | 219 template <typename HashTranslator, typename T> |
| 195 inline bool HashSet<Value, HashFunctions, Traits, Allocator>::contains(const T&
value) const | 220 inline bool HashSet<Value, HashFunctions, Traits, Allocator>::contains( |
| 196 { | 221 const T& value) const { |
| 197 return m_impl.template contains<HashSetTranslatorAdapter<HashTranslator>>(va
lue); | 222 return m_impl.template contains<HashSetTranslatorAdapter<HashTranslator>>( |
| 198 } | 223 value); |
| 199 | 224 } |
| 200 template <typename T, typename U, typename V, typename W> | 225 |
| 201 inline typename HashSet<T, U, V, W>::AddResult HashSet<T, U, V, W>::add(ValuePas
sInType value) | 226 template <typename T, typename U, typename V, typename W> |
| 202 { | 227 inline typename HashSet<T, U, V, W>::AddResult HashSet<T, U, V, W>::add( |
| 203 return m_impl.add(value); | 228 ValuePassInType value) { |
| 204 } | 229 return m_impl.add(value); |
| 205 | 230 } |
| 206 template <typename Value, typename HashFunctions, typename Traits, typename Allo
cator> | 231 |
| 232 template <typename Value, |
| 233 typename HashFunctions, |
| 234 typename Traits, |
| 235 typename Allocator> |
| 207 template <typename HashTranslator, typename T> | 236 template <typename HashTranslator, typename T> |
| 208 inline typename HashSet<Value, HashFunctions, Traits, Allocator>::AddResult | 237 inline typename HashSet<Value, HashFunctions, Traits, Allocator>::AddResult |
| 209 HashSet<Value, HashFunctions, Traits, Allocator>::add(const T& value) | 238 HashSet<Value, HashFunctions, Traits, Allocator>::add(const T& value) { |
| 210 { | 239 return m_impl |
| 211 return m_impl.template addPassingHashCode<HashSetTranslatorAdapter<HashTrans
lator>>(value, value); | 240 .template addPassingHashCode<HashSetTranslatorAdapter<HashTranslator>>( |
| 212 } | 241 value, value); |
| 213 | 242 } |
| 214 template <typename T, typename U, typename V, typename W> | 243 |
| 215 inline void HashSet<T, U, V, W>::remove(iterator it) | 244 template <typename T, typename U, typename V, typename W> |
| 216 { | 245 inline void HashSet<T, U, V, W>::remove(iterator it) { |
| 217 m_impl.remove(it.m_impl); | 246 m_impl.remove(it.m_impl); |
| 218 } | 247 } |
| 219 | 248 |
| 220 template <typename T, typename U, typename V, typename W> | 249 template <typename T, typename U, typename V, typename W> |
| 221 inline void HashSet<T, U, V, W>::remove(ValuePeekInType value) | 250 inline void HashSet<T, U, V, W>::remove(ValuePeekInType value) { |
| 222 { | 251 remove(find(value)); |
| 223 remove(find(value)); | 252 } |
| 224 } | 253 |
| 225 | 254 template <typename T, typename U, typename V, typename W> |
| 226 template <typename T, typename U, typename V, typename W> | 255 inline void HashSet<T, U, V, W>::clear() { |
| 227 inline void HashSet<T, U, V, W>::clear() | 256 m_impl.clear(); |
| 228 { | 257 } |
| 229 m_impl.clear(); | 258 |
| 230 } | 259 template <typename T, typename U, typename V, typename W> |
| 231 | 260 inline bool HashSet<T, U, V, W>::isValidValue(ValuePeekInType value) { |
| 232 template <typename T, typename U, typename V, typename W> | 261 if (ValueTraits::isDeletedValue(value)) |
| 233 inline bool HashSet<T, U, V, W>::isValidValue(ValuePeekInType value) | 262 return false; |
| 234 { | 263 |
| 235 if (ValueTraits::isDeletedValue(value)) | 264 if (HashFunctions::safeToCompareToEmptyOrDeleted) { |
| 236 return false; | 265 if (value == ValueTraits::emptyValue()) |
| 237 | 266 return false; |
| 238 if (HashFunctions::safeToCompareToEmptyOrDeleted) { | 267 } else { |
| 239 if (value == ValueTraits::emptyValue()) | 268 if (isHashTraitsEmptyValue<ValueTraits>(value)) |
| 240 return false; | 269 return false; |
| 241 } else { | 270 } |
| 242 if (isHashTraitsEmptyValue<ValueTraits>(value)) | 271 |
| 243 return false; | 272 return true; |
| 244 } | 273 } |
| 245 | 274 |
| 246 return true; | 275 template <typename T, typename U, typename V, typename W> |
| 247 } | 276 inline typename HashSet<T, U, V, W>::ValuePassOutType HashSet<T, U, V, W>::take( |
| 248 | 277 iterator it) { |
| 249 template <typename T, typename U, typename V, typename W> | 278 if (it == end()) |
| 250 inline typename HashSet<T, U, V, W>::ValuePassOutType HashSet<T, U, V, W>::take(
iterator it) | 279 return ValueTraits::emptyValue(); |
| 251 { | 280 |
| 252 if (it == end()) | 281 ValuePassOutType result = ValueTraits::passOut(const_cast<ValueType&>(*it)); |
| 253 return ValueTraits::emptyValue(); | 282 remove(it); |
| 254 | 283 |
| 255 ValuePassOutType result = ValueTraits::passOut(const_cast<ValueType&>(*it)); | 284 return result; |
| 256 remove(it); | 285 } |
| 257 | 286 |
| 258 return result; | 287 template <typename T, typename U, typename V, typename W> |
| 259 } | 288 inline typename HashSet<T, U, V, W>::ValuePassOutType HashSet<T, U, V, W>::take( |
| 260 | 289 ValuePeekInType value) { |
| 261 template <typename T, typename U, typename V, typename W> | 290 return take(find(value)); |
| 262 inline typename HashSet<T, U, V, W>::ValuePassOutType HashSet<T, U, V, W>::take(
ValuePeekInType value) | 291 } |
| 263 { | 292 |
| 264 return take(find(value)); | 293 template <typename T, typename U, typename V, typename W> |
| 265 } | 294 inline typename HashSet<T, U, V, W>::ValuePassOutType |
| 266 | 295 HashSet<T, U, V, W>::takeAny() { |
| 267 template <typename T, typename U, typename V, typename W> | 296 return take(begin()); |
| 268 inline typename HashSet<T, U, V, W>::ValuePassOutType HashSet<T, U, V, W>::takeA
ny() | |
| 269 { | |
| 270 return take(begin()); | |
| 271 } | 297 } |
| 272 | 298 |
| 273 template <typename C, typename W> | 299 template <typename C, typename W> |
| 274 inline void copyToVector(const C& collection, W& vector) | 300 inline void copyToVector(const C& collection, W& vector) { |
| 275 { | 301 typedef typename C::const_iterator iterator; |
| 276 typedef typename C::const_iterator iterator; | 302 |
| 277 | 303 vector.resize(collection.size()); |
| 278 vector.resize(collection.size()); | 304 |
| 279 | 305 iterator it = collection.begin(); |
| 280 iterator it = collection.begin(); | 306 iterator end = collection.end(); |
| 281 iterator end = collection.end(); | 307 for (unsigned i = 0; it != end; ++it, ++i) |
| 282 for (unsigned i = 0; it != end; ++it, ++i) | 308 vector[i] = *it; |
| 283 vector[i] = *it; | |
| 284 } | 309 } |
| 285 | 310 |
| 286 #if !ENABLE(OILPAN) | 311 #if !ENABLE(OILPAN) |
| 287 template <typename T, typename U, typename V> | 312 template <typename T, typename U, typename V> |
| 288 struct NeedsTracing<HashSet<T, U, V>> { | 313 struct NeedsTracing<HashSet<T, U, V>> { |
| 289 static const bool value = false; | 314 static const bool value = false; |
| 290 }; | 315 }; |
| 291 #endif | 316 #endif |
| 292 | 317 |
| 293 } // namespace WTF | 318 } // namespace WTF |
| 294 | 319 |
| 295 using WTF::HashSet; | 320 using WTF::HashSet; |
| 296 | 321 |
| 297 #endif // WTF_HashSet_h | 322 #endif // WTF_HashSet_h |
| OLD | NEW |