// // Lol Engine // // Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net> // This program is free software; you can redistribute it and/or // modify it under the terms of the Do What The Fuck You Want To // Public License, Version 2, as published by Sam Hocevar. See // http://www.wtfpl.net/ for more details. // #include <lol/engine-internal.h> namespace lol { /* * hash implementations */ static class HashData { public: HashData() { /* Initialise CRC32 table */ for (int i = 0; i < 256; i++) { uint32_t tmp = i; for (int j = 8; j--; ) tmp = (tmp >> 1) ^ ((tmp & 1) ? 0xedb88320 : 0); crc32_table[i] = tmp; } } uint32_t crc32_table[256]; } const data; /* * Helper hash functions */ static inline uint32_t Hash8(uint8_t x) { uint32_t ret = 0xffffffffu; ret = data.crc32_table[(uint8_t)(ret ^ x)] ^ (ret >> 8); return ret ^ 0xffffffffu; } static inline uint32_t Hash16(uint16_t x) { uint32_t ret = 0xffffffffu; ret = data.crc32_table[(uint8_t)(ret ^ x)] ^ (ret >> 8); ret = data.crc32_table[(uint8_t)(ret ^ (x >> 8))] ^ (ret >> 8); return ret ^ 0xffffffffu; } static inline uint32_t Hash32(uint32_t x) { uint32_t ret = 0xffffffffu; ret = data.crc32_table[(uint8_t)(ret ^ x)] ^ (ret >> 8); ret = data.crc32_table[(uint8_t)(ret ^ (x >> 8))] ^ (ret >> 8); ret = data.crc32_table[(uint8_t)(ret ^ (x >> 16))] ^ (ret >> 8); ret = data.crc32_table[(uint8_t)(ret ^ (x >> 24))] ^ (ret >> 8); return ret ^ 0xffffffffu; } static inline uint32_t Hash64(uint64_t x) { uint32_t ret = 0xffffffffu; ret = data.crc32_table[(uint8_t)(ret ^ x)] ^ (ret >> 8); ret = data.crc32_table[(uint8_t)(ret ^ (x >> 8))] ^ (ret >> 8); ret = data.crc32_table[(uint8_t)(ret ^ (x >> 16))] ^ (ret >> 8); ret = data.crc32_table[(uint8_t)(ret ^ (x >> 24))] ^ (ret >> 8); ret = data.crc32_table[(uint8_t)(ret ^ (x >> 32))] ^ (ret >> 8); ret = data.crc32_table[(uint8_t)(ret ^ (x >> 40))] ^ (ret >> 8); ret = data.crc32_table[(uint8_t)(ret ^ (x >> 48))] ^ (ret >> 8); ret = data.crc32_table[(uint8_t)(ret ^ (x >> 56))] ^ (ret >> 8); return ret ^ 0xffffffffu; } /* * Integer hash functions */ uint32_t hash<int8_t>::operator ()(int8_t x) const { return Hash8((uint8_t)x); } uint32_t hash<uint8_t>::operator ()(uint8_t x) const { return Hash8(x); } uint32_t hash<int16_t>::operator ()(int16_t x) const { return Hash16((uint16_t)x); } uint32_t hash<uint16_t>::operator ()(uint16_t x) const { return Hash16(x); } uint32_t hash<int32_t>::operator ()(int32_t x) const { return Hash32((uint32_t)x); } uint32_t hash<uint32_t>::operator ()(uint32_t x) const { return Hash32(x); } uint32_t hash<int64_t>::operator ()(int64_t x) const { return Hash64((uint64_t)x); } uint32_t hash<uint64_t>::operator ()(uint64_t x) const { return Hash64(x); } /* * Floating-point hash functions */ uint32_t hash<half>::operator ()(half f) const { return Hash16(f.bits); } uint32_t hash<float>::operator ()(float f) const { union { float tmp; uint32_t x; } u = { f }; return Hash32(u.x); } uint32_t hash<double>::operator ()(double f) const { union { double tmp; uint64_t x; } u = { f }; return Hash64(u.x); } /* * String and array hash functions */ static uint32_t HashCharString(char const *s) { uint32_t ret = 0xffffffffu, ch; while ((ch = (uint8_t)*s++)) ret = data.crc32_table[(uint8_t)(ret ^ ch)] ^ (ret >> 8); return ret ^ 0xffffffffu; } uint32_t hash<char const *>::operator ()(char const *s) const { return HashCharString(s); } uint32_t hash<std::string>::operator ()(std::string const &s) const { return HashCharString(&s[0]); } uint32_t hash<char const *>::operator ()(String const &s) const { return HashCharString(&s[0]); } uint32_t hash<String>::operator ()(String const &s) const { return HashCharString(&s[0]); } uint32_t hash<String>::operator ()(char const *s) const { return HashCharString(s); } } /* namespace lol */