You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
2.3 KiB
67 lines
2.3 KiB
#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.affine().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{};
|