Browse Source
maybe ECS framework can be used to gain more efficiency, but it's just fine for nowV2-origin
24 changed files with 517 additions and 245 deletions
@ -0,0 +1,67 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include <functional> |
||||
|
#include <math/eigen_alias.hpp> |
||||
|
|
||||
|
#include <xxhash.h> |
||||
|
|
||||
|
namespace detail |
||||
|
{ |
||||
|
template <typename T> |
||||
|
struct float_to_int_type |
||||
|
{ |
||||
|
static_assert(std::is_floating_point_v<T>, "T must be a floating point type"); |
||||
|
using type = std::conditional_t<sizeof(T) == 4, uint32_t, uint64_t>; |
||||
|
}; |
||||
|
|
||||
|
static constexpr float float_hash_epsilon = 1e-6f; |
||||
|
} |
||||
|
|
||||
|
struct hash_funcs_fn |
||||
|
{ |
||||
|
template <typename T, int M, int N> |
||||
|
size_t operator()(const Eigen::Matrix<T, M, N> &mat) const |
||||
|
{ |
||||
|
static_assert(M != Eigen::Dynamic && N != Eigen::Dynamic, "only fixed size matrix is supported"); |
||||
|
|
||||
|
if constexpr (std::is_integral_v<T>) |
||||
|
return XXH3_64bits(mat.data(), sizeof(T) * M * N); |
||||
|
else if constexpr (std::is_floating_point_v<T>) |
||||
|
{ |
||||
|
using integral_type = typename detail::float_to_int_type<T>::type; |
||||
|
Eigen::Matrix<integral_type, M, N> int_mat = (mat.array() / static_cast<T>(detail::float_hash_epsilon)).template cast<integral_type>(); |
||||
|
return XXH3_64bits(int_mat.data(), sizeof(integral_type) * M * N); |
||||
|
} |
||||
|
else |
||||
|
static_assert([]() { return false; }(), "unsupported type in hash<Eigen::Matrix>"); |
||||
|
} |
||||
|
|
||||
|
template <typename T, int N> |
||||
|
size_t operator()(const Eigen::Transform<T, N, Eigen::AffineCompact> &trans) const |
||||
|
{ |
||||
|
if constexpr (std::is_integral_v<T>) |
||||
|
return XXH3_64bits(trans.data(), sizeof(T) * N * (N + 1)); |
||||
|
else if constexpr (std::is_floating_point_v<T>) |
||||
|
{ |
||||
|
using integral_type = typename detail::float_to_int_type<T>::type; |
||||
|
Eigen::Matrix<integral_type, N, N + 1> int_mat = (trans.array() / static_cast<T>(detail::float_hash_epsilon)).template cast<integral_type>(); |
||||
|
return XXH3_64bits(int_mat.data(), sizeof(integral_type) * N * (N + 1)); |
||||
|
} |
||||
|
else |
||||
|
static_assert([]() { return false; }(), "unsupported type in hash<Eigen::Matrix>"); |
||||
|
} |
||||
|
|
||||
|
template <typename T> |
||||
|
size_t operator()(std::reference_wrapper<T> ref) const |
||||
|
{ |
||||
|
return size_t(std::addressof(ref.get())); |
||||
|
} |
||||
|
|
||||
|
template <typename T> |
||||
|
size_t operator()(std::reference_wrapper<const T> ref) const |
||||
|
{ |
||||
|
return size_t(std::addressof(ref.get())); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
static constexpr hash_funcs_fn hash_funcs{}; |
||||
@ -0,0 +1,40 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include <type_traits> |
||||
|
|
||||
|
template <typename T> |
||||
|
struct pointer_wrapper{ |
||||
|
static_assert(std::is_object_v<T>, "T must be an object type"); |
||||
|
|
||||
|
pointer_wrapper() noexcept = default; |
||||
|
explicit pointer_wrapper(T* p) noexcept : ptr(p) {} |
||||
|
explicit pointer_wrapper(T&& x) noexcept |
||||
|
{ |
||||
|
T& ref = std::forward<T&&>(x); |
||||
|
ptr = std::addressof(ref); |
||||
|
} |
||||
|
|
||||
|
T& get() const noexcept { return *ptr; } |
||||
|
auto operator->() const noexcept { return ptr; } |
||||
|
operator T&() const noexcept { return *ptr; } |
||||
|
|
||||
|
T copy() const noexcept { return *ptr; } |
||||
|
|
||||
|
auto raw() const noexcept -> T* { return ptr; } |
||||
|
operator bool() const noexcept { return ptr != nullptr; } |
||||
|
|
||||
|
private: |
||||
|
T* ptr{nullptr}; |
||||
|
}; |
||||
|
|
||||
|
template <typename T> |
||||
|
auto make_pointer_wrapper(T* p) noexcept -> pointer_wrapper<T> |
||||
|
{ |
||||
|
return pointer_wrapper<T>(p); |
||||
|
} |
||||
|
|
||||
|
template <typename T> |
||||
|
auto make_pointer_wrapper(T& x) noexcept -> pointer_wrapper<T> |
||||
|
{ |
||||
|
return pointer_wrapper<T>(x); |
||||
|
} |
||||
Loading…
Reference in new issue