Refactor: BLI: simplify extending get_default_hash function

This simplifies extending `blender::get_default_hash` to more than 4 parameters
by just adding extra factors to the list. The behavior should be the same as
before.

Pull Request: https://projects.blender.org/blender/blender/pulls/139392
This commit is contained in:
Jacques Lucke
2025-05-24 21:01:05 +02:00
parent 4baf428e5b
commit 64a13f4be2
4 changed files with 30 additions and 26 deletions

View File

@@ -65,6 +65,7 @@
#include <string>
#include <utility>
#include "BLI_hash_fwd.hh"
#include "BLI_string_ref.hh"
namespace blender {
@@ -215,35 +216,24 @@ template<typename T> struct DefaultHash<T *> {
}
};
template<typename T> uint64_t get_default_hash(const T &v)
namespace detail {
static constexpr std::array<uint64_t, 3> default_hash_factors = {19349669, 83492791, 3632623};
template<size_t... I, typename... Args>
inline uint64_t get_default_hash_array(std::index_sequence<I...> /*indices*/, const Args &...args)
{
return DefaultHash<std::decay_t<T>>{}(v);
static_assert(sizeof...(Args) == sizeof...(I));
static_assert(sizeof...(Args) <= default_hash_factors.size());
return (0 ^ ... ^ (default_hash_factors[I] * DefaultHash<std::decay_t<Args>>{}(args)));
}
template<typename T1, typename T2> uint64_t get_default_hash(const T1 &v1, const T2 &v2)
{
const uint64_t h1 = get_default_hash(v1);
const uint64_t h2 = get_default_hash(v2);
return h1 ^ (h2 * 19349669);
}
} // namespace detail
template<typename T1, typename T2, typename T3>
uint64_t get_default_hash(const T1 &v1, const T2 &v2, const T3 &v3)
template<typename T, typename... Args>
inline uint64_t get_default_hash(const T &v, const Args &...args)
{
const uint64_t h1 = get_default_hash(v1);
const uint64_t h2 = get_default_hash(v2);
const uint64_t h3 = get_default_hash(v3);
return h1 ^ (h2 * 19349669) ^ (h3 * 83492791);
}
template<typename T1, typename T2, typename T3, typename T4>
uint64_t get_default_hash(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
{
const uint64_t h1 = get_default_hash(v1);
const uint64_t h2 = get_default_hash(v2);
const uint64_t h3 = get_default_hash(v3);
const uint64_t h4 = get_default_hash(v4);
return h1 ^ (h2 * 19349669) ^ (h3 * 83492791) ^ (h4 * 3632623);
return DefaultHash<std::decay_t<T>>{}(v) ^
detail::get_default_hash_array(std::make_index_sequence<sizeof...(Args)>(), args...);
}
/** Support hashing different kinds of pointer types. */

View File

@@ -0,0 +1,14 @@
/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include <cstdint>
namespace blender {
template<typename T, typename... Args>
inline uint64_t get_default_hash(const T &v, const Args &...args);
}

View File

@@ -60,14 +60,13 @@
#include <array>
#include <vector>
#include "BLI_hash_fwd.hh"
#include "BLI_index_range.hh"
#include "BLI_memory_utils.hh"
#include "BLI_utildefines.h"
namespace blender {
template<typename T> uint64_t get_default_hash(const T &v);
/**
* References an array of type T that is owned by someone else. The data in the array cannot be
* modified.

View File

@@ -251,6 +251,7 @@ set(SRC
BLI_gsqueue.h
BLI_hash.h
BLI_hash.hh
BLI_hash_fwd.hh
BLI_hash_md5.hh
BLI_hash_mm2a.hh
BLI_hash_mm3.hh