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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 | 137 |
138 // An alternate version of find() that finds the object by hashing and | 138 // 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. | 139 // comparing with some other type, to avoid the cost of type conversion. |
140 // The HashTranslator interface is defined in HashSet. | 140 // The HashTranslator interface is defined in HashSet. |
141 template <typename HashTranslator, typename T> iterator find(const T&); | 141 template <typename HashTranslator, typename T> iterator find(const T&); |
142 template <typename HashTranslator, typename T> const_iterator find(const T&) const; | 142 template <typename HashTranslator, typename T> const_iterator find(const T&) const; |
143 template <typename HashTranslator, typename T> bool contains(const T&) const ; | 143 template <typename HashTranslator, typename T> bool contains(const T&) const ; |
144 | 144 |
145 // The return value of add is a pair of a pointer to the stored value, and a | 145 // 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. | 146 // bool that is true if an new entry was added. |
147 AddResult add(ValuePassInType); | 147 template <typename IncomingValueType> |
Mikhail
2016/03/17 09:17:48
if 'ValuePassInType' is not used any more, maybe i
Yuta Kitamura
2016/03/18 04:42:11
Done.
| |
148 AddResult add(IncomingValueType&&); | |
Mikhail
2016/03/17 09:17:48
Does this converting to template methods (here and
Yuta Kitamura
2016/03/18 04:42:11
I did this kind of transmutation many times in the
| |
148 | 149 |
149 // Same as add() except that the return value is an iterator. Useful in | 150 // 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 | 151 // 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. | 152 // it's not possible to use a pointer to the storedValue. |
152 iterator addReturnIterator(ValuePassInType); | 153 template <typename IncomingValueType> |
154 iterator addReturnIterator(IncomingValueType&&); | |
153 | 155 |
154 // Add the value to the end of the collection. If the value was already in | 156 // Add the value to the end of the collection. If the value was already in |
155 // the list, it is moved to the end. | 157 // the list, it is moved to the end. |
156 AddResult appendOrMoveToLast(ValuePassInType); | 158 template <typename IncomingValueType> |
159 AddResult appendOrMoveToLast(IncomingValueType&&); | |
157 | 160 |
158 // Add the value to the beginning of the collection. If the value was | 161 // Add the value to the beginning of the collection. If the value was |
159 // already in the list, it is moved to the beginning. | 162 // already in the list, it is moved to the beginning. |
160 AddResult prependOrMoveToFirst(ValuePassInType); | 163 template <typename IncomingValueType> |
164 AddResult prependOrMoveToFirst(IncomingValueType&&); | |
161 | 165 |
162 AddResult insertBefore(ValuePeekInType beforeValue, ValuePassInType newValue ); | 166 template <typename IncomingValueType> |
163 AddResult insertBefore(iterator, ValuePassInType); | 167 AddResult insertBefore(ValuePeekInType beforeValue, IncomingValueType&& newV alue); |
168 template <typename IncomingValueType> | |
169 AddResult insertBefore(iterator, IncomingValueType&&); | |
164 | 170 |
165 void remove(ValuePeekInType value) { return remove(find(value)); } | 171 void remove(ValuePeekInType value) { return remove(find(value)); } |
166 void remove(iterator); | 172 void remove(iterator); |
167 void clear(); | 173 void clear(); |
168 template <typename Collection> | 174 template <typename Collection> |
169 void removeAll(const Collection& other) { WTF::removeAll(*this, other); } | 175 void removeAll(const Collection& other) { WTF::removeAll(*this, other); } |
170 | 176 |
171 ValuePassOutType take(iterator); | 177 ValuePassOutType take(iterator); |
172 ValuePassOutType take(ValuePeekInType); | 178 ValuePassOutType take(ValuePeekInType); |
173 ValuePassOutType takeFirst(); | 179 ValuePassOutType takeFirst(); |
(...skipping 22 matching lines...) Expand all Loading... | |
196 Node* m_tail; | 202 Node* m_tail; |
197 typename Allocator::AllocatorProvider m_allocatorProvider; | 203 typename Allocator::AllocatorProvider m_allocatorProvider; |
198 }; | 204 }; |
199 | 205 |
200 // ListHashSetNode has this base class to hold the members because the MSVC | 206 // ListHashSetNode has this base class to hold the members because the MSVC |
201 // compiler otherwise gets into circular template dependencies when trying to do | 207 // compiler otherwise gets into circular template dependencies when trying to do |
202 // sizeof on a node. | 208 // sizeof on a node. |
203 template <typename ValueArg> class ListHashSetNodeBase { | 209 template <typename ValueArg> class ListHashSetNodeBase { |
204 DISALLOW_NEW(); | 210 DISALLOW_NEW(); |
205 protected: | 211 protected: |
206 ListHashSetNodeBase(const ValueArg& value) | 212 template <typename U> |
207 : m_value(value) | 213 explicit ListHashSetNodeBase(U&& value) |
214 : m_value(std::forward<U>(value)) | |
208 , m_prev(nullptr) | 215 , m_prev(nullptr) |
209 , m_next(nullptr) | 216 , m_next(nullptr) |
210 #if ENABLE(ASSERT) | 217 #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) | 218 , m_isAllocated(true) |
223 #endif | 219 #endif |
224 { | 220 { |
225 } | 221 } |
226 | 222 |
227 public: | 223 public: |
228 ValueArg m_value; | 224 ValueArg m_value; |
229 ListHashSetNodeBase* m_prev; | 225 ListHashSetNodeBase* m_prev; |
230 ListHashSetNodeBase* m_next; | 226 ListHashSetNodeBase* m_next; |
231 #if ENABLE(ASSERT) | 227 #if ENABLE(ASSERT) |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
349 #endif | 345 #endif |
350 AlignedBuffer<sizeof(NodeBase) * m_poolSize, WTF_ALIGN_OF(NodeBase)> m_pool; | 346 AlignedBuffer<sizeof(NodeBase) * m_poolSize, WTF_ALIGN_OF(NodeBase)> m_pool; |
351 }; | 347 }; |
352 | 348 |
353 template <typename ValueArg, typename AllocatorArg> class ListHashSetNode : publ ic ListHashSetNodeBase<ValueArg> { | 349 template <typename ValueArg, typename AllocatorArg> class ListHashSetNode : publ ic ListHashSetNodeBase<ValueArg> { |
354 public: | 350 public: |
355 typedef AllocatorArg NodeAllocator; | 351 typedef AllocatorArg NodeAllocator; |
356 typedef ValueArg Value; | 352 typedef ValueArg Value; |
357 | 353 |
358 template <typename U> | 354 template <typename U> |
359 ListHashSetNode(U value) | 355 ListHashSetNode(U&& value) |
360 : ListHashSetNodeBase<ValueArg>(value) {} | 356 : ListHashSetNodeBase<ValueArg>(std::forward<U>(value)) {} |
361 | 357 |
362 void* operator new(size_t, NodeAllocator* allocator) | 358 void* operator new(size_t, NodeAllocator* allocator) |
363 { | 359 { |
364 static_assert(sizeof(ListHashSetNode) == sizeof(ListHashSetNodeBase<Valu eArg>), "please add any fields to the base"); | 360 static_assert(sizeof(ListHashSetNode) == sizeof(ListHashSetNodeBase<Valu eArg>), "please add any fields to the base"); |
365 return allocator->allocateNode(); | 361 return allocator->allocateNode(); |
366 } | 362 } |
367 | 363 |
368 void setWasAlreadyDestructed() | 364 void setWasAlreadyDestructed() |
369 { | 365 { |
370 if (NodeAllocator::isGarbageCollected && !IsTriviallyDestructible<ValueA rg>::value) | 366 if (NodeAllocator::isGarbageCollected && !IsTriviallyDestructible<ValueA rg>::value) |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
657 | 653 |
658 template <typename T, size_t inlineCapacity, typename U, typename V> | 654 template <typename T, size_t inlineCapacity, typename U, typename V> |
659 friend class ListHashSet; | 655 friend class ListHashSet; |
660 }; | 656 }; |
661 | 657 |
662 template <typename HashFunctions> | 658 template <typename HashFunctions> |
663 struct ListHashSetTranslator { | 659 struct ListHashSetTranslator { |
664 STATIC_ONLY(ListHashSetTranslator); | 660 STATIC_ONLY(ListHashSetTranslator); |
665 template <typename T> static unsigned hash(const T& key) { return HashFuncti ons::hash(key); } | 661 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); } | 662 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) | 663 template <typename T, typename U, typename V> static void translate(T*& loca tion, U&& key, const V& allocator) |
668 { | 664 { |
669 location = new (const_cast<V*>(&allocator)) T(key); | 665 location = new (const_cast<V*>(&allocator)) T(std::forward<U>(key)); |
670 } | 666 } |
671 }; | 667 }; |
672 | 668 |
673 template <typename T, size_t inlineCapacity, typename U, typename V> | 669 template <typename T, size_t inlineCapacity, typename U, typename V> |
674 inline ListHashSet<T, inlineCapacity, U, V>::ListHashSet() | 670 inline ListHashSet<T, inlineCapacity, U, V>::ListHashSet() |
675 : m_head(nullptr) | 671 : m_head(nullptr) |
676 , m_tail(nullptr) | 672 , m_tail(nullptr) |
677 { | 673 { |
678 } | 674 } |
679 | 675 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
823 return m_impl.template contains<ListHashSetTranslatorAdapter<HashTranslator> >(value); | 819 return m_impl.template contains<ListHashSetTranslatorAdapter<HashTranslator> >(value); |
824 } | 820 } |
825 | 821 |
826 template <typename T, size_t inlineCapacity, typename U, typename V> | 822 template <typename T, size_t inlineCapacity, typename U, typename V> |
827 inline bool ListHashSet<T, inlineCapacity, U, V>::contains(ValuePeekInType value ) const | 823 inline bool ListHashSet<T, inlineCapacity, U, V>::contains(ValuePeekInType value ) const |
828 { | 824 { |
829 return m_impl.template contains<BaseTranslator>(value); | 825 return m_impl.template contains<BaseTranslator>(value); |
830 } | 826 } |
831 | 827 |
832 template <typename T, size_t inlineCapacity, typename U, typename V> | 828 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) | 829 template <typename IncomingValueType> |
830 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa pacity, U, V>::add(IncomingValueType&& value) | |
834 { | 831 { |
835 createAllocatorIfNeeded(); | 832 createAllocatorIfNeeded(); |
836 // The second argument is a const ref. This is useful for the HashTable | 833 // 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 | 834 // 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 | 835 // inconvenient, since it constrains us to be const, whereas the allocator |
839 // actually changes when it does allocations. | 836 // actually changes when it does allocations. |
840 auto result = m_impl.template add<BaseTranslator>(value, *this->allocator()) ; | 837 auto result = m_impl.template add<BaseTranslator>(std::forward<IncomingValue Type>(value), *this->allocator()); |
841 if (result.isNewEntry) | 838 if (result.isNewEntry) |
842 appendNode(*result.storedValue); | 839 appendNode(*result.storedValue); |
843 return AddResult(*result.storedValue, result.isNewEntry); | 840 return AddResult(*result.storedValue, result.isNewEntry); |
844 } | 841 } |
845 | 842 |
846 template <typename T, size_t inlineCapacity, typename U, typename V> | 843 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) | 844 template <typename IncomingValueType> |
845 typename ListHashSet<T, inlineCapacity, U, V>::iterator ListHashSet<T, inlineCap acity, U, V>::addReturnIterator(IncomingValueType&& value) | |
848 { | 846 { |
849 return makeIterator(add(value).m_node); | 847 return makeIterator(add(std::forward<IncomingValueType>(value)).m_node); |
850 } | 848 } |
851 | 849 |
852 template <typename T, size_t inlineCapacity, typename U, typename V> | 850 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) | 851 template <typename IncomingValueType> |
852 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa pacity, U, V>::appendOrMoveToLast(IncomingValueType&& value) | |
854 { | 853 { |
855 createAllocatorIfNeeded(); | 854 createAllocatorIfNeeded(); |
856 auto result = m_impl.template add<BaseTranslator>(value, *this->allocator()) ; | 855 auto result = m_impl.template add<BaseTranslator>(std::forward<IncomingValue Type>(value), *this->allocator()); |
857 Node* node = *result.storedValue; | 856 Node* node = *result.storedValue; |
858 if (!result.isNewEntry) | 857 if (!result.isNewEntry) |
859 unlink(node); | 858 unlink(node); |
860 appendNode(node); | 859 appendNode(node); |
861 return AddResult(*result.storedValue, result.isNewEntry); | 860 return AddResult(*result.storedValue, result.isNewEntry); |
862 } | 861 } |
863 | 862 |
864 template <typename T, size_t inlineCapacity, typename U, typename V> | 863 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) | 864 template <typename IncomingValueType> |
865 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa pacity, U, V>::prependOrMoveToFirst(IncomingValueType&& value) | |
866 { | 866 { |
867 createAllocatorIfNeeded(); | 867 createAllocatorIfNeeded(); |
868 auto result = m_impl.template add<BaseTranslator>(value, *this->allocator()) ; | 868 auto result = m_impl.template add<BaseTranslator>(std::forward<IncomingValue Type>(value), *this->allocator()); |
869 Node* node = *result.storedValue; | 869 Node* node = *result.storedValue; |
870 if (!result.isNewEntry) | 870 if (!result.isNewEntry) |
871 unlink(node); | 871 unlink(node); |
872 prependNode(node); | 872 prependNode(node); |
873 return AddResult(*result.storedValue, result.isNewEntry); | 873 return AddResult(*result.storedValue, result.isNewEntry); |
874 } | 874 } |
875 | 875 |
876 template <typename T, size_t inlineCapacity, typename U, typename V> | 876 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) | 877 template <typename IncomingValueType> |
878 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa pacity, U, V>::insertBefore(iterator it, IncomingValueType&& newValue) | |
878 { | 879 { |
879 createAllocatorIfNeeded(); | 880 createAllocatorIfNeeded(); |
880 auto result = m_impl.template add<BaseTranslator>(newValue, *this->allocator ()); | 881 auto result = m_impl.template add<BaseTranslator>(std::forward<IncomingValue Type>(newValue), *this->allocator()); |
881 if (result.isNewEntry) | 882 if (result.isNewEntry) |
882 insertNodeBefore(it.node(), *result.storedValue); | 883 insertNodeBefore(it.node(), *result.storedValue); |
883 return AddResult(*result.storedValue, result.isNewEntry); | 884 return AddResult(*result.storedValue, result.isNewEntry); |
884 } | 885 } |
885 | 886 |
886 template <typename T, size_t inlineCapacity, typename U, typename V> | 887 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) | 888 template <typename IncomingValueType> |
889 typename ListHashSet<T, inlineCapacity, U, V>::AddResult ListHashSet<T, inlineCa pacity, U, V>::insertBefore(ValuePeekInType beforeValue, IncomingValueType&& new Value) | |
888 { | 890 { |
889 createAllocatorIfNeeded(); | 891 createAllocatorIfNeeded(); |
890 return insertBefore(find(beforeValue), newValue); | 892 return insertBefore(find(beforeValue), std::forward<IncomingValueType>(newVa lue)); |
891 } | 893 } |
892 | 894 |
893 template <typename T, size_t inlineCapacity, typename U, typename V> | 895 template <typename T, size_t inlineCapacity, typename U, typename V> |
894 inline void ListHashSet<T, inlineCapacity, U, V>::remove(iterator it) | 896 inline void ListHashSet<T, inlineCapacity, U, V>::remove(iterator it) |
895 { | 897 { |
896 if (it == end()) | 898 if (it == end()) |
897 return; | 899 return; |
898 m_impl.remove(it.node()); | 900 m_impl.remove(it.node()); |
899 unlinkAndDelete(it.node()); | 901 unlinkAndDelete(it.node()); |
900 } | 902 } |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1038 struct NeedsTracing<ListHashSet<T, U, V>> { | 1040 struct NeedsTracing<ListHashSet<T, U, V>> { |
1039 static const bool value = false; | 1041 static const bool value = false; |
1040 }; | 1042 }; |
1041 #endif | 1043 #endif |
1042 | 1044 |
1043 } // namespace WTF | 1045 } // namespace WTF |
1044 | 1046 |
1045 using WTF::ListHashSet; | 1047 using WTF::ListHashSet; |
1046 | 1048 |
1047 #endif // WTF_ListHashSet_h | 1049 #endif // WTF_ListHashSet_h |
OLD | NEW |