summaryrefslogtreecommitdiffhomepage
path: root/compat/int-hash.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'compat/int-hash.cpp')
-rw-r--r--compat/int-hash.cpp78
1 files changed, 47 insertions, 31 deletions
diff --git a/compat/int-hash.cpp b/compat/int-hash.cpp
index 5847e284..aa5287f8 100644
--- a/compat/int-hash.cpp
+++ b/compat/int-hash.cpp
@@ -6,72 +6,88 @@ namespace floormat {
namespace {
+template<typename T> struct fnvhash_params;
+
+template<> struct fnvhash_params<uint32_t> { uint32_t a = 0x811c9dc5u, b = 0x01000193u; };
+template<> struct fnvhash_params<uint64_t> { uint64_t a = 0xcbf29ce484222325u, b = 0x100000001b3u; };
+
[[maybe_unused]]
-CORRADE_ALWAYS_INLINE uint32_t FNVHash_32(uint32_t x)
+CORRADE_ALWAYS_INLINE size_t fnvhash_uint_32(uint32_t x)
{
- const auto *str = (const char*)&x, *end = str + 4;
- uint32_t hash = 0x811c9dc5u;
-fm_UNROLL_4
- for (; str != end; ++str)
- {
- hash *= 0x01000193u;
- hash ^= (uint8_t)*str;
- }
+ constexpr auto params = fnvhash_params<std::common_type_t<size_t>>{};
+ constexpr auto a = params.a, b = params.b;
+ auto hash = a;
+ const auto* str = (const char*)&x;
+
+ hash *= b; hash ^= (uint8_t)*str++; // 0
+ hash *= b; hash ^= (uint8_t)*str++; // 1
+ hash *= b; hash ^= (uint8_t)*str++; // 2
+ hash *= b; hash ^= (uint8_t)*str++; // 3
+
return hash;
}
-CORRADE_ALWAYS_INLINE uint64_t FNVHash_64(uint64_t x)
+CORRADE_ALWAYS_INLINE size_t fnvhash_uint_64(uint64_t x)
{
- const auto *str = (const char*)&x, *end = str + 8;
- uint64_t hash = 0xcbf29ce484222325u;
-fm_UNROLL_8
- for (; str != end; ++str)
- {
- hash *= 0x100000001b3u;
- hash ^= (uint8_t)*str;
- }
+ constexpr auto params = fnvhash_params<std::common_type_t<size_t>>{};
+ constexpr auto a = params.a, b = params.b;
+ auto hash = a;
+ const auto* str = (const char*)&x;
+
+ hash *= b; hash ^= (uint8_t)*str++; // 0
+ hash *= b; hash ^= (uint8_t)*str++; // 1
+ hash *= b; hash ^= (uint8_t)*str++; // 2
+ hash *= b; hash ^= (uint8_t)*str++; // 3
+ hash *= b; hash ^= (uint8_t)*str++; // 4
+ hash *= b; hash ^= (uint8_t)*str++; // 5
+ hash *= b; hash ^= (uint8_t)*str++; // 6
+ hash *= b; hash ^= (uint8_t)*str++; // 7
+
return hash;
}
} // namespace
-uint64_t fnvhash_32(const void* buf, size_t size)
+uint32_t hash_32(const void* buf, size_t size) noexcept
{
+ constexpr auto params = fnvhash_params<std::common_type_t<uint32_t>>{};
+ constexpr auto a = params.a, b = params.b;
+ auto hash = a;
const auto *str = (const char*)buf, *const end = str + size;
- uint32_t hash = 0x811c9dc5u;
+
fm_UNROLL_4
for (; str != end; ++str)
{
- hash *= 0x01000193u;
+ hash *= b;
hash ^= (uint8_t)*str;
}
return hash;
}
-uint64_t fnvhash_64(const void* buf, size_t size)
+uint64_t hash_64(const void* buf, size_t size) noexcept
{
+ constexpr auto params = fnvhash_params<std::common_type_t<size_t>>{};
+ constexpr auto a = params.a, b = params.b;
+ auto hash = a;
const auto *str = (const char*)buf, *const end = str + size;
- uint64_t hash = 0xcbf29ce484222325u;
+
fm_UNROLL_8
for (; str != end; ++str)
{
- hash *= 0x100000001b3u;
+ hash *= b;
hash ^= (uint8_t)*str;
}
return hash;
}
-size_t int_hash(uint32_t x) noexcept
+size_t hash_int(uint32_t x) noexcept
{
- if constexpr(sizeof(size_t) == 4)
- return FNVHash_32(x);
- else
- return FNVHash_64(x);
+ return fnvhash_uint_32(x);
}
-size_t int_hash(uint64_t x) noexcept
+size_t hash_int(uint64_t x) noexcept
{
- return FNVHash_64(x);
+ return fnvhash_uint_64(x);
}
} // namespace floormat