00001
00002
00003
00004
00005
00006
00007 #ifndef BALL_DATATYPE_HASHMAP_H
00008 #define BALL_DATATYPE_HASHMAP_H
00009
00010 #ifndef BALL_COMMON_H
00011 # include <BALL/common.h>
00012 #endif
00013
00014 #ifndef BALL_COMMON_HASH_H
00015 # include <BALL/COMMON/hash.h>
00016 #endif
00017
00018 #ifndef BALL_DATATYPE_TRIPLE_H
00019 # include <BALL/DATATYPE/triple.h>
00020 #endif
00021
00022 #ifndef BALL_DATATYPE_QUADRUPLE_H
00023 # include <BALL/DATATYPE/quadruple.h>
00024 #endif
00025
00026 #include <utility>
00027 #include <algorithm>
00028
00029 #if defined(BALL_HAS_UNORDERED_MAP)
00030
00031 #if defined(BALL_PLATFORM_WINDOWS)
00032 # include <boost/unordered_map.hpp>
00033 #else
00034 # include <tr1/unordered_map>
00035 #endif
00036
00037 #elif defined(BALL_EXT_INCLUDE_PREFIX)
00038 # include <ext/hash_map>
00039 # include <ext/hash_fun.h>
00040 #else
00041 # include <hash_map>
00042 # include <hash_fun.h>
00043 #endif
00044
00045 #ifdef BALL_HAS_UNORDERED_MAP
00046
00047 namespace std
00048 {
00049 namespace tr1
00050 {
00051
00052
00053 template<typename T>
00054 void hash_combine_ala_boost(size_t & seed, T const & v)
00055 {
00056 hash<T> h;
00057 seed ^= h(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
00058 }
00059
00060 template<class A, class B>
00061 struct hash<pair<A, B> > : public std::unary_function<pair<A,B>, size_t>
00062 {
00063 inline size_t
00064 operator()(pair<A, B> p) const
00065 {
00066 size_t seed = 0;
00067 hash_combine_ala_boost(seed, p.first);
00068 hash_combine_ala_boost(seed, p.second);
00069
00070 return seed;
00071 }
00072 };
00073
00074 template <class A, class B, class C>
00075 struct hash< ::BALL::Triple<A, B, C> > : public std::unary_function< ::BALL::Triple<A, B, C>, size_t>
00076 {
00077 inline size_t
00078 operator()(::BALL::Triple<A, B, C> t) const
00079 {
00080 size_t seed = 0;
00081 hash_combine_ala_boost(seed, t.first);
00082 hash_combine_ala_boost(seed, t.second);
00083 hash_combine_ala_boost(seed, t.third);
00084
00085 return seed;
00086 }
00087 };
00088
00089 template <class A, class B, class C, class D>
00090 struct hash< const ::BALL::Quadruple<A, B, C, D> > : public std::unary_function< const ::BALL::Quadruple<A, B, C, D>, size_t>
00091 {
00092 inline size_t
00093 operator()(const ::BALL::Quadruple<A, B, C, D> q) const
00094 {
00095 size_t seed = 0;
00096 hash_combine_ala_boost(seed, q.first);
00097 hash_combine_ala_boost(seed, q.second);
00098 hash_combine_ala_boost(seed, q.third);
00099 hash_combine_ala_boost(seed, q.fourth);
00100
00101 return seed;
00102 }
00103 };
00104
00105 #ifndef BALL_COMPILER_MSVC
00106 template<>
00107 struct hash<const ::BALL::String&> : public std::unary_function<const ::BALL::String &, size_t>
00108 {
00109 inline size_t
00110 operator()(const ::BALL::String& s) const
00111 {
00112 hash<const string&> h;
00113 return h(s);
00114 }
00115 };
00116 #endif
00117
00118 template<>
00119 struct hash< ::BALL::String > : public std::unary_function< ::BALL::String, size_t >
00120 {
00121 inline size_t
00122 operator()( ::BALL::String s) const
00123 {
00124 hash<string> h;
00125 return h(s);
00126 }
00127 };
00128 }
00129 }
00130 #endif
00131
00132 #ifdef BALL_HAS_HASH_MAP
00133 namespace BALL_MAP_NAMESPACE
00134 {
00135 template<class T>
00136 struct hash<T*>
00137 {
00138 size_t operator()(const T* x) const { return (size_t)x; }
00139 };
00140
00141 template<>
00142 struct hash<BALL::String>
00143 {
00144 size_t operator () (const BALL::String& s) const {return __stl_hash_string(s.c_str());}
00145 };
00146
00147 #ifdef BALL_NEEDS_LONGSIZE_HASH
00148 template<>
00149 struct hash<BALL::LongSize>
00150 {
00151 size_t operator()(BALL::LongSize x) const { return (size_t)x; }
00152 };
00153 #endif
00154 }
00155 #endif // BALL_HAS_HASH_MAP
00156
00157 namespace BALL
00158 {
00164 template <class Key, class T>
00165 class HashMap
00166 : public BALL_MAP_NAME
00167 {
00168 public:
00169
00175 class IllegalKey
00176 : public Exception::GeneralException
00177 {
00178 public:
00179 IllegalKey(const char* file, int line)
00180 : Exception::GeneralException(file, line)
00181 {
00182 }
00183 };
00184
00186
00187 typedef BALL_MAP_NAME Base;
00188 typedef typename Base::value_type ValueType;
00189 typedef Key KeyType;
00190 typedef typename Base::value_type* PointerType;
00191 typedef typename Base::iterator Iterator;
00192 typedef typename Base::const_iterator ConstIterator;
00194
00196 inline bool has(const Key& key) const
00197 {
00198 return Base::find(key)!=Base::end();
00199 }
00200
00206 const T& operator [] (const Key& key) const;
00207
00209 T& operator [] (const Key& key);
00210
00212 bool operator == (const HashMap<Key, T>& rhs) const;
00213
00214 Size size() const { return BALL_MAP_NAME::size(); }
00215 };
00216
00217
00218
00219
00220
00221 template <class Key, class T>
00222 const T& HashMap<Key, T>::operator [] (const Key& key) const
00223 {
00224 ConstIterator it = find(key);
00225 if (it == Base::end())
00226 {
00227 throw IllegalKey(__FILE__, __LINE__);
00228 }
00229 else
00230 {
00231 return it->second;
00232 }
00233 }
00234
00235
00236 template <class Key, class T>
00237 bool HashMap<Key, T>::operator == (const HashMap<Key, T>& rhs) const
00238 {
00239
00240 if (size() != rhs.size())
00241 {
00242 return false;
00243 }
00244
00245
00246
00247
00248 ConstIterator it(BALL_MAP_NAME::begin());
00249 for (; it != BALL_MAP_NAME::end(); ++it)
00250 {
00251 if (!rhs.has(it->first)) return false;
00252 }
00253 return true;
00254 }
00255
00256 template <class Key, class T>
00257 T& HashMap<Key, T>::operator [] (const Key& key)
00258
00259 {
00260 Iterator it = find(key);
00261 if (it == Base::end())
00262 {
00263 it = insert(ValueType(key, T())).first;
00264 }
00265 return it->second;
00266 }
00267
00268 }
00269
00270 #endif // BALL_DATATYPE_HASHMAP_H