mirror of https://github.com/mamba-org/mamba.git
Make more classes hashable and comparable (#3363)
Signed-off-by: Julien Jerphanion <git@jjerphan.xyz> Co-authored-by: Klaim <Klaim@users.noreply.github.com>
This commit is contained in:
parent
154012f256
commit
b09f1d162f
|
@ -15,6 +15,7 @@
|
|||
#include <fmt/format.h>
|
||||
|
||||
#include "mamba/specs/error.hpp"
|
||||
#include "mamba/util/tuple_hash.hpp"
|
||||
|
||||
namespace mamba::specs
|
||||
{
|
||||
|
@ -124,6 +125,17 @@ namespace mamba::specs
|
|||
*/
|
||||
[[nodiscard]] auto contains(BuildNumber point) const -> bool;
|
||||
|
||||
// TODO(C++20): replace by the `= default` implementation of `operator==`
|
||||
[[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 +167,13 @@ struct fmt::formatter<mamba::specs::BuildNumberSpec>
|
|||
format(const ::mamba::specs::BuildNumberSpec& spec, format_context& ctx) -> decltype(ctx.out());
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std::hash<mamba::specs::BuildNumberSpec>
|
||||
{
|
||||
auto operator()(const mamba::specs::BuildNumberSpec& spec) const -> std::size_t
|
||||
{
|
||||
return mamba::util::hash_vals(spec.str());
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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,17 @@ namespace mamba::specs
|
|||
|
||||
[[nodiscard]] auto str() const -> const std::string&;
|
||||
|
||||
// TODO(C++20): replace by the `= default` implementation of `operator==`
|
||||
[[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 +78,13 @@ struct fmt::formatter<mamba::specs::ChimeraStringSpec>
|
|||
format(const ::mamba::specs::ChimeraStringSpec& spec, format_context& ctx) -> decltype(ctx.out());
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std::hash<mamba::specs::ChimeraStringSpec>
|
||||
{
|
||||
auto operator()(const mamba::specs::ChimeraStringSpec& spec) const -> std::size_t
|
||||
{
|
||||
return mamba::util::hash_vals(spec.str());
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,17 @@ namespace mamba::specs
|
|||
|
||||
[[nodiscard]] auto str() const -> const std::string&;
|
||||
|
||||
// TODO(C++20): replace by the `= default` implementation of `operator==`
|
||||
[[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 +68,13 @@ struct fmt::formatter<mamba::specs::GlobSpec>
|
|||
auto format(const ::mamba::specs::GlobSpec& spec, format_context& ctx) -> decltype(ctx.out());
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std::hash<mamba::specs::GlobSpec>
|
||||
{
|
||||
auto operator()(const mamba::specs::GlobSpec& spec) const -> std::size_t
|
||||
{
|
||||
return std::hash<std::string>{}(spec.str());
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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,28 @@ namespace mamba::specs
|
|||
*/
|
||||
[[nodiscard]] auto contains_except_channel(const PackageInfo& pkg) const -> bool;
|
||||
|
||||
// TODO(C++20): replace by the `= default` implementation of `operator==`
|
||||
[[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 //
|
||||
&& m_extra == other.m_extra;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto operator!=(const MatchSpec& other) const -> bool
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
auto extra_members_hash() const -> std::size_t
|
||||
{
|
||||
return mamba::util::hash_vals(m_extra);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
struct ExtraMembers
|
||||
|
@ -150,7 +173,29 @@ namespace mamba::specs
|
|||
std::string features = {};
|
||||
string_set track_features = {};
|
||||
bool optional = false;
|
||||
|
||||
// TODO(C++20): replace by the `= default` implementation of `operator==`
|
||||
[[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<ExtraMembers>;
|
||||
};
|
||||
friend struct std::hash<MatchSpec::ExtraMembers>;
|
||||
|
||||
std::optional<UnresolvedChannel> m_channel;
|
||||
VersionSpec m_version;
|
||||
|
@ -255,4 +300,41 @@ namespace mamba::specs
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
struct std::hash<mamba::specs::MatchSpec>
|
||||
{
|
||||
auto operator()(const mamba::specs::MatchSpec& spec) const -> std::size_t
|
||||
{
|
||||
return mamba::util::hash_vals(
|
||||
spec.channel(),
|
||||
spec.version(),
|
||||
spec.name(),
|
||||
spec.build_string(),
|
||||
spec.name_space(),
|
||||
spec.build_number(),
|
||||
spec.extra_members_hash()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std::hash<mamba::specs::MatchSpec::ExtraMembers>
|
||||
{
|
||||
auto operator()(const mamba::specs::MatchSpec::ExtraMembers& extra) const -> std::size_t
|
||||
{
|
||||
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
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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<mamba::specs::PackageInfo>
|
||||
{
|
||||
auto operator()(const mamba::specs::PackageInfo& pkg) const -> std::size_t
|
||||
{
|
||||
auto seed = std::size_t(0);
|
||||
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(),
|
||||
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_vals(seed, pkg.noarch, pkg.size, pkg.timestamp, pkg.package_type);
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -47,6 +47,18 @@ namespace mamba::specs
|
|||
|
||||
[[nodiscard]] auto str() const -> const std::string&;
|
||||
|
||||
// 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
|
||||
&& m_pattern.flags() == other.m_pattern.flags();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto operator!=(const RegexSpec& other) const -> bool
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::regex m_pattern;
|
||||
|
|
|
@ -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,18 @@ 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 +150,13 @@ struct fmt::formatter<mamba::specs::UnresolvedChannel>
|
|||
auto format(const UnresolvedChannel& uc, format_context& ctx) const -> format_context::iterator;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std::hash<mamba::specs::UnresolvedChannel>
|
||||
{
|
||||
auto operator()(const mamba::specs::UnresolvedChannel& uc) const -> std::size_t
|
||||
{
|
||||
return mamba::util::hash_vals(uc.location(), uc.platform_filters(), static_cast<int>(uc.type()));
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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,23 @@ struct fmt::formatter<mamba::specs::VersionSpec>
|
|||
|
||||
auto format(const ::mamba::specs::VersionSpec& spec, format_context& ctx) -> decltype(ctx.out());
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std::hash<mamba::specs::VersionPredicate>
|
||||
{
|
||||
auto operator()(const mamba::specs::VersionPredicate& pred) const -> std::size_t
|
||||
{
|
||||
return mamba::util::hash_vals(pred.str());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std::hash<mamba::specs::VersionSpec>
|
||||
{
|
||||
auto operator()(const mamba::specs::VersionSpec& spec) const -> std::size_t
|
||||
{
|
||||
return mamba::util::hash_vals(spec.str());
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -38,6 +38,19 @@ namespace mamba::util
|
|||
branch_type data;
|
||||
std::size_t left_child = 0;
|
||||
std::size_t right_child = 0;
|
||||
|
||||
// TODO(C++20): replace by the `= default` implementation of `operator==`
|
||||
[[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 +103,17 @@ namespace mamba::util
|
|||
[[nodiscard]] auto right(idx_type idx) const -> idx_type;
|
||||
[[nodiscard]] auto root() const -> idx_type;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto operator!=(const flat_binary_tree& other) const -> bool
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
void dfs_raw(Visitor&& visitor, idx_type start) const;
|
||||
|
||||
|
|
|
@ -173,6 +173,17 @@ namespace mamba::util
|
|||
template <typename UnaryFunc>
|
||||
void infix_for_each(UnaryFunc&& func) const;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto operator!=(const self_type& other) const -> bool
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
using idx_type = typename tree_type::idx_type;
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "mamba/util/tuple_hash.hpp"
|
||||
|
||||
namespace mamba::util
|
||||
{
|
||||
|
||||
|
@ -557,4 +559,14 @@ namespace mamba::util
|
|||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Key, typename Compare, typename Allocator>
|
||||
struct std::hash<mamba::util::flat_set<Key, Compare, Allocator>>
|
||||
{
|
||||
auto operator()(const mamba::util::flat_set<Key, Compare, Allocator>& set) const -> std::size_t
|
||||
{
|
||||
return mamba::util::hash_vals(set);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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<element_type> m_ptr = nullptr;
|
||||
|
@ -236,4 +250,18 @@ namespace mamba::util
|
|||
m_ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct std::hash<mamba::util::heap_optional<T>>
|
||||
{
|
||||
std::size_t operator()(const mamba::util::heap_optional<T>& opt) const
|
||||
{
|
||||
if (opt.has_value())
|
||||
{
|
||||
return std::hash<T>{}(*opt);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue