OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserv
ed. |
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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 static void constructDeletedValue(P*& slot, bool) { slot = reinterpret_c
ast<P*>(-1); } | 138 static void constructDeletedValue(P*& slot, bool) { slot = reinterpret_c
ast<P*>(-1); } |
139 static bool isDeletedValue(P* value) { return value == reinterpret_cast<
P*>(-1); } | 139 static bool isDeletedValue(P* value) { return value == reinterpret_cast<
P*>(-1); } |
140 }; | 140 }; |
141 | 141 |
142 template<typename T> struct SimpleClassHashTraits : GenericHashTraits<T> { | 142 template<typename T> struct SimpleClassHashTraits : GenericHashTraits<T> { |
143 static const bool emptyValueIsZero = true; | 143 static const bool emptyValueIsZero = true; |
144 static void constructDeletedValue(T& slot, bool) { new (NotNull, &slot)
T(HashTableDeletedValue); } | 144 static void constructDeletedValue(T& slot, bool) { new (NotNull, &slot)
T(HashTableDeletedValue); } |
145 static bool isDeletedValue(const T& value) { return value.isHashTableDel
etedValue(); } | 145 static bool isDeletedValue(const T& value) { return value.isHashTableDel
etedValue(); } |
146 }; | 146 }; |
147 | 147 |
148 template<typename P> struct HashTraits<OwnPtr<P> > : SimpleClassHashTraits<O
wnPtr<P> > { | 148 template<typename P> struct HashTraits<OwnPtr<P>> : SimpleClassHashTraits<Ow
nPtr<P>> { |
149 typedef std::nullptr_t EmptyValueType; | 149 typedef std::nullptr_t EmptyValueType; |
150 | 150 |
151 static EmptyValueType emptyValue() { return nullptr; } | 151 static EmptyValueType emptyValue() { return nullptr; } |
152 | 152 |
153 static const bool hasIsEmptyValueFunction = true; | 153 static const bool hasIsEmptyValueFunction = true; |
154 static bool isEmptyValue(const OwnPtr<P>& value) { return !value; } | 154 static bool isEmptyValue(const OwnPtr<P>& value) { return !value; } |
155 | 155 |
156 typedef typename OwnPtr<P>::PtrType PeekInType; | 156 typedef typename OwnPtr<P>::PtrType PeekInType; |
157 | 157 |
158 typedef PassOwnPtr<P> PassInType; | 158 typedef PassOwnPtr<P> PassInType; |
159 static void store(PassOwnPtr<P> value, OwnPtr<P>& storage) { storage = v
alue; } | 159 static void store(PassOwnPtr<P> value, OwnPtr<P>& storage) { storage = v
alue; } |
160 | 160 |
161 typedef PassOwnPtr<P> PassOutType; | 161 typedef PassOwnPtr<P> PassOutType; |
162 static PassOwnPtr<P> passOut(OwnPtr<P>& value) { return value.release();
} | 162 static PassOwnPtr<P> passOut(OwnPtr<P>& value) { return value.release();
} |
163 static PassOwnPtr<P> passOut(std::nullptr_t) { return nullptr; } | 163 static PassOwnPtr<P> passOut(std::nullptr_t) { return nullptr; } |
164 | 164 |
165 typedef typename OwnPtr<P>::PtrType PeekOutType; | 165 typedef typename OwnPtr<P>::PtrType PeekOutType; |
166 static PeekOutType peek(const OwnPtr<P>& value) { return value.get(); } | 166 static PeekOutType peek(const OwnPtr<P>& value) { return value.get(); } |
167 static PeekOutType peek(std::nullptr_t) { return 0; } | 167 static PeekOutType peek(std::nullptr_t) { return 0; } |
168 }; | 168 }; |
169 | 169 |
170 template<typename P> struct HashTraits<RefPtr<P> > : SimpleClassHashTraits<R
efPtr<P> > { | 170 template<typename P> struct HashTraits<RefPtr<P>> : SimpleClassHashTraits<Re
fPtr<P>> { |
171 typedef std::nullptr_t EmptyValueType; | 171 typedef std::nullptr_t EmptyValueType; |
172 static EmptyValueType emptyValue() { return nullptr; } | 172 static EmptyValueType emptyValue() { return nullptr; } |
173 | 173 |
174 static const bool hasIsEmptyValueFunction = true; | 174 static const bool hasIsEmptyValueFunction = true; |
175 static bool isEmptyValue(const RefPtr<P>& value) { return !value; } | 175 static bool isEmptyValue(const RefPtr<P>& value) { return !value; } |
176 | 176 |
177 typedef RefPtrValuePeeker<P> PeekInType; | 177 typedef RefPtrValuePeeker<P> PeekInType; |
178 typedef RefPtr<P>* IteratorGetType; | 178 typedef RefPtr<P>* IteratorGetType; |
179 typedef const RefPtr<P>* IteratorConstGetType; | 179 typedef const RefPtr<P>* IteratorConstGetType; |
180 typedef RefPtr<P>& IteratorReferenceType; | 180 typedef RefPtr<P>& IteratorReferenceType; |
181 typedef const RefPtr<P>& IteratorConstReferenceType; | 181 typedef const RefPtr<P>& IteratorConstReferenceType; |
182 static IteratorReferenceType getToReferenceConversion(IteratorGetType x)
{ return *x; } | 182 static IteratorReferenceType getToReferenceConversion(IteratorGetType x)
{ return *x; } |
183 static IteratorConstReferenceType getToReferenceConstConversion(Iterator
ConstGetType x) { return *x; } | 183 static IteratorConstReferenceType getToReferenceConstConversion(Iterator
ConstGetType x) { return *x; } |
184 | 184 |
185 typedef PassRefPtr<P> PassInType; | 185 typedef PassRefPtr<P> PassInType; |
186 static void store(PassRefPtr<P> value, RefPtr<P>& storage) { storage = v
alue; } | 186 static void store(PassRefPtr<P> value, RefPtr<P>& storage) { storage = v
alue; } |
187 | 187 |
188 typedef PassRefPtr<P> PassOutType; | 188 typedef PassRefPtr<P> PassOutType; |
189 static PassOutType passOut(RefPtr<P>& value) { return value.release(); } | 189 static PassOutType passOut(RefPtr<P>& value) { return value.release(); } |
190 static PassOutType passOut(std::nullptr_t) { return nullptr; } | 190 static PassOutType passOut(std::nullptr_t) { return nullptr; } |
191 | 191 |
192 typedef P* PeekOutType; | 192 typedef P* PeekOutType; |
193 static PeekOutType peek(const RefPtr<P>& value) { return value.get(); } | 193 static PeekOutType peek(const RefPtr<P>& value) { return value.get(); } |
194 static PeekOutType peek(std::nullptr_t) { return 0; } | 194 static PeekOutType peek(std::nullptr_t) { return 0; } |
195 }; | 195 }; |
196 | 196 |
197 template<typename T> struct HashTraits<RawPtr<T> > : HashTraits<T*> { }; | 197 template<typename T> struct HashTraits<RawPtr<T>> : HashTraits<T*> { }; |
198 | 198 |
199 template<> struct HashTraits<String> : SimpleClassHashTraits<String> { | 199 template<> struct HashTraits<String> : SimpleClassHashTraits<String> { |
200 static const bool hasIsEmptyValueFunction = true; | 200 static const bool hasIsEmptyValueFunction = true; |
201 static bool isEmptyValue(const String&); | 201 static bool isEmptyValue(const String&); |
202 }; | 202 }; |
203 | 203 |
204 // This struct template is an implementation detail of the isHashTraitsEmpty
Value function, | 204 // This struct template is an implementation detail of the isHashTraitsEmpty
Value function, |
205 // which selects either the emptyValue function or the isEmptyValue function
to check for empty values. | 205 // which selects either the emptyValue function or the isEmptyValue function
to check for empty values. |
206 template<typename Traits, bool hasEmptyValueFunction> struct HashTraitsEmpty
ValueChecker; | 206 template<typename Traits, bool hasEmptyValueFunction> struct HashTraitsEmpty
ValueChecker; |
207 template<typename Traits> struct HashTraitsEmptyValueChecker<Traits, true> { | 207 template<typename Traits> struct HashTraitsEmptyValueChecker<Traits, true> { |
208 template<typename T> static bool isEmptyValue(const T& value) { return T
raits::isEmptyValue(value); } | 208 template<typename T> static bool isEmptyValue(const T& value) { return T
raits::isEmptyValue(value); } |
209 }; | 209 }; |
210 template<typename Traits> struct HashTraitsEmptyValueChecker<Traits, false>
{ | 210 template<typename Traits> struct HashTraitsEmptyValueChecker<Traits, false>
{ |
211 template<typename T> static bool isEmptyValue(const T& value) { return v
alue == Traits::emptyValue(); } | 211 template<typename T> static bool isEmptyValue(const T& value) { return v
alue == Traits::emptyValue(); } |
212 }; | 212 }; |
213 template<typename Traits, typename T> inline bool isHashTraitsEmptyValue(con
st T& value) | 213 template<typename Traits, typename T> inline bool isHashTraitsEmptyValue(con
st T& value) |
214 { | 214 { |
215 return HashTraitsEmptyValueChecker<Traits, Traits::hasIsEmptyValueFuncti
on>::isEmptyValue(value); | 215 return HashTraitsEmptyValueChecker<Traits, Traits::hasIsEmptyValueFuncti
on>::isEmptyValue(value); |
216 } | 216 } |
217 | 217 |
218 template<typename FirstTraitsArg, typename SecondTraitsArg> | 218 template<typename FirstTraitsArg, typename SecondTraitsArg> |
219 struct PairHashTraits : GenericHashTraits<std::pair<typename FirstTraitsArg:
:TraitType, typename SecondTraitsArg::TraitType> > { | 219 struct PairHashTraits : GenericHashTraits<std::pair<typename FirstTraitsArg:
:TraitType, typename SecondTraitsArg::TraitType>> { |
220 typedef FirstTraitsArg FirstTraits; | 220 typedef FirstTraitsArg FirstTraits; |
221 typedef SecondTraitsArg SecondTraits; | 221 typedef SecondTraitsArg SecondTraits; |
222 typedef std::pair<typename FirstTraits::TraitType, typename SecondTraits
::TraitType> TraitType; | 222 typedef std::pair<typename FirstTraits::TraitType, typename SecondTraits
::TraitType> TraitType; |
223 typedef std::pair<typename FirstTraits::EmptyValueType, typename SecondT
raits::EmptyValueType> EmptyValueType; | 223 typedef std::pair<typename FirstTraits::EmptyValueType, typename SecondT
raits::EmptyValueType> EmptyValueType; |
224 | 224 |
225 static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && Se
condTraits::emptyValueIsZero; | 225 static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && Se
condTraits::emptyValueIsZero; |
226 static EmptyValueType emptyValue() { return std::make_pair(FirstTraits::
emptyValue(), SecondTraits::emptyValue()); } | 226 static EmptyValueType emptyValue() { return std::make_pair(FirstTraits::
emptyValue(), SecondTraits::emptyValue()); } |
227 | 227 |
228 static const bool needsDestruction = FirstTraits::needsDestruction || Se
condTraits::needsDestruction; | 228 static const bool needsDestruction = FirstTraits::needsDestruction || Se
condTraits::needsDestruction; |
229 | 229 |
(...skipping 10 matching lines...) Expand all Loading... |
240 // zeroing must hold as they did at the initial allocation. | 240 // zeroing must hold as they did at the initial allocation. |
241 // Therefore we zero the value part of the slot here for GC | 241 // Therefore we zero the value part of the slot here for GC |
242 // collections. | 242 // collections. |
243 if (zeroValue) | 243 if (zeroValue) |
244 memset(reinterpret_cast<void*>(&slot.second), 0, sizeof(slot.sec
ond)); | 244 memset(reinterpret_cast<void*>(&slot.second), 0, sizeof(slot.sec
ond)); |
245 } | 245 } |
246 static bool isDeletedValue(const TraitType& value) { return FirstTraits:
:isDeletedValue(value.first); } | 246 static bool isDeletedValue(const TraitType& value) { return FirstTraits:
:isDeletedValue(value.first); } |
247 }; | 247 }; |
248 | 248 |
249 template<typename First, typename Second> | 249 template<typename First, typename Second> |
250 struct HashTraits<std::pair<First, Second> > : public PairHashTraits<HashTra
its<First>, HashTraits<Second> > { }; | 250 struct HashTraits<std::pair<First, Second>> : public PairHashTraits<HashTrai
ts<First>, HashTraits<Second>> { }; |
251 | 251 |
252 template<typename KeyTypeArg, typename ValueTypeArg> | 252 template<typename KeyTypeArg, typename ValueTypeArg> |
253 struct KeyValuePair { | 253 struct KeyValuePair { |
254 typedef KeyTypeArg KeyType; | 254 typedef KeyTypeArg KeyType; |
255 | 255 |
256 KeyValuePair(const KeyTypeArg& _key, const ValueTypeArg& _value) | 256 KeyValuePair(const KeyTypeArg& _key, const ValueTypeArg& _value) |
257 : key(_key) | 257 : key(_key) |
258 , value(_value) | 258 , value(_value) |
259 { | 259 { |
260 } | 260 } |
261 | 261 |
262 template <typename OtherKeyType, typename OtherValueType> | 262 template <typename OtherKeyType, typename OtherValueType> |
263 KeyValuePair(const KeyValuePair<OtherKeyType, OtherValueType>& other) | 263 KeyValuePair(const KeyValuePair<OtherKeyType, OtherValueType>& other) |
264 : key(other.key) | 264 : key(other.key) |
265 , value(other.value) | 265 , value(other.value) |
266 { | 266 { |
267 } | 267 } |
268 | 268 |
269 KeyTypeArg key; | 269 KeyTypeArg key; |
270 ValueTypeArg value; | 270 ValueTypeArg value; |
271 }; | 271 }; |
272 | 272 |
273 template<typename KeyTraitsArg, typename ValueTraitsArg> | 273 template<typename KeyTraitsArg, typename ValueTraitsArg> |
274 struct KeyValuePairHashTraits : GenericHashTraits<KeyValuePair<typename KeyT
raitsArg::TraitType, typename ValueTraitsArg::TraitType> > { | 274 struct KeyValuePairHashTraits : GenericHashTraits<KeyValuePair<typename KeyT
raitsArg::TraitType, typename ValueTraitsArg::TraitType>> { |
275 typedef KeyTraitsArg KeyTraits; | 275 typedef KeyTraitsArg KeyTraits; |
276 typedef ValueTraitsArg ValueTraits; | 276 typedef ValueTraitsArg ValueTraits; |
277 typedef KeyValuePair<typename KeyTraits::TraitType, typename ValueTraits
::TraitType> TraitType; | 277 typedef KeyValuePair<typename KeyTraits::TraitType, typename ValueTraits
::TraitType> TraitType; |
278 typedef KeyValuePair<typename KeyTraits::EmptyValueType, typename ValueT
raits::EmptyValueType> EmptyValueType; | 278 typedef KeyValuePair<typename KeyTraits::EmptyValueType, typename ValueT
raits::EmptyValueType> EmptyValueType; |
279 | 279 |
280 static const bool emptyValueIsZero = KeyTraits::emptyValueIsZero && Valu
eTraits::emptyValueIsZero; | 280 static const bool emptyValueIsZero = KeyTraits::emptyValueIsZero && Valu
eTraits::emptyValueIsZero; |
281 static EmptyValueType emptyValue() { return KeyValuePair<typename KeyTra
its::EmptyValueType, typename ValueTraits::EmptyValueType>(KeyTraits::emptyValue
(), ValueTraits::emptyValue()); } | 281 static EmptyValueType emptyValue() { return KeyValuePair<typename KeyTra
its::EmptyValueType, typename ValueTraits::EmptyValueType>(KeyTraits::emptyValue
(), ValueTraits::emptyValue()); } |
282 | 282 |
283 static const bool needsDestruction = KeyTraits::needsDestruction || Valu
eTraits::needsDestruction; | 283 static const bool needsDestruction = KeyTraits::needsDestruction || Valu
eTraits::needsDestruction; |
284 template<typename U = void> | 284 template<typename U = void> |
285 struct NeedsTracingLazily { | 285 struct NeedsTracingLazily { |
286 static const bool value = ShouldBeTraced<KeyTraits>::value || Should
BeTraced<ValueTraits>::value; | 286 static const bool value = ShouldBeTraced<KeyTraits>::value || Should
BeTraced<ValueTraits>::value; |
287 }; | 287 }; |
288 static const WeakHandlingFlag weakHandlingFlag = (KeyTraits::weakHandlin
gFlag == WeakHandlingInCollections || ValueTraits::weakHandlingFlag == WeakHandl
ingInCollections) ? WeakHandlingInCollections : NoWeakHandlingInCollections; | 288 static const WeakHandlingFlag weakHandlingFlag = (KeyTraits::weakHandlin
gFlag == WeakHandlingInCollections || ValueTraits::weakHandlingFlag == WeakHandl
ingInCollections) ? WeakHandlingInCollections : NoWeakHandlingInCollections; |
289 | 289 |
290 static const unsigned minimumTableSize = KeyTraits::minimumTableSize; | 290 static const unsigned minimumTableSize = KeyTraits::minimumTableSize; |
291 | 291 |
292 static void constructDeletedValue(TraitType& slot, bool zeroValue) | 292 static void constructDeletedValue(TraitType& slot, bool zeroValue) |
293 { | 293 { |
294 KeyTraits::constructDeletedValue(slot.key, zeroValue); | 294 KeyTraits::constructDeletedValue(slot.key, zeroValue); |
295 // See similar code in this file for why we need to do this. | 295 // See similar code in this file for why we need to do this. |
296 if (zeroValue) | 296 if (zeroValue) |
297 memset(reinterpret_cast<void*>(&slot.value), 0, sizeof(slot.valu
e)); | 297 memset(reinterpret_cast<void*>(&slot.value), 0, sizeof(slot.valu
e)); |
298 } | 298 } |
299 static bool isDeletedValue(const TraitType& value) { return KeyTraits::i
sDeletedValue(value.key); } | 299 static bool isDeletedValue(const TraitType& value) { return KeyTraits::i
sDeletedValue(value.key); } |
300 }; | 300 }; |
301 | 301 |
302 template<typename Key, typename Value> | 302 template<typename Key, typename Value> |
303 struct HashTraits<KeyValuePair<Key, Value> > : public KeyValuePairHashTraits
<HashTraits<Key>, HashTraits<Value> > { }; | 303 struct HashTraits<KeyValuePair<Key, Value>> : public KeyValuePairHashTraits<
HashTraits<Key>, HashTraits<Value>> { }; |
304 | 304 |
305 template<typename T> | 305 template<typename T> |
306 struct NullableHashTraits : public HashTraits<T> { | 306 struct NullableHashTraits : public HashTraits<T> { |
307 static const bool emptyValueIsZero = false; | 307 static const bool emptyValueIsZero = false; |
308 static T emptyValue() { return reinterpret_cast<T>(1); } | 308 static T emptyValue() { return reinterpret_cast<T>(1); } |
309 }; | 309 }; |
310 | 310 |
311 // This is for tracing inside collections that have special support for weak | 311 // This is for tracing inside collections that have special support for weak |
312 // pointers. The trait has a trace method which returns true if there are we
ak | 312 // pointers. The trait has a trace method which returns true if there are we
ak |
313 // pointers to things that have not (yet) been marked live. Returning true | 313 // pointers to things that have not (yet) been marked live. Returning true |
314 // indicates that the entry in the collection may yet be removed by weak | 314 // indicates that the entry in the collection may yet be removed by weak |
315 // handling. Default implementation for non-weak types is to use the regular | 315 // handling. Default implementation for non-weak types is to use the regular |
316 // non-weak TraceTrait. Default implementation for types with weakness is to | 316 // non-weak TraceTrait. Default implementation for types with weakness is to |
317 // call traceInCollection on the type's trait. | 317 // call traceInCollection on the type's trait. |
318 template<WeakHandlingFlag weakHandlingFlag, ShouldWeakPointersBeMarkedStrong
ly strongify, typename T, typename Traits> | 318 template<WeakHandlingFlag weakHandlingFlag, ShouldWeakPointersBeMarkedStrong
ly strongify, typename T, typename Traits> |
319 struct TraceInCollectionTrait; | 319 struct TraceInCollectionTrait; |
320 | 320 |
321 } // namespace WTF | 321 } // namespace WTF |
322 | 322 |
323 using WTF::HashTraits; | 323 using WTF::HashTraits; |
324 using WTF::PairHashTraits; | 324 using WTF::PairHashTraits; |
325 using WTF::NullableHashTraits; | 325 using WTF::NullableHashTraits; |
326 using WTF::SimpleClassHashTraits; | 326 using WTF::SimpleClassHashTraits; |
327 | 327 |
328 #endif // WTF_HashTraits_h | 328 #endif // WTF_HashTraits_h |
OLD | NEW |