Chromium Code Reviews| 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 |