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:
parent
334b897e19
commit
590eee0684
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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>>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user