From 64a13f4be2775f7a2fc8e73e8ced1feac4146216 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 24 May 2025 21:01:05 +0200 Subject: [PATCH] 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 --- source/blender/blenlib/BLI_hash.hh | 38 ++++++++++---------------- source/blender/blenlib/BLI_hash_fwd.hh | 14 ++++++++++ source/blender/blenlib/BLI_span.hh | 3 +- source/blender/blenlib/CMakeLists.txt | 1 + 4 files changed, 30 insertions(+), 26 deletions(-) create mode 100644 source/blender/blenlib/BLI_hash_fwd.hh diff --git a/source/blender/blenlib/BLI_hash.hh b/source/blender/blenlib/BLI_hash.hh index e6fe832f818..738d639f519 100644 --- a/source/blender/blenlib/BLI_hash.hh +++ b/source/blender/blenlib/BLI_hash.hh @@ -65,6 +65,7 @@ #include #include +#include "BLI_hash_fwd.hh" #include "BLI_string_ref.hh" namespace blender { @@ -215,35 +216,24 @@ template struct DefaultHash { } }; -template uint64_t get_default_hash(const T &v) +namespace detail { +static constexpr std::array default_hash_factors = {19349669, 83492791, 3632623}; + +template +inline uint64_t get_default_hash_array(std::index_sequence /*indices*/, const Args &...args) { - return DefaultHash>{}(v); + static_assert(sizeof...(Args) == sizeof...(I)); + static_assert(sizeof...(Args) <= default_hash_factors.size()); + return (0 ^ ... ^ (default_hash_factors[I] * DefaultHash>{}(args))); } -template 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 -uint64_t get_default_hash(const T1 &v1, const T2 &v2, const T3 &v3) +template +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 -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>{}(v) ^ + detail::get_default_hash_array(std::make_index_sequence(), args...); } /** Support hashing different kinds of pointer types. */ diff --git a/source/blender/blenlib/BLI_hash_fwd.hh b/source/blender/blenlib/BLI_hash_fwd.hh new file mode 100644 index 00000000000..994cebb76a6 --- /dev/null +++ b/source/blender/blenlib/BLI_hash_fwd.hh @@ -0,0 +1,14 @@ +/* SPDX-FileCopyrightText: 2025 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include + +namespace blender { + +template +inline uint64_t get_default_hash(const T &v, const Args &...args); + +} diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh index 1ddf9151a75..2eccbc99515 100644 --- a/source/blender/blenlib/BLI_span.hh +++ b/source/blender/blenlib/BLI_span.hh @@ -60,14 +60,13 @@ #include #include +#include "BLI_hash_fwd.hh" #include "BLI_index_range.hh" #include "BLI_memory_utils.hh" #include "BLI_utildefines.h" namespace blender { -template 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. diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index ecb089815c3..d1d29adca0a 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -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