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