• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  *
19  */
20 
21 #ifndef WTF_HashCountedSet_h
22 #define WTF_HashCountedSet_h
23 
24 #include "wtf/Assertions.h"
25 #include "wtf/HashMap.h"
26 #include "wtf/Vector.h"
27 
28 namespace WTF {
29 
30     template<typename Value, typename HashFunctions = typename DefaultHash<Value>::Hash,
31         typename Traits = HashTraits<Value> > class HashCountedSet {
32         WTF_MAKE_FAST_ALLOCATED;
33     private:
34         typedef HashMap<Value, unsigned, HashFunctions, Traits> ImplType;
35     public:
36         typedef Value ValueType;
37         typedef typename ImplType::iterator iterator;
38         typedef typename ImplType::const_iterator const_iterator;
39         typedef typename ImplType::AddResult AddResult;
40 
HashCountedSet()41         HashCountedSet() {}
42 
43         void swap(HashCountedSet&);
44 
45         unsigned size() const;
46         unsigned capacity() const;
47         bool isEmpty() const;
48 
49         // Iterators iterate over pairs of values and counts.
50         iterator begin();
51         iterator end();
52         const_iterator begin() const;
53         const_iterator end() const;
54 
55         iterator find(const ValueType&);
56         const_iterator find(const ValueType&) const;
57         bool contains(const ValueType&) const;
58         unsigned count(const ValueType&) const;
59 
60         // Increases the count if an equal value is already present
61         // the return value is a pair of an interator to the new value's
62         // location, and a bool that is true if an new entry was added.
63         AddResult add(const ValueType&);
64 
65         // Reduces the count of the value, and removes it if count
66         // goes down to zero, returns true if the value is removed.
67         bool remove(const ValueType&);
68         bool remove(iterator);
69 
70         // Removes the value, regardless of its count.
71         void removeAll(iterator);
72         void removeAll(const ValueType&);
73 
74         // Clears the whole set.
75         void clear();
76 
77     private:
78         ImplType m_impl;
79     };
80 
81     template<typename Value, typename HashFunctions, typename Traits>
swap(HashCountedSet & other)82     inline void HashCountedSet<Value, HashFunctions, Traits>::swap(HashCountedSet& other)
83     {
84         m_impl.swap(other.m_impl);
85     }
86 
87     template<typename Value, typename HashFunctions, typename Traits>
size()88     inline unsigned HashCountedSet<Value, HashFunctions, Traits>::size() const
89     {
90         return m_impl.size();
91     }
92 
93     template<typename Value, typename HashFunctions, typename Traits>
capacity()94     inline unsigned HashCountedSet<Value, HashFunctions, Traits>::capacity() const
95     {
96         return m_impl.capacity();
97     }
98 
99     template<typename Value, typename HashFunctions, typename Traits>
isEmpty()100     inline bool HashCountedSet<Value, HashFunctions, Traits>::isEmpty() const
101     {
102         return size() == 0;
103     }
104 
105     template<typename Value, typename HashFunctions, typename Traits>
begin()106     inline typename HashCountedSet<Value, HashFunctions, Traits>::iterator HashCountedSet<Value, HashFunctions, Traits>::begin()
107     {
108         return m_impl.begin();
109     }
110 
111     template<typename Value, typename HashFunctions, typename Traits>
end()112     inline typename HashCountedSet<Value, HashFunctions, Traits>::iterator HashCountedSet<Value, HashFunctions, Traits>::end()
113     {
114         return m_impl.end();
115     }
116 
117     template<typename Value, typename HashFunctions, typename Traits>
begin()118     inline typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator HashCountedSet<Value, HashFunctions, Traits>::begin() const
119     {
120         return m_impl.begin();
121     }
122 
123     template<typename Value, typename HashFunctions, typename Traits>
end()124     inline typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator HashCountedSet<Value, HashFunctions, Traits>::end() const
125     {
126         return m_impl.end();
127     }
128 
129     template<typename Value, typename HashFunctions, typename Traits>
find(const ValueType & value)130     inline typename HashCountedSet<Value, HashFunctions, Traits>::iterator HashCountedSet<Value, HashFunctions, Traits>::find(const ValueType& value)
131     {
132         return m_impl.find(value);
133     }
134 
135     template<typename Value, typename HashFunctions, typename Traits>
find(const ValueType & value)136     inline typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator HashCountedSet<Value, HashFunctions, Traits>::find(const ValueType& value) const
137     {
138         return m_impl.find(value);
139     }
140 
141     template<typename Value, typename HashFunctions, typename Traits>
contains(const ValueType & value)142     inline bool HashCountedSet<Value, HashFunctions, Traits>::contains(const ValueType& value) const
143     {
144         return m_impl.contains(value);
145     }
146 
147     template<typename Value, typename HashFunctions, typename Traits>
count(const ValueType & value)148     inline unsigned HashCountedSet<Value, HashFunctions, Traits>::count(const ValueType& value) const
149     {
150         return m_impl.get(value);
151     }
152 
153     template<typename Value, typename HashFunctions, typename Traits>
add(const ValueType & value)154     inline typename HashCountedSet<Value, HashFunctions, Traits>::AddResult HashCountedSet<Value, HashFunctions, Traits>::add(const ValueType &value)
155     {
156         AddResult result = m_impl.add(value, 0);
157         ++result.iterator->value;
158         return result;
159     }
160 
161     template<typename Value, typename HashFunctions, typename Traits>
remove(const ValueType & value)162     inline bool HashCountedSet<Value, HashFunctions, Traits>::remove(const ValueType& value)
163     {
164         return remove(find(value));
165     }
166 
167     template<typename Value, typename HashFunctions, typename Traits>
remove(iterator it)168     inline bool HashCountedSet<Value, HashFunctions, Traits>::remove(iterator it)
169     {
170         if (it == end())
171             return false;
172 
173         unsigned oldVal = it->value;
174         ASSERT(oldVal);
175         unsigned newVal = oldVal - 1;
176         if (newVal) {
177             it->value = newVal;
178             return false;
179         }
180 
181         m_impl.remove(it);
182         return true;
183     }
184 
185     template<typename Value, typename HashFunctions, typename Traits>
removeAll(const ValueType & value)186     inline void HashCountedSet<Value, HashFunctions, Traits>::removeAll(const ValueType& value)
187     {
188         removeAll(find(value));
189     }
190 
191     template<typename Value, typename HashFunctions, typename Traits>
removeAll(iterator it)192     inline void HashCountedSet<Value, HashFunctions, Traits>::removeAll(iterator it)
193     {
194         if (it == end())
195             return;
196 
197         m_impl.remove(it);
198     }
199 
200     template<typename Value, typename HashFunctions, typename Traits>
clear()201     inline void HashCountedSet<Value, HashFunctions, Traits>::clear()
202     {
203         m_impl.clear();
204     }
205 
206     template<typename Value, typename HashFunctions, typename Traits, typename VectorType>
copyToVector(const HashCountedSet<Value,HashFunctions,Traits> & collection,VectorType & vector)207     inline void copyToVector(const HashCountedSet<Value, HashFunctions, Traits>& collection, VectorType& vector)
208     {
209         typedef typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator iterator;
210 
211         vector.resize(collection.size());
212 
213         iterator it = collection.begin();
214         iterator end = collection.end();
215         for (unsigned i = 0; it != end; ++it, ++i)
216             vector[i] = *it;
217     }
218 
219     template<typename Value, typename HashFunctions, typename Traits>
copyToVector(const HashCountedSet<Value,HashFunctions,Traits> & collection,Vector<Value> & vector)220     inline void copyToVector(const HashCountedSet<Value, HashFunctions, Traits>& collection, Vector<Value>& vector)
221     {
222         typedef typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator iterator;
223 
224         vector.resize(collection.size());
225 
226         iterator it = collection.begin();
227         iterator end = collection.end();
228         for (unsigned i = 0; it != end; ++it, ++i)
229             vector[i] = (*it).key;
230     }
231 
232 
233 } // namespace WTF
234 
235 using WTF::HashCountedSet;
236 
237 #endif /* WTF_HashCountedSet_h */
238