| # Gaudi Framework, version v20r3
Generated: 24 Nov 2008

# Hash.h

Go to the documentation of this file.

    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