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