From d09b5fb75f047b52d446fef8152c128cdcdebaa4 Mon Sep 17 00:00:00 2001 From: Julien Jerphanion Date: Fri, 26 Jul 2024 15:08:14 +0200 Subject: [PATCH 1/4] Make more classes hashable and comparable Signed-off-by: Julien Jerphanion --- .../include/mamba/specs/build_number_spec.hpp | 23 ++++++ .../mamba/specs/chimera_string_spec.hpp | 22 ++++++ libmamba/include/mamba/specs/glob_spec.hpp | 19 +++++ libmamba/include/mamba/specs/match_spec.hpp | 72 +++++++++++++++++++ libmamba/include/mamba/specs/package_info.hpp | 44 ++++++++++++ libmamba/include/mamba/specs/regex_spec.hpp | 12 ++++ .../mamba/specs/unresolved_channel.hpp | 25 +++++++ libmamba/include/mamba/specs/version_spec.hpp | 34 +++++++++ .../include/mamba/util/flat_binary_tree.hpp | 21 ++++++ .../mamba/util/flat_bool_expr_tree.hpp | 10 +++ libmamba/include/mamba/util/flat_set.hpp | 17 +++++ libmamba/include/mamba/util/heap_optional.hpp | 28 ++++++++ 12 files changed, 327 insertions(+) diff --git a/libmamba/include/mamba/specs/build_number_spec.hpp b/libmamba/include/mamba/specs/build_number_spec.hpp index b9e0533e9d..6436885e23 100644 --- a/libmamba/include/mamba/specs/build_number_spec.hpp +++ b/libmamba/include/mamba/specs/build_number_spec.hpp @@ -15,6 +15,7 @@ #include #include "mamba/specs/error.hpp" +#include "mamba/util/tuple_hash.hpp" namespace mamba::specs { @@ -124,6 +125,16 @@ namespace mamba::specs */ [[nodiscard]] auto contains(BuildNumber point) const -> bool; + [[nodiscard]] auto operator==(const BuildNumberSpec& other) const -> bool + { + return m_predicate == other.m_predicate; + } + + [[nodiscard]] auto operator!=(const BuildNumberSpec& other) const -> bool + { + return !(*this == other); + } + private: BuildNumberPredicate m_predicate; @@ -155,4 +166,16 @@ struct fmt::formatter format(const ::mamba::specs::BuildNumberSpec& spec, format_context& ctx) -> decltype(ctx.out()); }; +template <> +struct std::hash +{ + auto operator()(const mamba::specs::BuildNumberSpec& spec) const -> std::size_t + { + auto seed = std::size_t{ 0 }; + seed = mamba::util::hash_combine_val(seed, spec.str()); + + return seed; + } +}; + #endif diff --git a/libmamba/include/mamba/specs/chimera_string_spec.hpp b/libmamba/include/mamba/specs/chimera_string_spec.hpp index e1cfbb7e15..24f61ef1ce 100644 --- a/libmamba/include/mamba/specs/chimera_string_spec.hpp +++ b/libmamba/include/mamba/specs/chimera_string_spec.hpp @@ -15,6 +15,7 @@ #include "mamba/specs/error.hpp" #include "mamba/specs/glob_spec.hpp" #include "mamba/specs/regex_spec.hpp" +#include "mamba/util/tuple_hash.hpp" namespace mamba::specs { @@ -51,6 +52,16 @@ namespace mamba::specs [[nodiscard]] auto str() const -> const std::string&; + [[nodiscard]] auto operator==(const ChimeraStringSpec& other) const -> bool + { + return m_spec == other.m_spec; + } + + [[nodiscard]] auto operator!=(const ChimeraStringSpec& other) const -> bool + { + return !(*this == other); + } + private: Chimera m_spec; @@ -66,4 +77,15 @@ struct fmt::formatter format(const ::mamba::specs::ChimeraStringSpec& spec, format_context& ctx) -> decltype(ctx.out()); }; +template <> +struct std::hash +{ + auto operator()(const mamba::specs::ChimeraStringSpec& spec) const -> std::size_t + { + auto seed = std::size_t(0); + seed = mamba::util::hash_combine_val(seed, spec.str()); + return seed; + } +}; + #endif diff --git a/libmamba/include/mamba/specs/glob_spec.hpp b/libmamba/include/mamba/specs/glob_spec.hpp index 71d8411453..0a59ec68aa 100644 --- a/libmamba/include/mamba/specs/glob_spec.hpp +++ b/libmamba/include/mamba/specs/glob_spec.hpp @@ -43,6 +43,16 @@ namespace mamba::specs [[nodiscard]] auto str() const -> const std::string&; + [[nodiscard]] auto operator==(const GlobSpec& other) const -> bool + { + return m_pattern == other.m_pattern; + } + + [[nodiscard]] auto operator!=(const GlobSpec& other) const -> bool + { + return !(*this == other); + } + private: std::string m_pattern = std::string(free_pattern); @@ -57,4 +67,13 @@ struct fmt::formatter auto format(const ::mamba::specs::GlobSpec& spec, format_context& ctx) -> decltype(ctx.out()); }; +template <> +struct std::hash +{ + auto operator()(const mamba::specs::GlobSpec& spec) const -> std::size_t + { + return std::hash{}(spec.str()); + } +}; + #endif diff --git a/libmamba/include/mamba/specs/match_spec.hpp b/libmamba/include/mamba/specs/match_spec.hpp index 52108f295c..245a1b4ba8 100644 --- a/libmamba/include/mamba/specs/match_spec.hpp +++ b/libmamba/include/mamba/specs/match_spec.hpp @@ -22,6 +22,7 @@ #include "mamba/specs/version_spec.hpp" #include "mamba/util/flat_set.hpp" #include "mamba/util/heap_optional.hpp" +#include "mamba/util/tuple_hash.hpp" namespace mamba::specs { @@ -135,6 +136,24 @@ namespace mamba::specs */ [[nodiscard]] auto contains_except_channel(const PackageInfo& pkg) const -> bool; + auto operator==(const MatchSpec& other) const -> bool + { + return m_channel == other.m_channel && m_version == other.m_version + && m_name == other.m_name && m_build_string == other.m_build_string + && m_name_space == other.m_name_space && m_build_number == other.m_build_number + && m_extra == other.m_extra; + } + + auto operator!=(const MatchSpec& other) const -> bool + { + return !(*this == other); + } + + auto extra_members_hash(std::size_t seed) const -> std::size_t + { + return mamba::util::hash_combine_val(seed, m_extra); + } + private: struct ExtraMembers @@ -150,7 +169,23 @@ namespace mamba::specs std::string features = {}; string_set track_features = {}; bool optional = false; + + [[nodiscard]] auto operator==(const ExtraMembers& other) const -> bool + { + return filename == other.filename && subdirs == other.subdirs && md5 == other.md5 + && sha256 == other.sha256 && license == other.license + && license_family == other.license_family && features == other.features + && track_features == other.track_features && optional == other.optional; + } + + [[nodiscard]] auto operator!=(const ExtraMembers& other) const -> bool + { + return !(*this == other); + } + + friend struct std::hash; }; + friend struct std::hash; std::optional m_channel; VersionSpec m_version; @@ -255,4 +290,41 @@ namespace mamba::specs return true; } } + +template <> +struct std::hash +{ + auto operator()(const mamba::specs::MatchSpec& spec) const -> std::size_t + { + auto seed = std::size_t(0); + seed = mamba::util::hash_combine_val(seed, spec.channel()); + seed = mamba::util::hash_combine_val(seed, spec.version()); + seed = mamba::util::hash_combine_val(seed, spec.name()); + seed = mamba::util::hash_combine_val(seed, spec.build_string()); + seed = mamba::util::hash_combine_val(seed, spec.name_space()); + seed = mamba::util::hash_combine_val(seed, spec.build_number()); + seed = spec.extra_members_hash(seed); + return seed; + } +}; + +template <> +struct std::hash +{ + auto operator()(const mamba::specs::MatchSpec::ExtraMembers& extra) const -> std::size_t + { + auto seed = std::size_t(0); + seed = mamba::util::hash_combine_val(seed, extra.filename); + seed = mamba::util::hash_combine_val(seed, extra.subdirs); + seed = mamba::util::hash_combine_val(seed, extra.md5); + seed = mamba::util::hash_combine_val(seed, extra.sha256); + seed = mamba::util::hash_combine_val(seed, extra.license); + seed = mamba::util::hash_combine_val(seed, extra.license_family); + seed = mamba::util::hash_combine_val(seed, extra.features); + seed = mamba::util::hash_combine_val(seed, extra.track_features); + seed = mamba::util::hash_combine_val(seed, extra.optional); + return seed; + } +}; + #endif diff --git a/libmamba/include/mamba/specs/package_info.hpp b/libmamba/include/mamba/specs/package_info.hpp index 4623c30baa..cae2fe4513 100644 --- a/libmamba/include/mamba/specs/package_info.hpp +++ b/libmamba/include/mamba/specs/package_info.hpp @@ -15,6 +15,7 @@ #include "mamba/specs/error.hpp" #include "mamba/specs/platform.hpp" +#include "mamba/util/tuple_hash.hpp" namespace mamba::specs { @@ -81,4 +82,47 @@ namespace mamba::specs void from_json(const nlohmann::json& j, PackageInfo& pkg); } + +template <> +struct std::hash +{ + auto operator()(const mamba::specs::PackageInfo& pkg) const -> std::size_t + { + auto seed = std::size_t(0); + seed = mamba::util::hash_combine_val(seed, pkg.name); + seed = mamba::util::hash_combine_val(seed, pkg.version); + seed = mamba::util::hash_combine_val(seed, pkg.build_string); + seed = mamba::util::hash_combine_val(seed, pkg.build_number); + seed = mamba::util::hash_combine_val(seed, pkg.channel); + seed = mamba::util::hash_combine_val(seed, pkg.package_url); + seed = mamba::util::hash_combine_val(seed, pkg.platform); + seed = mamba::util::hash_combine_val(seed, pkg.filename); + seed = mamba::util::hash_combine_val(seed, pkg.license); + seed = mamba::util::hash_combine_val(seed, pkg.md5); + seed = mamba::util::hash_combine_val(seed, pkg.sha256); + seed = mamba::util::hash_combine_val(seed, pkg.signatures); + seed = mamba::util::hash_combine_val_range( + seed, + pkg.track_features.begin(), + pkg.track_features.end() + ); + seed = mamba::util::hash_combine_val_range( + seed, + pkg.dependencies.begin(), + pkg.dependencies.end() + ); + seed = mamba::util::hash_combine_val_range(seed, pkg.constrains.begin(), pkg.constrains.end()); + seed = mamba::util::hash_combine_val_range( + seed, + pkg.defaulted_keys.begin(), + pkg.defaulted_keys.end() + ); + seed = mamba::util::hash_combine_val(seed, pkg.noarch); + seed = mamba::util::hash_combine_val(seed, pkg.size); + seed = mamba::util::hash_combine_val(seed, pkg.timestamp); + seed = mamba::util::hash_combine_val(seed, pkg.package_type); + return seed; + } +}; + #endif diff --git a/libmamba/include/mamba/specs/regex_spec.hpp b/libmamba/include/mamba/specs/regex_spec.hpp index 28420a0b6c..d873ffe643 100644 --- a/libmamba/include/mamba/specs/regex_spec.hpp +++ b/libmamba/include/mamba/specs/regex_spec.hpp @@ -47,6 +47,18 @@ namespace mamba::specs [[nodiscard]] auto str() const -> const std::string&; + [[nodiscard]] auto operator==(const RegexSpec& other) const -> bool + { + return ( + m_raw_pattern == other.m_raw_pattern && m_pattern.flags() == other.m_pattern.flags() + ); + } + + [[nodiscard]] auto operator!=(const RegexSpec& other) const -> bool + { + return !(*this == other); + } + private: std::regex m_pattern; diff --git a/libmamba/include/mamba/specs/unresolved_channel.hpp b/libmamba/include/mamba/specs/unresolved_channel.hpp index ac8096be8a..294d54d5ec 100644 --- a/libmamba/include/mamba/specs/unresolved_channel.hpp +++ b/libmamba/include/mamba/specs/unresolved_channel.hpp @@ -17,6 +17,7 @@ #include "mamba/specs/error.hpp" #include "mamba/specs/platform.hpp" #include "mamba/util/flat_set.hpp" +#include "mamba/util/tuple_hash.hpp" namespace mamba::specs { @@ -111,6 +112,17 @@ namespace mamba::specs [[nodiscard]] auto str() const -> std::string; + [[nodiscard]] auto operator==(const UnresolvedChannel& other) const -> bool + { + return m_location == other.m_location && m_platform_filters == other.m_platform_filters + && m_type == other.m_type; + } + + [[nodiscard]] auto operator!=(const UnresolvedChannel& other) const -> bool + { + return !(*this == other); + } + private: std::string m_location = std::string(unknown_channel); @@ -137,4 +149,17 @@ struct fmt::formatter auto format(const UnresolvedChannel& uc, format_context& ctx) const -> format_context::iterator; }; +template <> +struct std::hash +{ + auto operator()(const mamba::specs::UnresolvedChannel& uc) const -> std::size_t + { + auto seed = std::size_t{ 0 }; + seed = mamba::util::hash_combine_val(seed, uc.location()); + seed = mamba::util::hash_combine_val(seed, uc.platform_filters()); + seed = mamba::util::hash_combine_val(seed, static_cast(uc.type())); + return seed; + } +}; + #endif diff --git a/libmamba/include/mamba/specs/version_spec.hpp b/libmamba/include/mamba/specs/version_spec.hpp index 62228e163f..f3e77e96be 100644 --- a/libmamba/include/mamba/specs/version_spec.hpp +++ b/libmamba/include/mamba/specs/version_spec.hpp @@ -17,6 +17,7 @@ #include "mamba/specs/error.hpp" #include "mamba/specs/version.hpp" #include "mamba/util/flat_bool_expr_tree.hpp" +#include "mamba/util/tuple_hash.hpp" namespace mamba::specs { @@ -195,6 +196,16 @@ namespace mamba::specs */ [[nodiscard]] auto expression_size() const -> std::size_t; + [[nodiscard]] auto operator==(const VersionSpec& other) const -> bool + { + return m_tree == other.m_tree; + } + + [[nodiscard]] auto operator!=(const VersionSpec& other) const -> bool + { + return !(*this == other); + } + private: tree_type m_tree; @@ -234,4 +245,27 @@ struct fmt::formatter auto format(const ::mamba::specs::VersionSpec& spec, format_context& ctx) -> decltype(ctx.out()); }; + +template <> +struct std::hash +{ + auto operator()(const mamba::specs::VersionPredicate& pred) const -> std::size_t + { + auto seed = std::size_t{ 0 }; + seed = mamba::util::hash_combine_val(seed, pred.str()); + return seed; + } +}; + +template <> +struct std::hash +{ + auto operator()(const mamba::specs::VersionSpec& spec) const -> std::size_t + { + auto seed = std::size_t{ 0 }; + seed = mamba::util::hash_combine_val(seed, spec.str()); + return seed; + } +}; + #endif diff --git a/libmamba/include/mamba/util/flat_binary_tree.hpp b/libmamba/include/mamba/util/flat_binary_tree.hpp index 749ba9ad16..0d7bfb5ea8 100644 --- a/libmamba/include/mamba/util/flat_binary_tree.hpp +++ b/libmamba/include/mamba/util/flat_binary_tree.hpp @@ -38,6 +38,17 @@ namespace mamba::util branch_type data; std::size_t left_child = 0; std::size_t right_child = 0; + + [[nodiscard]] auto operator==(const branch_node& other) const -> bool + { + return data == other.data && left_child == other.left_child + && right_child == other.right_child; + } + + [[nodiscard]] auto operator!=(const branch_node& other) const -> bool + { + return !(*this == other); + } }; using leaf_node = leaf_type; @@ -90,6 +101,16 @@ namespace mamba::util [[nodiscard]] auto right(idx_type idx) const -> idx_type; [[nodiscard]] auto root() const -> idx_type; + [[nodiscard]] auto operator==(const flat_binary_tree& other) const -> bool + { + return m_nodes == other.m_nodes && m_root == other.m_root; + } + + [[nodiscard]] auto operator!=(const flat_binary_tree& other) const -> bool + { + return !(*this == other); + } + template void dfs_raw(Visitor&& visitor, idx_type start) const; diff --git a/libmamba/include/mamba/util/flat_bool_expr_tree.hpp b/libmamba/include/mamba/util/flat_bool_expr_tree.hpp index 93f797b0fc..e5b9a6d8f5 100644 --- a/libmamba/include/mamba/util/flat_bool_expr_tree.hpp +++ b/libmamba/include/mamba/util/flat_bool_expr_tree.hpp @@ -173,6 +173,16 @@ namespace mamba::util template void infix_for_each(UnaryFunc&& func) const; + [[nodiscard]] auto operator==(const self_type& other) const -> bool + { + return m_tree == other.m_tree; + } + + [[nodiscard]] auto operator!=(const self_type& other) const -> bool + { + return !(*this == other); + } + private: using idx_type = typename tree_type::idx_type; diff --git a/libmamba/include/mamba/util/flat_set.hpp b/libmamba/include/mamba/util/flat_set.hpp index 55c7a96256..eccc4cbd8c 100644 --- a/libmamba/include/mamba/util/flat_set.hpp +++ b/libmamba/include/mamba/util/flat_set.hpp @@ -12,6 +12,8 @@ #include #include +#include "mamba/util/tuple_hash.hpp" + namespace mamba::util { @@ -557,4 +559,19 @@ namespace mamba::util return out; } } + +template +struct std::hash> +{ + auto operator()(const mamba::util::flat_set& set) const -> std::size_t + { + auto seed = std::size_t{ 0 }; + for (const auto& key : set) + { + seed = mamba::util::hash_combine_val(seed, key); + } + return seed; + } +}; + #endif diff --git a/libmamba/include/mamba/util/heap_optional.hpp b/libmamba/include/mamba/util/heap_optional.hpp index 123bae5c67..2ff7e06e91 100644 --- a/libmamba/include/mamba/util/heap_optional.hpp +++ b/libmamba/include/mamba/util/heap_optional.hpp @@ -68,6 +68,20 @@ namespace mamba::util void reset(); + [[nodiscard]] auto operator==(const heap_optional& other) const -> bool + { + if (has_value() && other.has_value()) + { + return *m_ptr == *other; + } + return !has_value() && !other.has_value(); + } + + [[nodiscard]] auto operator!=(const heap_optional& other) const -> bool + { + return !(*this == other); + } + private: std::unique_ptr m_ptr = nullptr; @@ -236,4 +250,18 @@ namespace mamba::util m_ptr = nullptr; } } + +template +struct std::hash> +{ + std::size_t operator()(const mamba::util::heap_optional& opt) const + { + if (opt.has_value()) + { + return std::hash{}(*opt); + } + return 0; + } +}; + #endif From a0380e933369e680f6aef6da30a9cc429adfb0bd Mon Sep 17 00:00:00 2001 From: Julien Jerphanion Date: Fri, 26 Jul 2024 17:03:06 +0200 Subject: [PATCH 2/4] Apply review comments Signed-off-by: Julien Jerphanion Co-authored-by: Klaim --- .../include/mamba/specs/build_number_spec.hpp | 6 +-- .../mamba/specs/chimera_string_spec.hpp | 5 +- libmamba/include/mamba/specs/glob_spec.hpp | 1 + libmamba/include/mamba/specs/match_spec.hpp | 50 ++++++++++--------- libmamba/include/mamba/specs/package_info.hpp | 32 ++++++------ libmamba/include/mamba/specs/regex_spec.hpp | 6 +-- .../mamba/specs/unresolved_channel.hpp | 6 +-- libmamba/include/mamba/specs/version_spec.hpp | 8 +-- .../include/mamba/util/flat_binary_tree.hpp | 2 + .../mamba/util/flat_bool_expr_tree.hpp | 1 + libmamba/include/mamba/util/flat_set.hpp | 7 +-- 11 files changed, 57 insertions(+), 67 deletions(-) diff --git a/libmamba/include/mamba/specs/build_number_spec.hpp b/libmamba/include/mamba/specs/build_number_spec.hpp index 6436885e23..0e50cee96a 100644 --- a/libmamba/include/mamba/specs/build_number_spec.hpp +++ b/libmamba/include/mamba/specs/build_number_spec.hpp @@ -125,6 +125,7 @@ namespace mamba::specs */ [[nodiscard]] auto contains(BuildNumber point) const -> bool; + // TODO: only use the `= default` implementation of `operator==` when we will use C++20. [[nodiscard]] auto operator==(const BuildNumberSpec& other) const -> bool { return m_predicate == other.m_predicate; @@ -171,10 +172,7 @@ struct std::hash { auto operator()(const mamba::specs::BuildNumberSpec& spec) const -> std::size_t { - auto seed = std::size_t{ 0 }; - seed = mamba::util::hash_combine_val(seed, spec.str()); - - return seed; + return mamba::util::hash_vals(spec.str()); } }; diff --git a/libmamba/include/mamba/specs/chimera_string_spec.hpp b/libmamba/include/mamba/specs/chimera_string_spec.hpp index 24f61ef1ce..80c15a6a75 100644 --- a/libmamba/include/mamba/specs/chimera_string_spec.hpp +++ b/libmamba/include/mamba/specs/chimera_string_spec.hpp @@ -52,6 +52,7 @@ namespace mamba::specs [[nodiscard]] auto str() const -> const std::string&; + // TODO: only use the `= default` implementation of `operator==` when we will use C++20. [[nodiscard]] auto operator==(const ChimeraStringSpec& other) const -> bool { return m_spec == other.m_spec; @@ -82,9 +83,7 @@ struct std::hash { auto operator()(const mamba::specs::ChimeraStringSpec& spec) const -> std::size_t { - auto seed = std::size_t(0); - seed = mamba::util::hash_combine_val(seed, spec.str()); - return seed; + return mamba::util::hash_vals(spec.str()); } }; diff --git a/libmamba/include/mamba/specs/glob_spec.hpp b/libmamba/include/mamba/specs/glob_spec.hpp index 0a59ec68aa..d7a140eec1 100644 --- a/libmamba/include/mamba/specs/glob_spec.hpp +++ b/libmamba/include/mamba/specs/glob_spec.hpp @@ -43,6 +43,7 @@ namespace mamba::specs [[nodiscard]] auto str() const -> const std::string&; + // TODO: only use the `= default` implementation of `operator==` when we will use C++20. [[nodiscard]] auto operator==(const GlobSpec& other) const -> bool { return m_pattern == other.m_pattern; diff --git a/libmamba/include/mamba/specs/match_spec.hpp b/libmamba/include/mamba/specs/match_spec.hpp index 245a1b4ba8..57f6f26562 100644 --- a/libmamba/include/mamba/specs/match_spec.hpp +++ b/libmamba/include/mamba/specs/match_spec.hpp @@ -136,7 +136,8 @@ namespace mamba::specs */ [[nodiscard]] auto contains_except_channel(const PackageInfo& pkg) const -> bool; - auto operator==(const MatchSpec& other) const -> bool + // TODO: only use the `= default` implementation of `operator==` when we will use C++20. + [[nodiscard]] auto operator==(const MatchSpec& other) const -> bool { return m_channel == other.m_channel && m_version == other.m_version && m_name == other.m_name && m_build_string == other.m_build_string @@ -144,14 +145,14 @@ namespace mamba::specs && m_extra == other.m_extra; } - auto operator!=(const MatchSpec& other) const -> bool + [[nodiscard]] auto operator!=(const MatchSpec& other) const -> bool { return !(*this == other); } - auto extra_members_hash(std::size_t seed) const -> std::size_t + auto extra_members_hash() const -> std::size_t { - return mamba::util::hash_combine_val(seed, m_extra); + return mamba::util::hash_vals(m_extra); } private: @@ -170,6 +171,7 @@ namespace mamba::specs string_set track_features = {}; bool optional = false; + // TODO: only use the `= default` implementation of `operator==` when we will use C++20. [[nodiscard]] auto operator==(const ExtraMembers& other) const -> bool { return filename == other.filename && subdirs == other.subdirs && md5 == other.md5 @@ -296,15 +298,15 @@ struct std::hash { auto operator()(const mamba::specs::MatchSpec& spec) const -> std::size_t { - auto seed = std::size_t(0); - seed = mamba::util::hash_combine_val(seed, spec.channel()); - seed = mamba::util::hash_combine_val(seed, spec.version()); - seed = mamba::util::hash_combine_val(seed, spec.name()); - seed = mamba::util::hash_combine_val(seed, spec.build_string()); - seed = mamba::util::hash_combine_val(seed, spec.name_space()); - seed = mamba::util::hash_combine_val(seed, spec.build_number()); - seed = spec.extra_members_hash(seed); - return seed; + return mamba::util::hash_vals( + spec.channel(), + spec.version(), + spec.name(), + spec.build_string(), + spec.name_space(), + spec.build_number(), + spec.extra_members_hash() + ); } }; @@ -313,17 +315,17 @@ struct std::hash { auto operator()(const mamba::specs::MatchSpec::ExtraMembers& extra) const -> std::size_t { - auto seed = std::size_t(0); - seed = mamba::util::hash_combine_val(seed, extra.filename); - seed = mamba::util::hash_combine_val(seed, extra.subdirs); - seed = mamba::util::hash_combine_val(seed, extra.md5); - seed = mamba::util::hash_combine_val(seed, extra.sha256); - seed = mamba::util::hash_combine_val(seed, extra.license); - seed = mamba::util::hash_combine_val(seed, extra.license_family); - seed = mamba::util::hash_combine_val(seed, extra.features); - seed = mamba::util::hash_combine_val(seed, extra.track_features); - seed = mamba::util::hash_combine_val(seed, extra.optional); - return seed; + return mamba::util::hash_vals( + extra.filename, + extra.subdirs, + extra.md5, + extra.sha256, + extra.license, + extra.license_family, + extra.features, + extra.track_features, + extra.optional + ); } }; diff --git a/libmamba/include/mamba/specs/package_info.hpp b/libmamba/include/mamba/specs/package_info.hpp index cae2fe4513..cdd8916d55 100644 --- a/libmamba/include/mamba/specs/package_info.hpp +++ b/libmamba/include/mamba/specs/package_info.hpp @@ -89,18 +89,21 @@ struct std::hash auto operator()(const mamba::specs::PackageInfo& pkg) const -> std::size_t { auto seed = std::size_t(0); - seed = mamba::util::hash_combine_val(seed, pkg.name); - seed = mamba::util::hash_combine_val(seed, pkg.version); - seed = mamba::util::hash_combine_val(seed, pkg.build_string); - seed = mamba::util::hash_combine_val(seed, pkg.build_number); - seed = mamba::util::hash_combine_val(seed, pkg.channel); - seed = mamba::util::hash_combine_val(seed, pkg.package_url); - seed = mamba::util::hash_combine_val(seed, pkg.platform); - seed = mamba::util::hash_combine_val(seed, pkg.filename); - seed = mamba::util::hash_combine_val(seed, pkg.license); - seed = mamba::util::hash_combine_val(seed, pkg.md5); - seed = mamba::util::hash_combine_val(seed, pkg.sha256); - seed = mamba::util::hash_combine_val(seed, pkg.signatures); + seed = mamba::util::hash_vals( + seed, + pkg.name, + pkg.version, + pkg.build_string, + pkg.build_number, + pkg.channel, + pkg.package_url, + pkg.platform, + pkg.filename, + pkg.license, + pkg.md5, + pkg.sha256, + pkg.signatures + ); seed = mamba::util::hash_combine_val_range( seed, pkg.track_features.begin(), @@ -117,10 +120,7 @@ struct std::hash pkg.defaulted_keys.begin(), pkg.defaulted_keys.end() ); - seed = mamba::util::hash_combine_val(seed, pkg.noarch); - seed = mamba::util::hash_combine_val(seed, pkg.size); - seed = mamba::util::hash_combine_val(seed, pkg.timestamp); - seed = mamba::util::hash_combine_val(seed, pkg.package_type); + seed = mamba::util::hash_vals(seed, pkg.noarch, pkg.size, pkg.timestamp, pkg.package_type); return seed; } }; diff --git a/libmamba/include/mamba/specs/regex_spec.hpp b/libmamba/include/mamba/specs/regex_spec.hpp index d873ffe643..71fc993031 100644 --- a/libmamba/include/mamba/specs/regex_spec.hpp +++ b/libmamba/include/mamba/specs/regex_spec.hpp @@ -47,11 +47,11 @@ namespace mamba::specs [[nodiscard]] auto str() const -> const std::string&; + // TODO: only use the `= default` implementation of `operator==` when we will use C++20. [[nodiscard]] auto operator==(const RegexSpec& other) const -> bool { - return ( - m_raw_pattern == other.m_raw_pattern && m_pattern.flags() == other.m_pattern.flags() - ); + return m_raw_pattern == other.m_raw_pattern + && m_pattern.flags() == other.m_pattern.flags(); } [[nodiscard]] auto operator!=(const RegexSpec& other) const -> bool diff --git a/libmamba/include/mamba/specs/unresolved_channel.hpp b/libmamba/include/mamba/specs/unresolved_channel.hpp index 294d54d5ec..d7da8d2598 100644 --- a/libmamba/include/mamba/specs/unresolved_channel.hpp +++ b/libmamba/include/mamba/specs/unresolved_channel.hpp @@ -154,11 +154,7 @@ struct std::hash { auto operator()(const mamba::specs::UnresolvedChannel& uc) const -> std::size_t { - auto seed = std::size_t{ 0 }; - seed = mamba::util::hash_combine_val(seed, uc.location()); - seed = mamba::util::hash_combine_val(seed, uc.platform_filters()); - seed = mamba::util::hash_combine_val(seed, static_cast(uc.type())); - return seed; + return mamba::util::hash_vals(uc.location(), uc.platform_filters(), static_cast(uc.type())); } }; diff --git a/libmamba/include/mamba/specs/version_spec.hpp b/libmamba/include/mamba/specs/version_spec.hpp index f3e77e96be..7ed08ae8cd 100644 --- a/libmamba/include/mamba/specs/version_spec.hpp +++ b/libmamba/include/mamba/specs/version_spec.hpp @@ -251,9 +251,7 @@ struct std::hash { auto operator()(const mamba::specs::VersionPredicate& pred) const -> std::size_t { - auto seed = std::size_t{ 0 }; - seed = mamba::util::hash_combine_val(seed, pred.str()); - return seed; + return mamba::util::hash_vals(pred.str()); } }; @@ -262,9 +260,7 @@ struct std::hash { auto operator()(const mamba::specs::VersionSpec& spec) const -> std::size_t { - auto seed = std::size_t{ 0 }; - seed = mamba::util::hash_combine_val(seed, spec.str()); - return seed; + return mamba::util::hash_vals(spec.str()); } }; diff --git a/libmamba/include/mamba/util/flat_binary_tree.hpp b/libmamba/include/mamba/util/flat_binary_tree.hpp index 0d7bfb5ea8..a1b8138a00 100644 --- a/libmamba/include/mamba/util/flat_binary_tree.hpp +++ b/libmamba/include/mamba/util/flat_binary_tree.hpp @@ -39,6 +39,7 @@ namespace mamba::util std::size_t left_child = 0; std::size_t right_child = 0; + // TODO: only use the `= default` implementation of `operator==` when we will use C++20. [[nodiscard]] auto operator==(const branch_node& other) const -> bool { return data == other.data && left_child == other.left_child @@ -101,6 +102,7 @@ namespace mamba::util [[nodiscard]] auto right(idx_type idx) const -> idx_type; [[nodiscard]] auto root() const -> idx_type; + // TODO: only use the `= default` implementation of `operator==` when we will use C++20. [[nodiscard]] auto operator==(const flat_binary_tree& other) const -> bool { return m_nodes == other.m_nodes && m_root == other.m_root; diff --git a/libmamba/include/mamba/util/flat_bool_expr_tree.hpp b/libmamba/include/mamba/util/flat_bool_expr_tree.hpp index e5b9a6d8f5..79c52cf778 100644 --- a/libmamba/include/mamba/util/flat_bool_expr_tree.hpp +++ b/libmamba/include/mamba/util/flat_bool_expr_tree.hpp @@ -173,6 +173,7 @@ namespace mamba::util template void infix_for_each(UnaryFunc&& func) const; + // TODO: only use the `= default` implementation of `operator==` when we will use C++20. [[nodiscard]] auto operator==(const self_type& other) const -> bool { return m_tree == other.m_tree; diff --git a/libmamba/include/mamba/util/flat_set.hpp b/libmamba/include/mamba/util/flat_set.hpp index eccc4cbd8c..8796edd902 100644 --- a/libmamba/include/mamba/util/flat_set.hpp +++ b/libmamba/include/mamba/util/flat_set.hpp @@ -565,12 +565,7 @@ struct std::hash> { auto operator()(const mamba::util::flat_set& set) const -> std::size_t { - auto seed = std::size_t{ 0 }; - for (const auto& key : set) - { - seed = mamba::util::hash_combine_val(seed, key); - } - return seed; + return mamba::util::hash_vals(set); } }; From fad28eeb60965e50df4e084a9c951e5f06789659 Mon Sep 17 00:00:00 2001 From: Julien Jerphanion Date: Fri, 26 Jul 2024 17:18:14 +0200 Subject: [PATCH 3/4] Format with one pair of attributes per line Signed-off-by: Julien Jerphanion Co-authored-by: Klaim --- libmamba/include/mamba/specs/match_spec.hpp | 22 +++++++++++++------ .../mamba/specs/unresolved_channel.hpp | 3 ++- .../include/mamba/util/flat_binary_tree.hpp | 3 ++- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/libmamba/include/mamba/specs/match_spec.hpp b/libmamba/include/mamba/specs/match_spec.hpp index 57f6f26562..45723d76f6 100644 --- a/libmamba/include/mamba/specs/match_spec.hpp +++ b/libmamba/include/mamba/specs/match_spec.hpp @@ -139,9 +139,12 @@ namespace mamba::specs // TODO: only use the `= default` implementation of `operator==` when we will use C++20. [[nodiscard]] auto operator==(const MatchSpec& other) const -> bool { - return m_channel == other.m_channel && m_version == other.m_version - && m_name == other.m_name && m_build_string == other.m_build_string - && m_name_space == other.m_name_space && m_build_number == other.m_build_number + return m_channel == other.m_channel // + && m_version == other.m_version // + && m_name == other.m_name // + && m_build_string == other.m_build_string // + && m_name_space == other.m_name_space // + && m_build_number == other.m_build_number // && m_extra == other.m_extra; } @@ -174,10 +177,15 @@ namespace mamba::specs // TODO: only use the `= default` implementation of `operator==` when we will use C++20. [[nodiscard]] auto operator==(const ExtraMembers& other) const -> bool { - return filename == other.filename && subdirs == other.subdirs && md5 == other.md5 - && sha256 == other.sha256 && license == other.license - && license_family == other.license_family && features == other.features - && track_features == other.track_features && optional == other.optional; + return filename == other.filename // + && subdirs == other.subdirs // + && md5 == other.md5 // + && sha256 == other.sha256 // + && license == other.license // + && license_family == other.license_family // + && features == other.features // + && track_features == other.track_features // + && optional == other.optional; } [[nodiscard]] auto operator!=(const ExtraMembers& other) const -> bool diff --git a/libmamba/include/mamba/specs/unresolved_channel.hpp b/libmamba/include/mamba/specs/unresolved_channel.hpp index d7da8d2598..120dcef805 100644 --- a/libmamba/include/mamba/specs/unresolved_channel.hpp +++ b/libmamba/include/mamba/specs/unresolved_channel.hpp @@ -114,7 +114,8 @@ namespace mamba::specs [[nodiscard]] auto operator==(const UnresolvedChannel& other) const -> bool { - return m_location == other.m_location && m_platform_filters == other.m_platform_filters + return m_location == other.m_location // + && m_platform_filters == other.m_platform_filters // && m_type == other.m_type; } diff --git a/libmamba/include/mamba/util/flat_binary_tree.hpp b/libmamba/include/mamba/util/flat_binary_tree.hpp index a1b8138a00..5f7323c037 100644 --- a/libmamba/include/mamba/util/flat_binary_tree.hpp +++ b/libmamba/include/mamba/util/flat_binary_tree.hpp @@ -42,7 +42,8 @@ namespace mamba::util // TODO: only use the `= default` implementation of `operator==` when we will use C++20. [[nodiscard]] auto operator==(const branch_node& other) const -> bool { - return data == other.data && left_child == other.left_child + return data == other.data // + && left_child == other.left_child // && right_child == other.right_child; } From f5f154b80d98cec67db837a42b2b816ed609e767 Mon Sep 17 00:00:00 2001 From: Julien Jerphanion Date: Fri, 26 Jul 2024 18:20:39 +0200 Subject: [PATCH 4/4] Reword comments Signed-off-by: Julien Jerphanion Co-authored-by: Klaim --- libmamba/include/mamba/specs/build_number_spec.hpp | 2 +- libmamba/include/mamba/specs/chimera_string_spec.hpp | 2 +- libmamba/include/mamba/specs/glob_spec.hpp | 2 +- libmamba/include/mamba/specs/match_spec.hpp | 4 ++-- libmamba/include/mamba/specs/regex_spec.hpp | 2 +- libmamba/include/mamba/util/flat_binary_tree.hpp | 4 ++-- libmamba/include/mamba/util/flat_bool_expr_tree.hpp | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libmamba/include/mamba/specs/build_number_spec.hpp b/libmamba/include/mamba/specs/build_number_spec.hpp index 0e50cee96a..695d3f196f 100644 --- a/libmamba/include/mamba/specs/build_number_spec.hpp +++ b/libmamba/include/mamba/specs/build_number_spec.hpp @@ -125,7 +125,7 @@ namespace mamba::specs */ [[nodiscard]] auto contains(BuildNumber point) const -> bool; - // TODO: only use the `= default` implementation of `operator==` when we will use C++20. + // TODO(C++20): replace by the `= default` implementation of `operator==` [[nodiscard]] auto operator==(const BuildNumberSpec& other) const -> bool { return m_predicate == other.m_predicate; diff --git a/libmamba/include/mamba/specs/chimera_string_spec.hpp b/libmamba/include/mamba/specs/chimera_string_spec.hpp index 80c15a6a75..c2f3112dd7 100644 --- a/libmamba/include/mamba/specs/chimera_string_spec.hpp +++ b/libmamba/include/mamba/specs/chimera_string_spec.hpp @@ -52,7 +52,7 @@ namespace mamba::specs [[nodiscard]] auto str() const -> const std::string&; - // TODO: only use the `= default` implementation of `operator==` when we will use C++20. + // TODO(C++20): replace by the `= default` implementation of `operator==` [[nodiscard]] auto operator==(const ChimeraStringSpec& other) const -> bool { return m_spec == other.m_spec; diff --git a/libmamba/include/mamba/specs/glob_spec.hpp b/libmamba/include/mamba/specs/glob_spec.hpp index d7a140eec1..f4090f779d 100644 --- a/libmamba/include/mamba/specs/glob_spec.hpp +++ b/libmamba/include/mamba/specs/glob_spec.hpp @@ -43,7 +43,7 @@ namespace mamba::specs [[nodiscard]] auto str() const -> const std::string&; - // TODO: only use the `= default` implementation of `operator==` when we will use C++20. + // TODO(C++20): replace by the `= default` implementation of `operator==` [[nodiscard]] auto operator==(const GlobSpec& other) const -> bool { return m_pattern == other.m_pattern; diff --git a/libmamba/include/mamba/specs/match_spec.hpp b/libmamba/include/mamba/specs/match_spec.hpp index 45723d76f6..1d690bacb1 100644 --- a/libmamba/include/mamba/specs/match_spec.hpp +++ b/libmamba/include/mamba/specs/match_spec.hpp @@ -136,7 +136,7 @@ namespace mamba::specs */ [[nodiscard]] auto contains_except_channel(const PackageInfo& pkg) const -> bool; - // TODO: only use the `= default` implementation of `operator==` when we will use C++20. + // TODO(C++20): replace by the `= default` implementation of `operator==` [[nodiscard]] auto operator==(const MatchSpec& other) const -> bool { return m_channel == other.m_channel // @@ -174,7 +174,7 @@ namespace mamba::specs string_set track_features = {}; bool optional = false; - // TODO: only use the `= default` implementation of `operator==` when we will use C++20. + // TODO(C++20): replace by the `= default` implementation of `operator==` [[nodiscard]] auto operator==(const ExtraMembers& other) const -> bool { return filename == other.filename // diff --git a/libmamba/include/mamba/specs/regex_spec.hpp b/libmamba/include/mamba/specs/regex_spec.hpp index 71fc993031..78610549e1 100644 --- a/libmamba/include/mamba/specs/regex_spec.hpp +++ b/libmamba/include/mamba/specs/regex_spec.hpp @@ -47,7 +47,7 @@ namespace mamba::specs [[nodiscard]] auto str() const -> const std::string&; - // TODO: only use the `= default` implementation of `operator==` when we will use C++20. + // TODO(C++20): replace by the `= default` implementation of `operator==` [[nodiscard]] auto operator==(const RegexSpec& other) const -> bool { return m_raw_pattern == other.m_raw_pattern diff --git a/libmamba/include/mamba/util/flat_binary_tree.hpp b/libmamba/include/mamba/util/flat_binary_tree.hpp index 5f7323c037..01c3b26813 100644 --- a/libmamba/include/mamba/util/flat_binary_tree.hpp +++ b/libmamba/include/mamba/util/flat_binary_tree.hpp @@ -39,7 +39,7 @@ namespace mamba::util std::size_t left_child = 0; std::size_t right_child = 0; - // TODO: only use the `= default` implementation of `operator==` when we will use C++20. + // TODO(C++20): replace by the `= default` implementation of `operator==` [[nodiscard]] auto operator==(const branch_node& other) const -> bool { return data == other.data // @@ -103,7 +103,7 @@ namespace mamba::util [[nodiscard]] auto right(idx_type idx) const -> idx_type; [[nodiscard]] auto root() const -> idx_type; - // TODO: only use the `= default` implementation of `operator==` when we will use C++20. + // TODO(C++20): replace by the `= default` implementation of `operator==` [[nodiscard]] auto operator==(const flat_binary_tree& other) const -> bool { return m_nodes == other.m_nodes && m_root == other.m_root; diff --git a/libmamba/include/mamba/util/flat_bool_expr_tree.hpp b/libmamba/include/mamba/util/flat_bool_expr_tree.hpp index 79c52cf778..abab3921ae 100644 --- a/libmamba/include/mamba/util/flat_bool_expr_tree.hpp +++ b/libmamba/include/mamba/util/flat_bool_expr_tree.hpp @@ -173,7 +173,7 @@ namespace mamba::util template void infix_for_each(UnaryFunc&& func) const; - // TODO: only use the `= default` implementation of `operator==` when we will use C++20. + // TODO(C++20): replace by the `= default` implementation of `operator==` [[nodiscard]] auto operator==(const self_type& other) const -> bool { return m_tree == other.m_tree;