#pragma once #include #include #include #include #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; using hash_t = std::size_t; static inline constexpr hash_t _hash32(uint32_t val) { return val * GOLDEN_RATIO_32; } static inline constexpr hash_t hash32(uint32_t val, std::size_t bits) { // higher bits are more random return _hash32(val) >> (8 * sizeof(hash_t) - bits); } static inline constexpr hash_t _hash64(uint64_t val) { return val * GOLDEN_RATIO_64; } static inline constexpr hash_t hash64(uint64_t val, std::size_t bits) { // higher bits are more random return _hash64(val) >> (8 * sizeof(hash_t) - bits); } template constexpr bool is_c_string_v = std::is_same_v, char*> || std::is_same_v, const char*>; template , bool> = true> inline hash_t hash(T val, std::size_t bits) { return hash64(static_cast(val), bits); } template && !is_c_string_v, bool> = true> inline hash_t hash(T val, std::size_t bits) { return hash(std::bit_cast(val), bits); } inline hash_t hash(const char* str, std::size_t bits) { constexpr uint32_t seed = 131; uint32_t hash = 0; while (*str) hash = hash * seed + (*str++); return hash64(hash, bits); }; template