#pragma once #include #include #include #include #include #include #include namespace types { // taken from linux constexpr uint32_t GOLDEN_RATIO_32 = 0x61C88647; // constexpr uint64_t GOLDEN_RATIO_64 = 0x61C8864680B583EBull; static constexpr uint32_t _hash32(uint32_t val) { return val * GOLDEN_RATIO_32; } static constexpr uint32_t hash32(uint32_t val, uint32_t bits) { // higher bits are more random return _hash32(val) >> (32 - bits); } template struct linux_hasher { static constexpr uint32_t hash(const T& val, uint32_t bits) { return hash32(val, bits); } }; template struct linux_hasher { static constexpr uint32_t hash(T* val, uint32_t bits) { return hash32(reinterpret_cast(val), bits); } }; template struct string_hasher { static constexpr uint32_t hash(T, uint32_t) { static_assert(types::template_false_type::value, "string hasher does not support this type"); return (uint32_t)0; } }; template <> struct string_hasher { static constexpr uint32_t hash(const char* str, uint32_t bits) { constexpr uint32_t seed = 131; uint32_t hash = 0; while (*str) hash = hash * seed + (*str++); return hash32(hash, bits); } }; template