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 * Copyright (C) 2011, Benjamin Poulain <ikipou@gmail.com> | 3 * Copyright (C) 2011, Benjamin Poulain <ikipou@gmail.com> |
4 * | 4 * |
5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
9 * | 9 * |
10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 typedef HashTable<Node*, Node*, IdentityExtractor, NodeHash, NodeTraits, Nod
eTraits, typename Allocator::TableAllocator> ImplType; | 67 typedef HashTable<Node*, Node*, IdentityExtractor, NodeHash, NodeTraits, Nod
eTraits, typename Allocator::TableAllocator> ImplType; |
68 typedef HashTableIterator<Node*, Node*, IdentityExtractor, NodeHash, NodeTra
its, NodeTraits, typename Allocator::TableAllocator> ImplTypeIterator; | 68 typedef HashTableIterator<Node*, Node*, IdentityExtractor, NodeHash, NodeTra
its, NodeTraits, typename Allocator::TableAllocator> ImplTypeIterator; |
69 typedef HashTableConstIterator<Node*, Node*, IdentityExtractor, NodeHash, No
deTraits, NodeTraits, typename Allocator::TableAllocator> ImplTypeConstIterator; | 69 typedef HashTableConstIterator<Node*, Node*, IdentityExtractor, NodeHash, No
deTraits, NodeTraits, typename Allocator::TableAllocator> ImplTypeConstIterator; |
70 | 70 |
71 typedef HashArg HashFunctions; | 71 typedef HashArg HashFunctions; |
72 | 72 |
73 public: | 73 public: |
74 typedef ValueArg ValueType; | 74 typedef ValueArg ValueType; |
75 typedef HashTraits<ValueType> ValueTraits; | 75 typedef HashTraits<ValueType> ValueTraits; |
76 typedef typename ValueTraits::PeekInType ValuePeekInType; | 76 typedef typename ValueTraits::PeekInType ValuePeekInType; |
77 typedef typename ValueTraits::PassInType ValuePassInType; | |
78 typedef typename ValueTraits::PassOutType ValuePassOutType; | 77 typedef typename ValueTraits::PassOutType ValuePassOutType; |
79 | 78 |
80 typedef ListHashSetIterator<ListHashSet> iterator; | 79 typedef ListHashSetIterator<ListHashSet> iterator; |
81 typedef ListHashSetConstIterator<ListHashSet> const_iterator; | 80 typedef ListHashSetConstIterator<ListHashSet> const_iterator; |
82 friend class ListHashSetIterator<ListHashSet>; | 81 friend class ListHashSetIterator<ListHashSet>; |
83 friend class ListHashSetConstIterator<ListHashSet>; | 82 friend class ListHashSetConstIterator<ListHashSet>; |
84 | 83 |
85 typedef ListHashSetReverseIterator<ListHashSet> reverse_iterator; | 84 typedef ListHashSetReverseIterator<ListHashSet> reverse_iterator; |
86 typedef ListHashSetConstReverseIterator<ListHashSet> const_reverse_iterator; | 85 typedef ListHashSetConstReverseIterator<ListHashSet> const_reverse_iterator; |
87 friend class ListHashSetReverseIterator<ListHashSet>; | 86 friend class ListHashSetReverseIterator<ListHashSet>; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 | 136 |
138 // An alternate version of find() that finds the object by hashing and | 137 // An alternate version of find() that finds the object by hashing and |
139 // comparing with some other type, to avoid the cost of type conversion. | 138 // comparing with some other type, to avoid the cost of type conversion. |
140 // The HashTranslator interface is defined in HashSet. | 139 // The HashTranslator interface is defined in HashSet. |
141 template <typename HashTranslator, typename T> iterator find(const T&); | 140 template <typename HashTranslator, typename T> iterator find(const T&); |
142 template <typename HashTranslator, typename T> const_iterator find(const T&)
const; | 141 template <typename HashTranslator, typename T> const_iterator find(const T&)
const; |
143 template <typename HashTranslator, typename T> bool contains(const T&) const
; | 142 template <typename HashTranslator, typename T> bool contains(const T&) const
; |
144 | 143 |
145 // The return value of add is a pair of a pointer to the stored value, and a | 144 // The return value of add is a pair of a pointer to the stored value, and a |
146 // bool that is true if an new entry was added. | 145 // bool that is true if an new entry was added. |
147 AddResult add(ValuePassInType); | 146 template <typename IncomingValueType> |
| 147 AddResult add(IncomingValueType&&); |
148 | 148 |
149 // Same as add() except that the return value is an iterator. Useful in | 149 // Same as add() except that the return value is an iterator. Useful in |
150 // cases where it's needed to have the same return value as find() and where | 150 // cases where it's needed to have the same return value as find() and where |
151 // it's not possible to use a pointer to the storedValue. | 151 // it's not possible to use a pointer to the storedValue. |
152 iterator addReturnIterator(ValuePassInType); | 152 template <typename IncomingValueType> |
| 153 iterator addReturnIterator(IncomingValueType&&); |
153 | 154 |
154 // Add the value to the end of the collection. If the value was already in | 155 // Add the value to the end of the collection. If the value was already in |
155 // the list, it is moved to the end. | 156 // the list, it is moved to the end. |
156 AddResult appendOrMoveToLast(ValuePassInType); | 157 template <typename IncomingValueType> |
| 158 AddResult appendOrMoveToLast(IncomingValueType&&); |
157 | 159 |
158 // Add the value to the beginning of the collection. If the value was | 160 // Add the value to the beginning of the collection. If the value was |
159 // already in the list, it is moved to the beginning. | 161 // already in the list, it is moved to the beginning. |
160 AddResult prependOrMoveToFirst(ValuePassInType); | 162 template <typename IncomingValueType> |
| 163 AddResult prependOrMoveToFirst(IncomingValueType&&); |
161 | 164 |
162 AddResult insertBefore(ValuePeekInType beforeValue, ValuePassInType newValue
); | 165 template <typename IncomingValueType> |
163 AddResult insertBefore(iterator, ValuePassInType); | 166 AddResult insertBefore(ValuePeekInType beforeValue, IncomingValueType&& newV
alue); |
| 167 template <typename IncomingValueType> |
| 168 AddResult insertBefore(iterator, IncomingValueType&&); |
164 | 169 |
165 void remove(ValuePeekInType value) { return remove(find(value)); } | 170 void remove(ValuePeekInType value) { return remove(find(value)); } |
166 void remove(iterator); | 171 void remove(iterator); |
167 void clear(); | 172 void clear(); |
168 template <typename Collection> | 173 template <typename Collection> |
169 void removeAll(const Collection& other) { WTF::removeAll(*this, other); } | 174 void removeAll(const Collection& other) { WTF::removeAll(*this, other); } |
170 | 175 |
171 ValuePassOutType take(iterator); | 176 ValuePassOutType take(iterator); |
172 ValuePassOutType take(ValuePeekInType); | 177 ValuePassOutType take(ValuePeekInType); |
173 ValuePassOutType takeFirst(); | 178 ValuePassOutType takeFirst(); |
(...skipping 22 matching lines...) Expand all Loading... |
196 Node* m_tail; | 201 Node* m_tail; |
197 typename Allocator::AllocatorProvider m_allocatorProvider; | 202 typename Allocator::AllocatorProvider m_allocatorProvider; |
198 }; | 203 }; |
199 | 204 |
200 // ListHashSetNode has this base class to hold the members because the MSVC | 205 // ListHashSetNode has this base class to hold the members because the MSVC |
201 // compiler otherwise gets into circular template dependencies when trying to do | 206 // compiler otherwise gets into circular template dependencies when trying to do |
202 // sizeof on a node. | 207 // sizeof on a node. |
203 template <typename ValueArg> class ListHashSetNodeBase { | 208 template <typename ValueArg> class ListHashSetNodeBase { |
204 DISALLOW_NEW(); | 209 DISALLOW_NEW(); |
205 protected: | 210 protected: |
206 ListHashSetNodeBase(const ValueArg& value) | 211 template <typename U> |
207 : m_value(value) | 212 explicit ListHashSetNodeBase(U&& value) |
| 213 : m_value(std::forward<U>(value)) |
208 , m_prev(nullptr) | 214 , m_prev(nullptr) |
209 , m_next(nullptr) | 215 , m_next(nullptr) |
210 #if ENABLE(ASSERT) | 216 #if ENABLE(ASSERT) |
211 , m_isAllocated(true) | |
212 #endif | |
213 { | |
214 } | |
215 | |
216 template <typename U> | |
217 ListHashSetNodeBase(const U& value) | |
218 : m_value(value) | |
219 , m_prev(nullptr) | |
220 , m_next(nullptr) | |
221 #if ENABLE(ASSERT) | |
222 , m_isAllocated(true) | 217 , m_isAllocated(true) |
223 #endif | 218 #endif |
224 { | 219 { |
225 } | 220 } |
226 | 221 |
227 public: | 222 public: |
228 ValueArg m_value; | 223 ValueArg m_value; |
229 ListHashSetNodeBase* m_prev; | 224 ListHashSetNodeBase* m_prev; |
230 ListHashSetNodeBase* m_next; | 225 ListHashSetNodeBase* m_next; |
231 #if ENABLE(ASSERT) | 226 #if ENABLE(ASSERT) |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 #endif | 344 #endif |
350 AlignedBuffer<sizeof(NodeBase) * m_poolSize, WTF_ALIGN_OF(NodeBase)> m_pool; | 345 AlignedBuffer<sizeof(NodeBase) * m_poolSize, WTF_ALIGN_OF(NodeBase)> m_pool; |
351 }; | 346 }; |
352 | 347 |
353 template <typename ValueArg, typename AllocatorArg> class ListHashSetNode : publ
ic ListHashSetNodeBase<ValueArg> { | 348 template <typename ValueArg, typename AllocatorArg> class ListHashSetNode : publ
ic ListHashSetNodeBase<ValueArg> { |
354 public: | 349 public: |
355 typedef AllocatorArg NodeAllocator; | 350 typedef AllocatorArg NodeAllocator; |
356 typedef ValueArg Value; | 351 typedef ValueArg Value; |
357 | 352 |
358 template <typename U> | 353 template <typename U> |
359 ListHashSetNode(U value) | 354 ListHashSetNode(U&& value) |
360 : ListHashSetNodeBase<ValueArg>(value) {} | 355 : ListHashSetNodeBase<ValueArg>(std::forward<U>(value)) {} |
361 | 356 |
362 void* operator new(size_t, NodeAllocator* allocator) | 357 void* operator new(size_t, NodeAllocator* allocator) |
363 { | 358 { |
364 static_assert(sizeof(ListHashSetNode) == sizeof(ListHashSetNodeBase<Valu
eArg>), "please add any fields to the base"); | 359 static_assert(sizeof(ListHashSetNode) == sizeof(ListHashSetNodeBase<Valu
eArg>), "please add any fields to the base"); |
365 return allocator->allocateNode(); | 360 return allocator->allocateNode(); |
366 } | 361 } |
367 | 362 |
368 void setWasAlreadyDestructed() | 363 void setWasAlreadyDestructed() |
369 { | 364 { |
370 if (NodeAllocator::isGarbageCollected && !IsTriviallyDestructible<ValueA
rg>::value) | 365 if (NodeAllocator::isGarbageCollected && !IsTriviallyDestructible<ValueA
rg>::value) |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 | 652 |
658 template <typename T, size_t inlineCapacity, typename U, typename V> | 653 template <typename T, size_t inlineCapacity, typename U, typename V> |
659 friend class ListHashSet; | 654 friend class ListHashSet; |
660 }; | 655 }; |
661 | 656 |
662 template <typename HashFunctions> | 657 template <typename HashFunctions> |
663 struct ListHashSetTranslator { | 658 struct ListHashSetTranslator { |
664 STATIC_ONLY(ListHashSetTranslator); | 659 STATIC_ONLY(ListHashSetTranslator); |
665 template <typename T> static unsigned hash(const T& key) { return HashFuncti
ons::hash(key); } | 660 template <typename T> static unsigned hash(const T& key) { return HashFuncti
ons::hash(key); } |
666 template <typename T, typename U> static bool equal(const T& a, const U& b)
{ return HashFunctions::equal(a->m_value, b); } | 661 template <typename T, typename U> static bool equal(const T& a, const U& b)
{ return HashFunctions::equal(a->m_value, b); } |
667 template <typename T, typename U, typename V> static void translate(T*& loca
tion, const U& key, const V& allocator) | 662 template <typename T, typename U, typename V> static void translate(T*& loca
tion, U&& key, const V& allocator) |
668 { | 663 { |
669 location = new (const_cast<V*>(&allocator)) T(key); | 664 location = new (const_cast<V*>(&allocator)) T(std::forward<U>(key)); |
670 } | 665 } |
671 }; | 666 }; |
672 | 667 |
673 template <typename T, size_t inlineCapacity, typename U, typename V> | 668 template <typename T, size_t inlineCapacity, typename U, typename V> |
674 inline ListHashSet<T, inlineCapacity, U, V>::ListHashSet() | 669 inline ListHashSet<T, inlineCapacity, U, V>::ListHashSet() |
675 : m_head(nullptr) | 670 : m_head(nullptr) |
676 , m_tail(nullptr) | 671 , m_tail(nullptr) |
677 { | 672 { |
678 } | 673 } |
679 | 674 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 return m_impl.template contains<ListHashSetTranslatorAdapter<HashTranslator>
>(value); | 818 return m_impl.template contains<ListHashSetTranslatorAdapter<HashTranslator>
>(value); |
824 } | 819 } |
825 | 820 |
826 template <typename T, size_t inlineCapacity, typename U, typename V> | 821 template <typename T, size_t inlineCapacity, typename U, typename V> |
827 inline bool ListHashSet<T, inlineCapacity, U, V>::contains(ValuePeekInType value
) const | 822 inline bool ListHashSet<T, inlineCapacity, U, V>::contains(ValuePeekInType value
) const |
828 { | 823 { |
829 return m_impl.template contains<BaseTranslator>(value); | 824 return m_impl.template contains<BaseTranslator>(value); |
830 } | 825 } |
831 | 826 |
832 template <typename T, size_t inlineCapacity, typename U, typename V> | 827 template <typename T, size_t inlineCapacity, typename U, typename V> |
833 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa
pacity, U, V>::add(ValuePassInType value) | 828 template <typename IncomingValueType> |
| 829 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa
pacity, U, V>::add(IncomingValueType&& value) |
834 { | 830 { |
835 createAllocatorIfNeeded(); | 831 createAllocatorIfNeeded(); |
836 // The second argument is a const ref. This is useful for the HashTable | 832 // The second argument is a const ref. This is useful for the HashTable |
837 // because it lets it take lvalues by reference, but for our purposes it's | 833 // because it lets it take lvalues by reference, but for our purposes it's |
838 // inconvenient, since it constrains us to be const, whereas the allocator | 834 // inconvenient, since it constrains us to be const, whereas the allocator |
839 // actually changes when it does allocations. | 835 // actually changes when it does allocations. |
840 auto result = m_impl.template add<BaseTranslator>(value, *this->allocator())
; | 836 auto result = m_impl.template add<BaseTranslator>(std::forward<IncomingValue
Type>(value), *this->allocator()); |
841 if (result.isNewEntry) | 837 if (result.isNewEntry) |
842 appendNode(*result.storedValue); | 838 appendNode(*result.storedValue); |
843 return AddResult(*result.storedValue, result.isNewEntry); | 839 return AddResult(*result.storedValue, result.isNewEntry); |
844 } | 840 } |
845 | 841 |
846 template <typename T, size_t inlineCapacity, typename U, typename V> | 842 template <typename T, size_t inlineCapacity, typename U, typename V> |
847 typename ListHashSet<T, inlineCapacity, U, V>::iterator ListHashSet<T, inlineCap
acity, U, V>::addReturnIterator(ValuePassInType value) | 843 template <typename IncomingValueType> |
| 844 typename ListHashSet<T, inlineCapacity, U, V>::iterator ListHashSet<T, inlineCap
acity, U, V>::addReturnIterator(IncomingValueType&& value) |
848 { | 845 { |
849 return makeIterator(add(value).m_node); | 846 return makeIterator(add(std::forward<IncomingValueType>(value)).m_node); |
850 } | 847 } |
851 | 848 |
852 template <typename T, size_t inlineCapacity, typename U, typename V> | 849 template <typename T, size_t inlineCapacity, typename U, typename V> |
853 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa
pacity, U, V>::appendOrMoveToLast(ValuePassInType value) | 850 template <typename IncomingValueType> |
| 851 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa
pacity, U, V>::appendOrMoveToLast(IncomingValueType&& value) |
854 { | 852 { |
855 createAllocatorIfNeeded(); | 853 createAllocatorIfNeeded(); |
856 auto result = m_impl.template add<BaseTranslator>(value, *this->allocator())
; | 854 auto result = m_impl.template add<BaseTranslator>(std::forward<IncomingValue
Type>(value), *this->allocator()); |
857 Node* node = *result.storedValue; | 855 Node* node = *result.storedValue; |
858 if (!result.isNewEntry) | 856 if (!result.isNewEntry) |
859 unlink(node); | 857 unlink(node); |
860 appendNode(node); | 858 appendNode(node); |
861 return AddResult(*result.storedValue, result.isNewEntry); | 859 return AddResult(*result.storedValue, result.isNewEntry); |
862 } | 860 } |
863 | 861 |
864 template <typename T, size_t inlineCapacity, typename U, typename V> | 862 template <typename T, size_t inlineCapacity, typename U, typename V> |
865 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa
pacity, U, V>::prependOrMoveToFirst(ValuePassInType value) | 863 template <typename IncomingValueType> |
| 864 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa
pacity, U, V>::prependOrMoveToFirst(IncomingValueType&& value) |
866 { | 865 { |
867 createAllocatorIfNeeded(); | 866 createAllocatorIfNeeded(); |
868 auto result = m_impl.template add<BaseTranslator>(value, *this->allocator())
; | 867 auto result = m_impl.template add<BaseTranslator>(std::forward<IncomingValue
Type>(value), *this->allocator()); |
869 Node* node = *result.storedValue; | 868 Node* node = *result.storedValue; |
870 if (!result.isNewEntry) | 869 if (!result.isNewEntry) |
871 unlink(node); | 870 unlink(node); |
872 prependNode(node); | 871 prependNode(node); |
873 return AddResult(*result.storedValue, result.isNewEntry); | 872 return AddResult(*result.storedValue, result.isNewEntry); |
874 } | 873 } |
875 | 874 |
876 template <typename T, size_t inlineCapacity, typename U, typename V> | 875 template <typename T, size_t inlineCapacity, typename U, typename V> |
877 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa
pacity, U, V>::insertBefore(iterator it, ValuePassInType newValue) | 876 template <typename IncomingValueType> |
| 877 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa
pacity, U, V>::insertBefore(iterator it, IncomingValueType&& newValue) |
878 { | 878 { |
879 createAllocatorIfNeeded(); | 879 createAllocatorIfNeeded(); |
880 auto result = m_impl.template add<BaseTranslator>(newValue, *this->allocator
()); | 880 auto result = m_impl.template add<BaseTranslator>(std::forward<IncomingValue
Type>(newValue), *this->allocator()); |
881 if (result.isNewEntry) | 881 if (result.isNewEntry) |
882 insertNodeBefore(it.node(), *result.storedValue); | 882 insertNodeBefore(it.node(), *result.storedValue); |
883 return AddResult(*result.storedValue, result.isNewEntry); | 883 return AddResult(*result.storedValue, result.isNewEntry); |
884 } | 884 } |
885 | 885 |
886 template <typename T, size_t inlineCapacity, typename U, typename V> | 886 template <typename T, size_t inlineCapacity, typename U, typename V> |
887 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa
pacity, U, V>::insertBefore(ValuePeekInType beforeValue, ValuePassInType newValu
e) | 887 template <typename IncomingValueType> |
| 888 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa
pacity, U, V>::insertBefore(ValuePeekInType beforeValue, IncomingValueType&& new
Value) |
888 { | 889 { |
889 createAllocatorIfNeeded(); | 890 createAllocatorIfNeeded(); |
890 return insertBefore(find(beforeValue), newValue); | 891 return insertBefore(find(beforeValue), std::forward<IncomingValueType>(newVa
lue)); |
891 } | 892 } |
892 | 893 |
893 template <typename T, size_t inlineCapacity, typename U, typename V> | 894 template <typename T, size_t inlineCapacity, typename U, typename V> |
894 inline void ListHashSet<T, inlineCapacity, U, V>::remove(iterator it) | 895 inline void ListHashSet<T, inlineCapacity, U, V>::remove(iterator it) |
895 { | 896 { |
896 if (it == end()) | 897 if (it == end()) |
897 return; | 898 return; |
898 m_impl.remove(it.node()); | 899 m_impl.remove(it.node()); |
899 unlinkAndDelete(it.node()); | 900 unlinkAndDelete(it.node()); |
900 } | 901 } |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1038 struct NeedsTracing<ListHashSet<T, U, V>> { | 1039 struct NeedsTracing<ListHashSet<T, U, V>> { |
1039 static const bool value = false; | 1040 static const bool value = false; |
1040 }; | 1041 }; |
1041 #endif | 1042 #endif |
1042 | 1043 |
1043 } // namespace WTF | 1044 } // namespace WTF |
1044 | 1045 |
1045 using WTF::ListHashSet; | 1046 using WTF::ListHashSet; |
1046 | 1047 |
1047 #endif // WTF_ListHashSet_h | 1048 #endif // WTF_ListHashSet_h |
OLD | NEW |