![]() |
|
|
Generated: 8 Jan 2009 |
00001 // $Id: Hash.h,v 1.6 2007/05/23 18:05:15 marcocle Exp $ 00002 #ifndef GAUDIKERNEL_HASH_H 00003 #define GAUDIKERNEL_HASH_H 1 00004 00005 // Include files 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 // Needed to behave like VC++'s hash_compare 00025 enum { // parameters for hash table 00026 bucket_size = 4, // 0 < bucket_size 00027 min_buckets = 8}; // min_buckets = 2 ^^ N, 0 < N 00028 00029 inline bool operator() ( const T& key1, const T& key2 ) const { 00030 // test if key1 ordered before key2 00031 return comp(key1,key2); 00032 } 00033 00034 protected: 00035 std::less<T> comp; 00036 }; 00037 00038 //--- Partial specializations 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 // void* is a special case and needs a full specialization 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 } // namespace GaudiUtils 00112 00113 #endif // GAUDIKERNEL_HASH_H