00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00027 #ifndef SHHASHMAP_HPP
00028 #define SHHASHMAP_HPP
00029
00030 #ifdef WIN32
00031 #include <hash_map>
00032 #else
00033 #include <ext/hash_map>
00034 #endif
00035
00036 #include <cstddef>
00037 #include <iosfwd>
00038
00039
00040 namespace SH {
00041
00053 #ifdef WIN32
00054 #define SH_STD_HASH(T) stdext::hash_compare<T>
00055
00056 template<class Key, class Hash, class Less>
00057 class ShHashCompare {
00058 public:
00059 static const size_t bucket_size = 4;
00060 static const size_t min_buckets = 8;
00061 size_t operator( )(const Key& key) const { return m_hash(key); }
00062 bool operator( )(const Key& key1, const Key& key2) { return m_less(key1, key2); }
00063
00064 private:
00065 Hash m_hash;
00066 Less m_less;
00067 };
00068
00069 #else
00070 #define SH_STD_HASH(T) ShHashFunc<T>
00071 template<typename T>
00072 struct ShHashFunc {
00073 size_t operator()(const T& data) const
00074 { return size_t(data); }
00075 };
00076 #endif
00077
00078 template<class Key, class Data, class Hash=SH_STD_HASH(Key),
00079 class Less=std::less<Key>, class Equal=std::equal_to<Key> >
00080 class ShHashMap {
00081 #ifdef WIN32
00082 typedef stdext::hash_map<Key, Data, ShHashCompare<Key, Hash, Less> > map_type;
00083 #else
00084 typedef __gnu_cxx::hash_map<Key, Data, Hash, Equal> map_type;
00085 #endif
00086 public:
00087
00088 typedef Key key_type;
00089 typedef Data data_type;
00090 typedef std::pair<const key_type, data_type> value_type;
00091 typedef int size_type;
00092
00093 typedef typename map_type::iterator iterator;
00094 typedef typename map_type::const_iterator const_iterator;
00095
00101 iterator begin()
00102 { return m_map.begin(); }
00103
00104 const_iterator begin() const
00105 { return m_map.begin(); }
00106
00107 iterator end()
00108 { return m_map.end(); }
00109
00110 const_iterator end() const
00111 { return m_map.end(); }
00112
00113
00115 size_type size() const
00116 { return m_map.size(); }
00117
00118 size_type max_size() const
00119 { return m_map.max_size(); }
00120
00121 bool empty() const
00122 { return m_map.empty(); }
00123
00125 void clear()
00126 { m_map.clear(); }
00127
00128 std::pair<iterator, bool> insert(const value_type &value)
00129 { return m_map.insert(value); }
00130
00131 iterator insert(iterator hint, const value_type& value)
00132 { return m_map.insert(hint, value); }
00133
00134 template<class InputIterator>
00135 void insert(InputIterator first, InputIterator last)
00136 { m_map.insert(first, last); }
00137
00138 void erase(iterator pos)
00139 { m_map.erase(pos); }
00140
00141 void erase(iterator first, iterator last)
00142 { m_map.erase(first, last); }
00143
00144 size_type erase(const value_type& value)
00145 { return m_map.erase(value); }
00146
00148 iterator find(const key_type &key)
00149 { return m_map.find(key); }
00150
00151 const_iterator find(const key_type &key) const
00152 { return m_map.find(key); }
00153
00154 size_type count(const key_type &key) const
00155 { return m_map.count(key); }
00156
00157 std::pair<iterator, iterator> equal_range(const key_type &key)
00158 { return m_map.equal_range(key); }
00159
00160 std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const
00161 { return m_map.equal_range(key); }
00162
00164 void swap(ShHashMap &other)
00165 { m_map.swap(other.m_map); }
00166
00167 data_type& operator[](const key_type &key)
00168 { return m_map[key]; }
00169
00170 private:
00171 map_type m_map;
00172 };
00173
00175 template<class Key1, class Key2, class Hash1=SH_STD_HASH(Key1), class Hash2=SH_STD_HASH(Key2)>
00176 struct ShPairHash {
00177 typedef std::pair<Key1, Key2> key_type;
00178 Hash1 m_hash1;
00179 Hash2 m_hash2;
00180 size_t operator()(const key_type &key) const
00181 { return m_hash1(key.first) | ~m_hash2(key.second); }
00182 };
00183
00184 template<class Key1, class Key2, class Data, class Hash1=SH_STD_HASH(Key1), class Hash2=SH_STD_HASH(Key2)>
00185 class ShPairHashMap: public ShHashMap<std::pair<Key1, Key2>, Data, ShPairHash<Key1, Key2, Hash1, Hash2> > {
00186 typedef std::pair<Key1, Key2> key_type;
00187 public:
00188 Data& operator()(const Key1& key1, const Key2& key2)
00189 {
00190 return operator[](key_type(key1, key2));
00191 }
00192 };
00193
00194 template<class T1, class T2, class T3>
00195 struct ShTriple
00196 {
00197 T1 v1;
00198 T2 v2;
00199 T3 v3;
00200
00201 ShTriple(const T1 &v1, const T2 &v2, const T3 &v3)
00202 : v1(v1), v2(v2), v3(v3) {}
00203
00204 bool operator==(const ShTriple &b) const
00205 { return v1 == b.v1 && v2 == b.v2 && v3 == b.v3; }
00206
00207 bool operator<(const ShTriple &b) const
00208 {
00209 return v1 < b.v1 ||
00210 (v1 == b.v1 &&
00211 (v2 < b.v2 ||
00212 (v2 == b.v2 &&
00213 (v3 < b.v3))));
00214 }
00215 };
00216
00217 template<class Key1, class Key2, class Key3,
00218 class Hash1=SH_STD_HASH(Key1), class Hash2=SH_STD_HASH(Key2),
00219 class Hash3=SH_STD_HASH(Key3)>
00220 struct ShTripleHash {
00221 typedef ShTriple<Key1, Key2, Key3> key_type;
00222 Hash1 hash1;
00223 Hash2 hash2;
00224 Hash3 hash3;
00225 size_t operator()(const key_type &key) const
00226 { return hash1(key.v1) + hash2(key.v2) + hash3(key.v3); }
00227 };
00228
00229 template<class Key1, class Key2, class Key3, class Data,
00230 class Hash1=SH_STD_HASH(Key1), class Hash2=SH_STD_HASH(Key2),
00231 class Hash3=SH_STD_HASH(Key3)>
00232 class ShTripleHashMap: public ShHashMap<ShTriple<Key1, Key2, Key3>, Data,
00233 ShTripleHash<Key1, Key2, Key3, Hash1, Hash2, Hash3> > {
00234 public:
00235 typedef ShTriple<Key1, Key2, Key3> key_type;
00236 Data& operator()(const Key1 &key1, const Key2 &key2, const Key3 &key3)
00237 {
00238 return operator[](key_type(key1, key2, key3));
00239 }
00240 };
00241
00242 template<class T1, class T2, class T3, class T4>
00243 struct ShPairPair
00244 {
00245 T1 v1;
00246 T2 v2;
00247 T3 v3;
00248 T4 v4;
00249
00250 ShPairPair(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
00251 : v1(v1), v2(v2), v3(v3), v4(v4) {}
00252
00253 bool operator==(const ShPairPair &b) const
00254 { return v1 == b.v1 && v2 == b.v2 && v3 == b.v3 && v4 == b.v4; }
00255
00256 bool operator<(const ShPairPair &b) const
00257 {
00258 return v1 < b.v1 ||
00259 (v1 == b.v1 &&
00260 (v2 < b.v2 ||
00261 (v2 == b.v2 &&
00262 (v3 < b.v3 ||
00263 (v3 == b.v3 &&
00264 (v4 < b.v4))))));
00265 }
00266 };
00267
00268 template<class Key1, class Key2, class Key3, class Key4,
00269 class Hash1=SH_STD_HASH(Key1), class Hash2=SH_STD_HASH(Key2),
00270 class Hash3=SH_STD_HASH(Key3), class Hash4=SH_STD_HASH(Key4)>
00271 struct ShPairPairHash {
00272 typedef ShPairPair<Key1, Key2, Key3, Key4> key_type;
00273 Hash1 hash1;
00274 Hash2 hash2;
00275 Hash3 hash3;
00276 Hash4 hash4;
00277 size_t operator()(const key_type &key) const
00278 { return hash1(key.v1) + hash2(key.v2) + hash3(key.v3) + hash4(key.v4); }
00279 };
00280
00281 template<class Key1, class Key2, class Key3, class Key4, class Data,
00282 class Hash1=SH_STD_HASH(Key1), class Hash2=SH_STD_HASH(Key2),
00283 class Hash3=SH_STD_HASH(Key3), class Hash4=SH_STD_HASH(Key4)>
00284 class ShPairPairHashMap: public ShHashMap<ShPairPair<Key1, Key2, Key3, Key4>, Data,
00285 ShPairPairHash<Key1, Key2, Key3, Key4, Hash1, Hash2, Hash3, Hash4> > {
00286 public:
00287 typedef ShPairPair<Key1, Key2, Key3, Key4> key_type;
00288 Data& operator()(const Key1 &key1, const Key2 &key2, const Key3 &key3, const Key4 &key4)
00289 {
00290 return operator[](key_type(key1, key2, key3, key4));
00291 }
00292 };
00293
00294 #undef SH_STD_HASH
00295
00296 }
00297
00298 #endif