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