Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(891)

Side by Side Diff: third_party/WebKit/Source/wtf/ListHashSet.h

Issue 1807153002: WTF: Implement move semantics for values of {List,Linked}HashSet. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ListHashSet-AddResult
Patch Set: Remove ValuePassInType. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/LinkedHashSet.h ('k') | third_party/WebKit/Source/wtf/ListHashSetTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698