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

#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{};