From 590eee0684007894d96ec95d2cee72ad5950c310 Mon Sep 17 00:00:00 2001 From: ecker Date: Wed, 10 Jun 2026 21:15:45 -0500 Subject: [PATCH] even more SFINAE abuse shoving the hasher into unordered_map (and somewhere along the line scene loading is quicker because of things) --- engine/inc/uf/utils/math/hash.h | 35 +++++++++++++++++++++- engine/inc/uf/utils/memory/unordered_map.h | 3 +- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/engine/inc/uf/utils/math/hash.h b/engine/inc/uf/utils/math/hash.h index 5033b3e4..72147642 100644 --- a/engine/inc/uf/utils/math/hash.h +++ b/engine/inc/uf/utils/math/hash.h @@ -2,6 +2,16 @@ #include +namespace uf { + namespace traits { + template + struct has_hash_method : std::false_type {}; + + template + struct has_hash_method().hash())>> : std::true_type {}; + } +} + namespace uf { namespace algo { template struct FNV1a; @@ -18,6 +28,11 @@ namespace uf { using FNV = FNV1a; + template::value, int> = 0> + inline size_t fnv1a(const T& v, size_t hash = FNV::basis) { + return (hash ^ v.hash()) * FNV::prime; + } + constexpr size_t fnv1a(const char* str, size_t hash = FNV::basis) { return *str ? fnv1a(str + 1, (hash ^ static_cast(static_cast(*str))) * FNV::prime) : hash; } @@ -30,7 +45,13 @@ namespace uf { return fnv1a(uf::stl::string_view(str), hash); } - template && !std::is_array_v && !std::is_pointer_v, int> = 0> + template && + !std::is_array_v && + !std::is_pointer_v && + !uf::traits::has_hash_method::value, + int + > = 0> inline size_t fnv1a(const T& v, size_t hash = FNV::basis) { const uint8_t* bytes = reinterpret_cast(&v); for (size_t i = 0; i < sizeof(T); ++i) { @@ -44,6 +65,11 @@ namespace uf { return fnv1a(uf::stl::string_view(str, N - 1), hash); } + template, int> = 0> + inline size_t fnv1a( const T v, size_t hash = FNV::basis ) { + return fnv1a(reinterpret_cast(v), hash); + } + template inline size_t fnv1a(const uf::stl::vector& values, size_t hash = FNV::basis) { if constexpr (std::is_same_v) { @@ -63,6 +89,13 @@ namespace uf { } return hash; } + + struct hasher { + using is_transparent = void; + template inline size_t operator()( const T& val ) const noexcept { + return uf::algo::fnv1a(val); + } + }; } diff --git a/engine/inc/uf/utils/memory/unordered_map.h b/engine/inc/uf/utils/memory/unordered_map.h index b0245492..61727cd5 100644 --- a/engine/inc/uf/utils/memory/unordered_map.h +++ b/engine/inc/uf/utils/memory/unordered_map.h @@ -5,13 +5,14 @@ #include #include "vector.h" +#include namespace uf { namespace stl { template< class Key, class T, - class Hash = std::hash, + class Hash = uf::algo::hasher, class KeyEqual = std::equal_to, #if UF_MEMORYPOOL_USE_STL_ALLOCATOR class Allocator = std::allocator>