even more SFINAE abuse shoving the hasher into unordered_map (and somewhere along the line scene loading is quicker because of things)

This commit is contained in:
ecker 2026-06-10 21:15:45 -05:00
parent 334b897e19
commit 590eee0684
2 changed files with 36 additions and 2 deletions

View File

@ -2,6 +2,16 @@
#include <uf/utils/memory/vector.h>
namespace uf {
namespace traits {
template <typename T, typename = void>
struct has_hash_method : std::false_type {};
template <typename T>
struct has_hash_method<T, std::void_t<decltype(std::declval<T>().hash())>> : std::true_type {};
}
}
namespace uf {
namespace algo {
template<size_t> struct FNV1a;
@ -18,6 +28,11 @@ namespace uf {
using FNV = FNV1a<sizeof(size_t)>;
template<typename T, std::enable_if_t<uf::traits::has_hash_method<T>::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<size_t>(static_cast<uint8_t>(*str))) * FNV::prime) : hash;
}
@ -30,7 +45,13 @@ namespace uf {
return fnv1a(uf::stl::string_view(str), hash);
}
template<typename T, std::enable_if_t<std::is_trivially_copyable_v<T> && !std::is_array_v<T> && !std::is_pointer_v<T>, int> = 0>
template<typename T, std::enable_if_t<
std::is_trivially_copyable_v<T> &&
!std::is_array_v<T> &&
!std::is_pointer_v<T> &&
!uf::traits::has_hash_method<T>::value,
int
> = 0>
inline size_t fnv1a(const T& v, size_t hash = FNV::basis) {
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&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<typename T, std::enable_if_t<std::is_pointer_v<T>, int> = 0>
inline size_t fnv1a( const T v, size_t hash = FNV::basis ) {
return fnv1a(reinterpret_cast<size_t>(v), hash);
}
template<typename T>
inline size_t fnv1a(const uf::stl::vector<T>& values, size_t hash = FNV::basis) {
if constexpr (std::is_same_v<T, bool>) {
@ -63,6 +89,13 @@ namespace uf {
}
return hash;
}
struct hasher {
using is_transparent = void;
template<typename T> inline size_t operator()( const T& val ) const noexcept {
return uf::algo::fnv1a(val);
}
};
}

View File

@ -5,13 +5,14 @@
#include <unordered_map>
#include "vector.h"
#include <uf/utils/math/hash.h>
namespace uf {
namespace stl {
template<
class Key,
class T,
class Hash = std::hash<Key>,
class Hash = uf::algo::hasher,
class KeyEqual = std::equal_to<Key>,
#if UF_MEMORYPOOL_USE_STL_ALLOCATOR
class Allocator = std::allocator<std::pair<const Key, T>>