15 #ifndef BELUGA_ALGORITHM_SPATIAL_HASH_HPP
16 #define BELUGA_ALGORITHM_SPATIAL_HASH_HPP
23 #include <type_traits>
44 template <std::
size_t N, std::
size_t I>
46 constexpr
auto kFib = []() {
47 if constexpr (std::is_same_v<std::size_t, std::uint64_t>) {
48 return 11400714819323198485LLU;
49 }
else if constexpr (std::is_same_v<std::size_t, std::uint32_t>) {
54 static_assert([](
auto) {
return false; }(std::integral_constant<std::size_t, N>{}));
58 using signed_type = std::make_signed_t<std::size_t>;
59 using unsigned_type = std::make_unsigned_t<std::size_t>;
62 const auto signed_value =
static_cast<signed_type
>(std::floor(value));
64 const auto unsigned_value =
static_cast<unsigned_type
>(signed_value);
66 const auto div_hashed_value = kFib * unsigned_value;
68 if constexpr (N * I != 0) {
69 const auto left_hash = (div_hashed_value << N * I);
70 const auto right_hash = (div_hashed_value >> (std::numeric_limits<std::size_t>::digits - N * I));
71 return left_hash | right_hash;
73 return div_hashed_value;
87 template <
class T, std::size_t... Ids>
90 const std::array<
double,
sizeof...(Ids)>& resolution,
91 [[maybe_unused]] std::index_sequence<Ids...> index_sequence) {
92 constexpr
auto kBits = std::numeric_limits<std::size_t>::digits /
sizeof...(Ids);
93 return (detail::floor_and_fibo_hash<kBits, Ids>(std::get<Ids>(value) / resolution[Ids]) ^ ...);
99 template <
class T,
typename Enable =
void>
103 template <
class T, std::
size_t N>
104 class spatial_hash<
std::array<T, N>, std::enable_if_t<std::is_arithmetic_v<T>, void>> {
121 constexpr std::size_t
operator()(
const std::array<T, N>& array)
const {
130 template <
template <
class...>
class Tuple,
class... Types>
148 constexpr std::size_t
operator()(
const Tuple<Types...>& tuple)
const {
149 return detail::hash_impl(tuple, resolution_, std::make_index_sequence<
sizeof...(Types)>());
169 double x_clustering_resolution,
170 double y_clustering_resolution,
171 double theta_clustering_resolution)
172 : underlying_hasher_{{x_clustering_resolution, y_clustering_resolution, theta_clustering_resolution}} {};
179 explicit spatial_hash(
double linear_clustering_resolution,
double angular_clustering_resolution)
180 :
spatial_hash(linear_clustering_resolution, linear_clustering_resolution, angular_clustering_resolution){};
191 const auto& position =
state.translation();
192 return underlying_hasher_(std::make_tuple(position.x(), position.y(),
state.so2().log()));