File indexing completed on 2024-05-12 15:43:37

0001 /*
0002  * This file is part of the KDE libraries
0003  * Copyright (C) 2005 Apple Computer, Inc.
0004  *
0005  * This library is free software; you can redistribute it and/or
0006  * modify it under the terms of the GNU Library General Public
0007  * License as published by the Free Software Foundation; either
0008  * version 2 of the License, or (at your option) any later version.
0009  *
0010  * This library is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013  * Library General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU Library General Public License
0016  * along with this library; see the file COPYING.LIB.  If not, write to
0017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018  * Boston, MA 02110-1301, USA.
0019  *
0020  */
0021 
0022 #ifndef WTF_HashCountedSet_h
0023 #define WTF_HashCountedSet_h
0024 
0025 #include <wtf/Assertions.h>
0026 #include <wtf/HashMap.h>
0027 #include <wtf/Vector.h>
0028 
0029 namespace WTF
0030 {
0031 
0032 template<typename Value, typename HashFunctions = typename DefaultHash<Value>::Hash,
0033          typename Traits = HashTraits<Value> > class HashCountedSet
0034 {
0035 private:
0036     typedef HashMap<Value, unsigned, HashFunctions, Traits> ImplType;
0037 public:
0038     typedef Value ValueType;
0039     typedef typename ImplType::iterator iterator;
0040     typedef typename ImplType::const_iterator const_iterator;
0041 
0042     HashCountedSet() {}
0043 
0044     int size() const;
0045     int capacity() const;
0046     bool isEmpty() const;
0047 
0048     // iterators iterate over pairs of values and counts
0049     iterator begin();
0050     iterator end();
0051     const_iterator begin() const;
0052     const_iterator end() const;
0053 
0054     iterator find(const ValueType &value);
0055     const_iterator find(const ValueType &value) const;
0056     bool contains(const ValueType &value) const;
0057     unsigned count(const ValueType &value) const;
0058 
0059     // increases the count if an equal value is already present
0060     // the return value is a pair of an iterator to the new value's location,
0061     // and a bool that is true if an new entry was added
0062     std::pair<iterator, bool> add(const ValueType &value);
0063 
0064     // reduces the count of the value, and removes it if count
0065     // goes down to zero
0066     void remove(const ValueType &value);
0067     void remove(iterator it);
0068 
0069     void clear();
0070 
0071 private:
0072     ImplType m_impl;
0073 };
0074 
0075 template<typename Value, typename HashFunctions, typename Traits>
0076 inline int HashCountedSet<Value, HashFunctions, Traits>::size() const
0077 {
0078     return m_impl.size();
0079 }
0080 
0081 template<typename Value, typename HashFunctions, typename Traits>
0082 inline int HashCountedSet<Value, HashFunctions, Traits>::capacity() const
0083 {
0084     return m_impl.capacity();
0085 }
0086 
0087 template<typename Value, typename HashFunctions, typename Traits>
0088 inline bool HashCountedSet<Value, HashFunctions, Traits>::isEmpty() const
0089 {
0090     return size() == 0;
0091 }
0092 
0093 template<typename Value, typename HashFunctions, typename Traits>
0094 inline typename HashCountedSet<Value, HashFunctions, Traits>::iterator HashCountedSet<Value, HashFunctions, Traits>::begin()
0095 {
0096     return m_impl.begin();
0097 }
0098 
0099 template<typename Value, typename HashFunctions, typename Traits>
0100 inline typename HashCountedSet<Value, HashFunctions, Traits>::iterator HashCountedSet<Value, HashFunctions, Traits>::end()
0101 {
0102     return m_impl.end();
0103 }
0104 
0105 template<typename Value, typename HashFunctions, typename Traits>
0106 inline typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator HashCountedSet<Value, HashFunctions, Traits>::begin() const
0107 {
0108     return m_impl.begin();
0109 }
0110 
0111 template<typename Value, typename HashFunctions, typename Traits>
0112 inline typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator HashCountedSet<Value, HashFunctions, Traits>::end() const
0113 {
0114     return m_impl.end();
0115 }
0116 
0117 template<typename Value, typename HashFunctions, typename Traits>
0118 inline typename HashCountedSet<Value, HashFunctions, Traits>::iterator HashCountedSet<Value, HashFunctions, Traits>::find(const ValueType &value)
0119 {
0120     return m_impl.find(value);
0121 }
0122 
0123 template<typename Value, typename HashFunctions, typename Traits>
0124 inline typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator HashCountedSet<Value, HashFunctions, Traits>::find(const ValueType &value) const
0125 {
0126     return m_impl.find(value);
0127 }
0128 
0129 template<typename Value, typename HashFunctions, typename Traits>
0130 inline bool HashCountedSet<Value, HashFunctions, Traits>::contains(const ValueType &value) const
0131 {
0132     return m_impl.contains(value);
0133 }
0134 
0135 template<typename Value, typename HashFunctions, typename Traits>
0136 inline unsigned HashCountedSet<Value, HashFunctions, Traits>::count(const ValueType &value) const
0137 {
0138     return m_impl.get(value);
0139 }
0140 
0141 template<typename Value, typename HashFunctions, typename Traits>
0142 inline std::pair<typename HashCountedSet<Value, HashFunctions, Traits>::iterator, bool> HashCountedSet<Value, HashFunctions, Traits>::add(const ValueType &value)
0143 {
0144     pair<iterator, bool> result = m_impl.add(value, 0);
0145     ++result.first->second;
0146     return result;
0147 }
0148 
0149 template<typename Value, typename HashFunctions, typename Traits>
0150 inline void HashCountedSet<Value, HashFunctions, Traits>::remove(const ValueType &value)
0151 {
0152     remove(find(value));
0153 }
0154 
0155 template<typename Value, typename HashFunctions, typename Traits>
0156 inline void HashCountedSet<Value, HashFunctions, Traits>::remove(iterator it)
0157 {
0158     if (it == end()) {
0159         return;
0160     }
0161 
0162     unsigned oldVal = it->second;
0163     ASSERT(oldVal != 0);
0164     unsigned newVal = oldVal - 1;
0165     if (newVal == 0) {
0166         m_impl.remove(it);
0167     } else {
0168         it->second = newVal;
0169     }
0170 }
0171 
0172 template<typename Value, typename HashFunctions, typename Traits>
0173 inline void HashCountedSet<Value, HashFunctions, Traits>::clear()
0174 {
0175     m_impl.clear();
0176 }
0177 
0178 template<typename Value, typename HashFunctions, typename Traits, typename VectorType>
0179 inline void copyToVector(const HashCountedSet<Value, HashFunctions, Traits> &collection, VectorType &vector)
0180 {
0181     typedef typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator iterator;
0182 
0183     vector.resize(collection.size());
0184 
0185     iterator it = collection.begin();
0186     iterator end = collection.end();
0187     for (unsigned i = 0; it != end; ++it, ++i) {
0188         vector[i] = *it;
0189     }
0190 }
0191 
0192 template<typename Value, typename HashFunctions, typename Traits>
0193 inline void copyToVector(const HashCountedSet<Value, HashFunctions, Traits> &collection, Vector<Value> &vector)
0194 {
0195     typedef typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator iterator;
0196 
0197     vector.resize(collection.size());
0198 
0199     iterator it = collection.begin();
0200     iterator end = collection.end();
0201     for (unsigned i = 0; it != end; ++it, ++i) {
0202         vector[i] = (*it).first;
0203     }
0204 }
0205 
0206 } // namespace khtml
0207 
0208 using WTF::HashCountedSet;
0209 
0210 #endif /* WTF_HashCountedSet_h */