| 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 19 matching lines...) Expand all Loading... |
| 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 < |
| 35 typename ValueArg, | 35 typename ValueArg, |
| 36 typename HashArg = typename DefaultHash<ValueArg>::Hash, | 36 typename HashArg = typename DefaultHash<ValueArg>::Hash, |
| 37 typename TraitsArg = HashTraits<ValueArg>, | 37 typename TraitsArg = HashTraits<ValueArg>, |
| 38 typename Allocator = PartitionAllocator> | 38 typename Allocator = PartitionAllocator> |
| 39 class HashSet { | 39 class HashSet { |
| 40 WTF_USE_ALLOCATOR(HashSet, Allocator); | 40 WTF_USE_ALLOCATOR(HashSet, Allocator); |
| 41 private: | 41 |
| 42 typedef HashArg HashFunctions; | 42 private: |
| 43 typedef TraitsArg ValueTraits; | 43 typedef HashArg HashFunctions; |
| 44 typedef typename ValueTraits::PeekInType ValuePeekInType; | 44 typedef TraitsArg ValueTraits; |
| 45 typedef typename ValueTraits::PassInType ValuePassInType; | 45 typedef typename ValueTraits::PeekInType ValuePeekInType; |
| 46 typedef typename ValueTraits::PassOutType ValuePassOutType; | 46 typedef typename ValueTraits::PassInType ValuePassInType; |
| 47 | 47 typedef typename ValueTraits::PassOutType ValuePassOutType; |
| 48 public: | 48 |
| 49 typedef typename ValueTraits::TraitType ValueType; | 49 public: |
| 50 | 50 typedef typename ValueTraits::TraitType ValueType; |
| 51 private: | 51 |
| 52 typedef HashTable<ValueType, ValueType, IdentityExtractor, | 52 private: |
| 53 HashFunctions, ValueTraits, ValueTraits, Allocator> HashTableType; | 53 typedef HashTable<ValueType, ValueType, IdentityExtractor, HashFunctions, Valu
eTraits, ValueTraits, Allocator> HashTableType; |
| 54 | 54 |
| 55 public: | 55 public: |
| 56 typedef HashTableConstIteratorAdapter<HashTableType, ValueTraits> iterator; | 56 typedef HashTableConstIteratorAdapter<HashTableType, ValueTraits> iterator; |
| 57 typedef HashTableConstIteratorAdapter<HashTableType, ValueTraits> const_iter
ator; | 57 typedef HashTableConstIteratorAdapter<HashTableType, ValueTraits> const_iterat
or; |
| 58 typedef typename HashTableType::AddResult AddResult; | 58 typedef typename HashTableType::AddResult AddResult; |
| 59 | 59 |
| 60 void swap(HashSet& ref) | 60 void swap(HashSet& ref) { |
| 61 { | 61 m_impl.swap(ref.m_impl); |
| 62 m_impl.swap(ref.m_impl); | 62 } |
| 63 } | 63 |
| 64 | 64 void swap(typename Allocator::template OtherType<HashSet>::Type other) { |
| 65 void swap(typename Allocator::template OtherType<HashSet>::Type other) | 65 HashSet& ref = Allocator::getOther(other); |
| 66 { | 66 m_impl.swap(ref.m_impl); |
| 67 HashSet& ref = Allocator::getOther(other); | 67 } |
| 68 m_impl.swap(ref.m_impl); | 68 |
| 69 } | 69 unsigned size() const; |
| 70 | 70 unsigned capacity() const; |
| 71 unsigned size() const; | 71 bool isEmpty() const; |
| 72 unsigned capacity() const; | 72 |
| 73 bool isEmpty() const; | 73 void reserveCapacityForSize(unsigned size) { |
| 74 | 74 m_impl.reserveCapacityForSize(size); |
| 75 void reserveCapacityForSize(unsigned size) | 75 } |
| 76 { | 76 |
| 77 m_impl.reserveCapacityForSize(size); | 77 iterator begin() const; |
| 78 } | 78 iterator end() const; |
| 79 | 79 |
| 80 iterator begin() const; | 80 iterator find(ValuePeekInType) const; |
| 81 iterator end() const; | 81 bool contains(ValuePeekInType) const; |
| 82 | 82 |
| 83 iterator find(ValuePeekInType) const; | 83 // An alternate version of find() that finds the object by hashing and |
| 84 bool contains(ValuePeekInType) const; | 84 // comparing with some other type, to avoid the cost of type |
| 85 | 85 // conversion. HashTranslator must have the following function members: |
| 86 // An alternate version of find() that finds the object by hashing and | 86 // static unsigned hash(const T&); |
| 87 // comparing with some other type, to avoid the cost of type | 87 // static bool equal(const ValueType&, const T&); |
| 88 // conversion. HashTranslator must have the following function members: | 88 template <typename HashTranslator, typename T> |
| 89 // static unsigned hash(const T&); | 89 iterator find(const T&) const; |
| 90 // static bool equal(const ValueType&, const T&); | 90 template <typename HashTranslator, typename T> |
| 91 template <typename HashTranslator, typename T> iterator find(const T&) const
; | 91 bool contains(const T&) const; |
| 92 template <typename HashTranslator, typename T> bool contains(const T&) const
; | 92 |
| 93 | 93 // The return value is a pair of an iterator to the new value's location, |
| 94 // The return value is a pair of an iterator to the new value's location, | 94 // and a bool that is true if an new entry was added. |
| 95 // and a bool that is true if an new entry was added. | 95 AddResult add(ValuePassInType); |
| 96 AddResult add(ValuePassInType); | 96 |
| 97 | 97 // An alternate version of add() that finds the object by hashing and |
| 98 // An alternate version of add() that finds the object by hashing and | 98 // comparing with some other type, to avoid the cost of type conversion if |
| 99 // comparing with some other type, to avoid the cost of type conversion if | 99 // the object is already in the table. HashTranslator must have the |
| 100 // the object is already in the table. HashTranslator must have the | 100 // following function members: |
| 101 // following function members: | 101 // static unsigned hash(const T&); |
| 102 // static unsigned hash(const T&); | 102 // static bool equal(const ValueType&, const T&); |
| 103 // static bool equal(const ValueType&, const T&); | 103 // static translate(ValueType&, const T&, unsigned hashCode); |
| 104 // static translate(ValueType&, const T&, unsigned hashCode); | 104 template <typename HashTranslator, typename T> |
| 105 template <typename HashTranslator, typename T> AddResult add(const T&); | 105 AddResult add(const T&); |
| 106 | 106 |
| 107 void remove(ValuePeekInType); | 107 void remove(ValuePeekInType); |
| 108 void remove(iterator); | 108 void remove(iterator); |
| 109 void clear(); | 109 void clear(); |
| 110 template <typename Collection> | 110 template <typename Collection> |
| 111 void removeAll(const Collection& toBeRemoved) { WTF::removeAll(*this, toBeRe
moved); } | 111 void removeAll(const Collection& toBeRemoved) { WTF::removeAll(*this, toBeRemo
ved); } |
| 112 | 112 |
| 113 static bool isValidValue(ValuePeekInType); | 113 static bool isValidValue(ValuePeekInType); |
| 114 | 114 |
| 115 ValuePassOutType take(iterator); | 115 ValuePassOutType take(iterator); |
| 116 ValuePassOutType take(ValuePeekInType); | 116 ValuePassOutType take(ValuePeekInType); |
| 117 ValuePassOutType takeAny(); | 117 ValuePassOutType takeAny(); |
| 118 | 118 |
| 119 template <typename VisitorDispatcher> | 119 template <typename VisitorDispatcher> |
| 120 void trace(VisitorDispatcher visitor) { m_impl.trace(visitor); } | 120 void trace(VisitorDispatcher visitor) { m_impl.trace(visitor); } |
| 121 | 121 |
| 122 private: | 122 private: |
| 123 HashTableType m_impl; | 123 HashTableType m_impl; |
| 124 }; | 124 }; |
| 125 | 125 |
| 126 struct IdentityExtractor { | 126 struct IdentityExtractor { |
| 127 template <typename T> | 127 template <typename T> |
| 128 static const T& extract(const T& t) { return t; } | 128 static const T& extract(const T& t) { return t; } |
| 129 }; | 129 }; |
| 130 | 130 |
| 131 template <typename Translator> | 131 template <typename Translator> |
| 132 struct HashSetTranslatorAdapter { | 132 struct HashSetTranslatorAdapter { |
| 133 template <typename T> static unsigned hash(const T& key) { return Translator
::hash(key); } | 133 template <typename T> |
| 134 template <typename T, typename U> static bool equal(const T& a, const U& b)
{ return Translator::equal(a, b); } | 134 static unsigned hash(const T& key) { return Translator::hash(key); } |
| 135 template <typename T, typename U> static void translate(T& location, const U
& key, const U&, unsigned hashCode) | 135 template <typename T, typename U> |
| 136 { | 136 static bool equal(const T& a, const U& b) { return Translator::equal(a, b); } |
| 137 Translator::translate(location, key, hashCode); | 137 template <typename T, typename U> |
| 138 } | 138 static void translate(T& location, const U& key, const U&, unsigned hashCode)
{ |
| 139 }; | 139 Translator::translate(location, key, hashCode); |
| 140 | 140 } |
| 141 template <typename T, typename U, typename V, typename W> | 141 }; |
| 142 inline unsigned HashSet<T, U, V, W>::size() const | 142 |
| 143 { | 143 template <typename T, typename U, typename V, typename W> |
| 144 return m_impl.size(); | 144 inline unsigned HashSet<T, U, V, W>::size() const { |
| 145 } | 145 return m_impl.size(); |
| 146 | 146 } |
| 147 template <typename T, typename U, typename V, typename W> | 147 |
| 148 inline unsigned HashSet<T, U, V, W>::capacity() const | 148 template <typename T, typename U, typename V, typename W> |
| 149 { | 149 inline unsigned HashSet<T, U, V, W>::capacity() const { |
| 150 return m_impl.capacity(); | 150 return m_impl.capacity(); |
| 151 } | 151 } |
| 152 | 152 |
| 153 template <typename T, typename U, typename V, typename W> | 153 template <typename T, typename U, typename V, typename W> |
| 154 inline bool HashSet<T, U, V, W>::isEmpty() const | 154 inline bool HashSet<T, U, V, W>::isEmpty() const { |
| 155 { | 155 return m_impl.isEmpty(); |
| 156 return m_impl.isEmpty(); | 156 } |
| 157 } | 157 |
| 158 | 158 template <typename T, typename U, typename V, typename W> |
| 159 template <typename T, typename U, typename V, typename W> | 159 inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::begin() const
{ |
| 160 inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::begin() const | 160 return m_impl.begin(); |
| 161 { | 161 } |
| 162 return m_impl.begin(); | 162 |
| 163 } | 163 template <typename T, typename U, typename V, typename W> |
| 164 | 164 inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::end() const { |
| 165 template <typename T, typename U, typename V, typename W> | 165 return m_impl.end(); |
| 166 inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::end() const | 166 } |
| 167 { | 167 |
| 168 return m_impl.end(); | 168 template <typename T, typename U, typename V, typename W> |
| 169 } | 169 inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::find(ValuePee
kInType value) const { |
| 170 | 170 return m_impl.find(value); |
| 171 template <typename T, typename U, typename V, typename W> | 171 } |
| 172 inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::find(ValuePee
kInType value) const | 172 |
| 173 { | 173 template <typename Value, typename HashFunctions, typename Traits, typename Allo
cator> |
| 174 return m_impl.find(value); | 174 inline bool HashSet<Value, HashFunctions, Traits, Allocator>::contains(ValuePeek
InType value) const { |
| 175 } | 175 return m_impl.contains(value); |
| 176 | |
| 177 template <typename Value, typename HashFunctions, typename Traits, typename Allo
cator> | |
| 178 inline bool HashSet<Value, HashFunctions, Traits, Allocator>::contains(ValuePeek
InType value) const | |
| 179 { | |
| 180 return m_impl.contains(value); | |
| 181 } | 176 } |
| 182 | 177 |
| 183 template <typename Value, typename HashFunctions, typename Traits, typename Allo
cator> | 178 template <typename Value, typename HashFunctions, typename Traits, typename Allo
cator> |
| 184 template <typename HashTranslator, typename T> | 179 template <typename HashTranslator, typename T> |
| 185 typename HashSet<Value, HashFunctions, Traits, Allocator>::iterator | 180 typename HashSet<Value, HashFunctions, Traits, Allocator>::iterator inline HashS
et<Value, HashFunctions, Traits, Allocator>::find(const T& value) const { |
| 186 inline HashSet<Value, HashFunctions, Traits, Allocator>::find(const T& value) co
nst | 181 return m_impl.template find<HashSetTranslatorAdapter<HashTranslator>>(value); |
| 187 { | |
| 188 return m_impl.template find<HashSetTranslatorAdapter<HashTranslator>>(value)
; | |
| 189 } | 182 } |
| 190 | 183 |
| 191 template <typename Value, typename HashFunctions, typename Traits, typename Allo
cator> | 184 template <typename Value, typename HashFunctions, typename Traits, typename Allo
cator> |
| 192 template <typename HashTranslator, typename T> | 185 template <typename HashTranslator, typename T> |
| 193 inline bool HashSet<Value, HashFunctions, Traits, Allocator>::contains(const T&
value) const | 186 inline bool HashSet<Value, HashFunctions, Traits, Allocator>::contains(const T&
value) const { |
| 194 { | 187 return m_impl.template contains<HashSetTranslatorAdapter<HashTranslator>>(valu
e); |
| 195 return m_impl.template contains<HashSetTranslatorAdapter<HashTranslator>>(va
lue); | 188 } |
| 196 } | 189 |
| 197 | 190 template <typename T, typename U, typename V, typename W> |
| 198 template <typename T, typename U, typename V, typename W> | 191 inline typename HashSet<T, U, V, W>::AddResult HashSet<T, U, V, W>::add(ValuePas
sInType value) { |
| 199 inline typename HashSet<T, U, V, W>::AddResult HashSet<T, U, V, W>::add(ValuePas
sInType value) | 192 return m_impl.add(value); |
| 200 { | |
| 201 return m_impl.add(value); | |
| 202 } | 193 } |
| 203 | 194 |
| 204 template <typename Value, typename HashFunctions, typename Traits, typename Allo
cator> | 195 template <typename Value, typename HashFunctions, typename Traits, typename Allo
cator> |
| 205 template <typename HashTranslator, typename T> | 196 template <typename HashTranslator, typename T> |
| 206 inline typename HashSet<Value, HashFunctions, Traits, Allocator>::AddResult | 197 inline typename HashSet<Value, HashFunctions, Traits, Allocator>::AddResult |
| 207 HashSet<Value, HashFunctions, Traits, Allocator>::add(const T& value) | 198 HashSet<Value, HashFunctions, Traits, Allocator>::add(const T& value) { |
| 208 { | 199 return m_impl.template addPassingHashCode<HashSetTranslatorAdapter<HashTransla
tor>>(value, value); |
| 209 return m_impl.template addPassingHashCode<HashSetTranslatorAdapter<HashTrans
lator>>(value, value); | 200 } |
| 210 } | 201 |
| 211 | 202 template <typename T, typename U, typename V, typename W> |
| 212 template <typename T, typename U, typename V, typename W> | 203 inline void HashSet<T, U, V, W>::remove(iterator it) { |
| 213 inline void HashSet<T, U, V, W>::remove(iterator it) | 204 m_impl.remove(it.m_impl); |
| 214 { | 205 } |
| 215 m_impl.remove(it.m_impl); | 206 |
| 216 } | 207 template <typename T, typename U, typename V, typename W> |
| 217 | 208 inline void HashSet<T, U, V, W>::remove(ValuePeekInType value) { |
| 218 template <typename T, typename U, typename V, typename W> | 209 remove(find(value)); |
| 219 inline void HashSet<T, U, V, W>::remove(ValuePeekInType value) | 210 } |
| 220 { | 211 |
| 221 remove(find(value)); | 212 template <typename T, typename U, typename V, typename W> |
| 222 } | 213 inline void HashSet<T, U, V, W>::clear() { |
| 223 | 214 m_impl.clear(); |
| 224 template <typename T, typename U, typename V, typename W> | 215 } |
| 225 inline void HashSet<T, U, V, W>::clear() | 216 |
| 226 { | 217 template <typename T, typename U, typename V, typename W> |
| 227 m_impl.clear(); | 218 inline bool HashSet<T, U, V, W>::isValidValue(ValuePeekInType value) { |
| 228 } | 219 if (ValueTraits::isDeletedValue(value)) |
| 229 | 220 return false; |
| 230 template <typename T, typename U, typename V, typename W> | 221 |
| 231 inline bool HashSet<T, U, V, W>::isValidValue(ValuePeekInType value) | 222 if (HashFunctions::safeToCompareToEmptyOrDeleted) { |
| 232 { | 223 if (value == ValueTraits::emptyValue()) |
| 233 if (ValueTraits::isDeletedValue(value)) | 224 return false; |
| 234 return false; | 225 } else { |
| 235 | 226 if (isHashTraitsEmptyValue<ValueTraits>(value)) |
| 236 if (HashFunctions::safeToCompareToEmptyOrDeleted) { | 227 return false; |
| 237 if (value == ValueTraits::emptyValue()) | 228 } |
| 238 return false; | 229 |
| 239 } else { | 230 return true; |
| 240 if (isHashTraitsEmptyValue<ValueTraits>(value)) | 231 } |
| 241 return false; | 232 |
| 242 } | 233 template <typename T, typename U, typename V, typename W> |
| 243 | 234 inline typename HashSet<T, U, V, W>::ValuePassOutType HashSet<T, U, V, W>::take(
iterator it) { |
| 244 return true; | 235 if (it == end()) |
| 245 } | 236 return ValueTraits::emptyValue(); |
| 246 | 237 |
| 247 template <typename T, typename U, typename V, typename W> | 238 ValuePassOutType result = ValueTraits::passOut(const_cast<ValueType&>(*it)); |
| 248 inline typename HashSet<T, U, V, W>::ValuePassOutType HashSet<T, U, V, W>::take(
iterator it) | 239 remove(it); |
| 249 { | 240 |
| 250 if (it == end()) | 241 return result; |
| 251 return ValueTraits::emptyValue(); | 242 } |
| 252 | 243 |
| 253 ValuePassOutType result = ValueTraits::passOut(const_cast<ValueType&>(*it)); | 244 template <typename T, typename U, typename V, typename W> |
| 254 remove(it); | 245 inline typename HashSet<T, U, V, W>::ValuePassOutType HashSet<T, U, V, W>::take(
ValuePeekInType value) { |
| 255 | 246 return take(find(value)); |
| 256 return result; | 247 } |
| 257 } | 248 |
| 258 | 249 template <typename T, typename U, typename V, typename W> |
| 259 template <typename T, typename U, typename V, typename W> | 250 inline typename HashSet<T, U, V, W>::ValuePassOutType HashSet<T, U, V, W>::takeA
ny() { |
| 260 inline typename HashSet<T, U, V, W>::ValuePassOutType HashSet<T, U, V, W>::take(
ValuePeekInType value) | 251 return take(begin()); |
| 261 { | |
| 262 return take(find(value)); | |
| 263 } | |
| 264 | |
| 265 template <typename T, typename U, typename V, typename W> | |
| 266 inline typename HashSet<T, U, V, W>::ValuePassOutType HashSet<T, U, V, W>::takeA
ny() | |
| 267 { | |
| 268 return take(begin()); | |
| 269 } | 252 } |
| 270 | 253 |
| 271 template <typename C, typename W> | 254 template <typename C, typename W> |
| 272 inline void copyToVector(const C& collection, W& vector) | 255 inline void copyToVector(const C& collection, W& vector) { |
| 273 { | 256 typedef typename C::const_iterator iterator; |
| 274 typedef typename C::const_iterator iterator; | 257 |
| 275 | 258 vector.resize(collection.size()); |
| 276 vector.resize(collection.size()); | 259 |
| 277 | 260 iterator it = collection.begin(); |
| 278 iterator it = collection.begin(); | 261 iterator end = collection.end(); |
| 279 iterator end = collection.end(); | 262 for (unsigned i = 0; it != end; ++it, ++i) |
| 280 for (unsigned i = 0; it != end; ++it, ++i) | 263 vector[i] = *it; |
| 281 vector[i] = *it; | |
| 282 } | 264 } |
| 283 | 265 |
| 284 #if !ENABLE(OILPAN) | 266 #if !ENABLE(OILPAN) |
| 285 template <typename T, typename U, typename V> | 267 template <typename T, typename U, typename V> |
| 286 struct NeedsTracing<HashSet<T, U, V>> { | 268 struct NeedsTracing<HashSet<T, U, V>> { |
| 287 static const bool value = false; | 269 static const bool value = false; |
| 288 }; | 270 }; |
| 289 #endif | 271 #endif |
| 290 | 272 |
| 291 } // namespace WTF | 273 } // namespace WTF |
| 292 | 274 |
| 293 using WTF::HashSet; | 275 using WTF::HashSet; |
| 294 | 276 |
| 295 #endif // WTF_HashSet_h | 277 #endif // WTF_HashSet_h |
| OLD | NEW |