#ifdef USE_API_MAXON #include "../../c4d_misc.h" #elif !defined(HASHCODE_H__) #define HASHCODE_H__ #include "../general.h" namespace maxon { /// @addtogroup STRUCTURES /// @{ /// This class implements default hash functions. They are used by HashMap. /// The class defines hash functions for the following cases: /// - integral values /// - pointers (where different pointers are assumed to be different keys, so only the address is considered, not the content) /// - objects whose type has a GetHashCode member function and which can be compared with == /// /// For any other case you have to define your own hash function, see CStringHash for the case of C-strings. class DefaultHash { public: /* from Sun's implementation of java.util.HashMap: Applies a supplemental hash function to a given hashCode, which defends against poor quality hash functions. This is critical because HashMap uses power-of-two length hash tables, that otherwise encounter collisions for hashCodes that do not differ in lower bits. Note: Null keys always map to hash 0, thus index 0. */ #ifdef __C4D_64BIT static UInt GetHashCode(UInt32 i) { UInt h = i; h ^= (h >> 20) ^ (h >> 12); return h ^ (h >> 7) ^ (h >> 4); } static UInt GetHashCode(UInt64 h) { h ^= h >> 32; h ^= (h >> 20) ^ (h >> 12); return h ^ (h >> 7) ^ (h >> 4); } #else static UInt GetHashCode(UInt32 h) { h ^= (h >> 20) ^ (h >> 12); return h ^ (h >> 7) ^ (h >> 4); } static UInt GetHashCode(UInt64 h) { return GetHashCode((UInt32) (h ^ (h >> 32))); } #endif static UInt GetHashCode(Int32 h) { return GetHashCode((UInt32) h); } static UInt GetHashCode(Int64 h) { return GetHashCode((UInt64) h); } template static UInt GetHashCode(const T* key) { return GetHashCode((UInt) key); } template static UInt GetHashCode(T* key) { return GetHashCode((UInt) key); } template static UInt GetHashCode(const K& key) { return key.GetHashCode(); } template static Bool IsEqual(const K1& a, const K2& b) { return a == b; } }; /// This class can be used as template argument for a HashMap if the HashMap shall use C-string keys. class CStringHash { public: static UInt GetHashCode(const Char* key) { UInt hash = 0; if (key) { while (*key) { hash = 31 * hash + *key; ++key; } } return hash; } static Bool IsEqual(const Char* a, const Char* b) { return (a == b) || (a && b && (strcmp(a, b) == 0)); } }; /// @} } // C4D_MISC_END #endif