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 #if defined(_MSC_VER)
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 #if defined(_MSC_VER)
00075 typedef stdext::hash_map<Key, Data, ShHashCompare<Key, Hash, Less> > map_type;
00076 #elif defined(__SGI_STL_PORT)
00077 typedef std::hash_map<Key, Data, Hash, Equal> map_type;
00078 #else
00079 typedef __gnu_cxx::hash_map<Key, Data, Hash, Equal> map_type;
00080 #endif
00081 public:
00082
00083 typedef Key key_type;
00084 typedef Data data_type;
00085 typedef std::pair<const key_type, data_type> value_type;
00086 typedef int size_type;
00087
00088 typedef typename map_type::iterator iterator;
00089 typedef typename map_type::const_iterator const_iterator;
00090
00096 iterator begin()
00097 { return m_map.begin(); }
00098
00099 const_iterator begin() const
00100 { return m_map.begin(); }
00101
00102 iterator end()
00103 { return m_map.end(); }
00104
00105 const_iterator end() const
00106 { return m_map.end(); }
00107
00108
00110 size_type size() const
00111 { return m_map.size(); }
00112
00113 size_type max_size() const
00114 { return m_map.max_size(); }
00115
00116 bool empty() const
00117 { return m_map.empty(); }
00118
00120 void clear()
00121 { m_map.clear(); }
00122
00123 std::pair<iterator, bool> insert(const value_type &value)
00124 { return m_map.insert(value); }
00125
00126 iterator insert(iterator hint, const value_type& value)
00127 { return m_map.insert(hint, value); }
00128
00129 template<class InputIterator>
00130 void insert(InputIterator first, InputIterator last)
00131 { m_map.insert(first, last); }
00132
00133 void erase(iterator pos)
00134 { m_map.erase(pos); }
00135
00136 void erase(iterator first, iterator last)
00137 { m_map.erase(first, last); }
00138
00139 size_type erase(const value_type& value)
00140 { return m_map.erase(value); }
00141
00143 iterator find(const key_type &key)
00144 { return m_map.find(key); }
00145
00146 const_iterator find(const key_type &key) const
00147 { return m_map.find(key); }
00148
00149 size_type count(const key_type &key) const
00150 { return m_map.count(key); }
00151
00152 std::pair<iterator, iterator> equal_range(const key_type &key)
00153 { return m_map.equal_range(key); }
00154
00155 std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const
00156 { return m_map.equal_range(key); }
00157
00159 void swap(ShHashMap &other)
00160 { m_map.swap(other.m_map); }
00161
00162 data_type& operator[](const key_type &key)
00163 { return m_map[key]; }
00164
00165 private:
00166 map_type m_map;
00167 };
00168
00170 template<class Key1, class Key2, class Hash1=SH_STD_HASH(Key1), class Hash2=SH_STD_HASH(Key2)>
00171 struct ShPairHash {
00172 typedef std::pair<Key1, Key2> key_type;
00173 Hash1 m_hash1;
00174 Hash2 m_hash2;
00175 size_t operator()(const key_type &key) const
00176 { return m_hash1(key.first) | ~m_hash2(key.second); }
00177 };
00178
00179 template<class Key1, class Key2, class Data, class Hash1=SH_STD_HASH(Key1), class Hash2=SH_STD_HASH(Key2)>
00180 class ShPairHashMap: public ShHashMap<std::pair<Key1, Key2>, Data, ShPairHash<Key1, Key2, Hash1, Hash2> > {
00181 typedef std::pair<Key1, Key2> key_type;
00182 public:
00183 Data& operator()(const Key1& key1, const Key2& key2)
00184 {
00185 return operator[](key_type(key1, key2));
00186 }
00187 };
00188
00189 template<class T1, class T2, class T3>
00190 struct ShTriple
00191 {
00192 T1 v1;
00193 T2 v2;
00194 T3 v3;
00195
00196 ShTriple(const T1 &v1, const T2 &v2, const T3 &v3)
00197 : v1(v1), v2(v2), v3(v3) {}
00198
00199 bool operator==(const ShTriple &b) const
00200 { return v1 == b.v1 && v2 == b.v2 && v3 == b.v3; }
00201
00202 bool operator<(const ShTriple &b) const
00203 {
00204 return v1 < b.v1 ||
00205 (v1 == b.v1 &&
00206 (v2 < b.v2 ||
00207 (v2 == b.v2 &&
00208 (v3 < b.v3))));
00209 }
00210 };
00211
00212 template<class Key1, class Key2, class Key3,
00213 class Hash1=SH_STD_HASH(Key1), class Hash2=SH_STD_HASH(Key2),
00214 class Hash3=SH_STD_HASH(Key3)>
00215 struct ShTripleHash {
00216 typedef ShTriple<Key1, Key2, Key3> key_type;
00217 Hash1 hash1;
00218 Hash2 hash2;
00219 Hash3 hash3;
00220 size_t operator()(const key_type &key) const
00221 { return hash1(key.v1) + hash2(key.v2) + hash3(key.v3); }
00222 };
00223
00224 template<class Key1, class Key2, class Key3, class Data,
00225 class Hash1=SH_STD_HASH(Key1), class Hash2=SH_STD_HASH(Key2),
00226 class Hash3=SH_STD_HASH(Key3)>
00227 class ShTripleHashMap: public ShHashMap<ShTriple<Key1, Key2, Key3>, Data,
00228 ShTripleHash<Key1, Key2, Key3, Hash1, Hash2, Hash3> > {
00229 public:
00230 typedef ShTriple<Key1, Key2, Key3> key_type;
00231 Data& operator()(const Key1 &key1, const Key2 &key2, const Key3 &key3)
00232 {
00233 return operator[](key_type(key1, key2, key3));
00234 }
00235 };
00236
00237 template<class T1, class T2, class T3, class T4>
00238 struct ShPairPair
00239 {
00240 T1 v1;
00241 T2 v2;
00242 T3 v3;
00243 T4 v4;
00244
00245 ShPairPair(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
00246 : v1(v1), v2(v2), v3(v3), v4(v4) {}
00247
00248 bool operator==(const ShPairPair &b) const
00249 { return v1 == b.v1 && v2 == b.v2 && v3 == b.v3 && v4 == b.v4; }
00250
00251 bool operator<(const ShPairPair &b) const
00252 {
00253 return v1 < b.v1 ||
00254 (v1 == b.v1 &&
00255 (v2 < b.v2 ||
00256 (v2 == b.v2 &&
00257 (v3 < b.v3 ||
00258 (v3 == b.v3 &&
00259 (v4 < b.v4))))));
00260 }
00261 };
00262
00263 template<class Key1, class Key2, class Key3, class Key4,
00264 class Hash1=SH_STD_HASH(Key1), class Hash2=SH_STD_HASH(Key2),
00265 class Hash3=SH_STD_HASH(Key3), class Hash4=SH_STD_HASH(Key4)>
00266 struct ShPairPairHash {
00267 typedef ShPairPair<Key1, Key2, Key3, Key4> key_type;
00268 Hash1 hash1;
00269 Hash2 hash2;
00270 Hash3 hash3;
00271 Hash4 hash4;
00272 size_t operator()(const key_type &key) const
00273 { return hash1(key.v1) + hash2(key.v2) + hash3(key.v3) + hash4(key.v4); }
00274 };
00275
00276 template<class Key1, class Key2, class Key3, class Key4, class Data,
00277 class Hash1=SH_STD_HASH(Key1), class Hash2=SH_STD_HASH(Key2),
00278 class Hash3=SH_STD_HASH(Key3), class Hash4=SH_STD_HASH(Key4)>
00279 class ShPairPairHashMap: public ShHashMap<ShPairPair<Key1, Key2, Key3, Key4>, Data,
00280 ShPairPairHash<Key1, Key2, Key3, Key4, Hash1, Hash2, Hash3, Hash4> > {
00281 public:
00282 typedef ShPairPair<Key1, Key2, Key3, Key4> key_type;
00283 Data& operator()(const Key1 &key1, const Key2 &key2, const Key3 &key3, const Key4 &key4)
00284 {
00285 return operator[](key_type(key1, key2, key3, key4));
00286 }
00287 };
00288
00289 #undef SH_STD_HASH
00290
00291 }
00292
00293 #endif