00001
00002 #ifndef GAUDIKERNEL_HASH_H
00003 #define GAUDIKERNEL_HASH_H 1
00004
00005
00006 #include <string>
00007 #include <functional>
00008
00009 namespace GaudiUtils {
00010
00020 template <class T>
00021 struct Hash: public std::unary_function<T,size_t> {
00022 inline size_t operator() ( const T& key ) const;
00023
00024
00025 enum {
00026 bucket_size = 4,
00027 min_buckets = 8};
00028
00029 inline bool operator() ( const T& key1, const T& key2 ) const {
00030
00031 return comp(key1,key2);
00032 }
00033
00034 protected:
00035 std::less<T> comp;
00036 };
00037
00038
00039 template <class T>
00040 struct Hash<T*>: public std::unary_function<T*,size_t>, private Hash<T> {
00041 inline size_t operator() ( const T* key ) const {
00042 return ( NULL == key ) ? (size_t)0 : Hash<T>::operator()(*key);
00043 }
00044 inline bool operator() ( const T* key1, const T* key2 ) const {
00045 return Hash<T>::operator() (*key1,*key2);
00046 }
00047 };
00048
00049 template<class T>
00050 struct Hash<const T*> : public Hash<T*>{};
00051 template<class T>
00052 struct Hash<T&> : public Hash<T>{};
00053 template<class T>
00054 struct Hash<const T&> : public Hash<T>{};
00055
00056
00057 template <class T>
00058 size_t Hash<T>::operator() ( const T& key ) const {
00059 size_t res = 0 ;
00060 size_t len = sizeof(T) ;
00061 const char* p = reinterpret_cast<const char*>( &key );
00062 while( len-- ) { res = ( res << 1 ) ^ *p; ++p; }
00063 return res;
00064 }
00065
00066 template <>
00067 inline size_t Hash<int>::operator() ( const int& key ) const { return (size_t)key; }
00068
00069 template <>
00070 inline size_t Hash<unsigned int>::operator() ( const unsigned int& key ) const { return (size_t)key; }
00071
00072 template <>
00073 inline size_t Hash<long>::operator() ( const long& key ) const { return (size_t)key; }
00074
00075 template <>
00076 inline size_t Hash<unsigned long>::operator() ( const unsigned long& key ) const { return (size_t)key; }
00077
00078 template <>
00079 inline size_t Hash<long long>::operator() ( const long long& key ) const { return (size_t)key; }
00080
00081 template <>
00082 inline size_t Hash<unsigned long long>::operator() ( const unsigned long long& key ) const { return (size_t)key; }
00083
00084
00085 template <>
00086 struct Hash<void *>: public std::unary_function<void*,size_t> {
00087 inline size_t operator() ( const void* key ) const {
00088 return reinterpret_cast<size_t>(key);
00089 }
00090 inline bool operator() ( const void* key1, const void* key2 ) const {
00091 return reinterpret_cast<size_t>(key1) < reinterpret_cast<size_t>(key2);
00092 }
00093 };
00094
00095 template <>
00096 inline size_t Hash<std::string>::operator() ( const std::string& key ) const {
00097 size_t res = 0 ;
00098 std::string::const_iterator e = key.end();
00099 std::string::const_iterator p = key.begin();
00100 while( p != e ) { res = ( res << 1 ) ^ *p; ++p; }
00101 return res;
00102 }
00103
00104 template <>
00105 inline size_t Hash<char *>::operator() ( const char *key ) const {
00106 size_t res = 0 ;
00107 if ( 0 == key ) { return 0; }
00108 while ( *key ) { res = ( res << 1 ) ^ *key; ++key; }
00109 return res;
00110 }
00111 }
00112
00113 #endif // GAUDIKERNEL_HASH_H