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>
|
#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 uf {
|
||||||
namespace algo {
|
namespace algo {
|
||||||
template<size_t> struct FNV1a;
|
template<size_t> struct FNV1a;
|
||||||
@ -18,6 +28,11 @@ namespace uf {
|
|||||||
|
|
||||||
using FNV = FNV1a<sizeof(size_t)>;
|
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) {
|
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;
|
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);
|
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) {
|
inline size_t fnv1a(const T& v, size_t hash = FNV::basis) {
|
||||||
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&v);
|
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&v);
|
||||||
for (size_t i = 0; i < sizeof(T); ++i) {
|
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);
|
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>
|
template<typename T>
|
||||||
inline size_t fnv1a(const uf::stl::vector<T>& values, size_t hash = FNV::basis) {
|
inline size_t fnv1a(const uf::stl::vector<T>& values, size_t hash = FNV::basis) {
|
||||||
if constexpr (std::is_same_v<T, bool>) {
|
if constexpr (std::is_same_v<T, bool>) {
|
||||||
@ -63,6 +89,13 @@ namespace uf {
|
|||||||
}
|
}
|
||||||
return hash;
|
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 <unordered_map>
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
|
#include <uf/utils/math/hash.h>
|
||||||
|
|
||||||
namespace uf {
|
namespace uf {
|
||||||
namespace stl {
|
namespace stl {
|
||||||
template<
|
template<
|
||||||
class Key,
|
class Key,
|
||||||
class T,
|
class T,
|
||||||
class Hash = std::hash<Key>,
|
class Hash = uf::algo::hasher,
|
||||||
class KeyEqual = std::equal_to<Key>,
|
class KeyEqual = std::equal_to<Key>,
|
||||||
#if UF_MEMORYPOOL_USE_STL_ALLOCATOR
|
#if UF_MEMORYPOOL_USE_STL_ALLOCATOR
|
||||||
class Allocator = std::allocator<std::pair<const Key, T>>
|
class Allocator = std::allocator<std::pair<const Key, T>>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user