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

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: 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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