diff --git a/include/aidge/utils/DynamicAttributes.hpp b/include/aidge/utils/DynamicAttributes.hpp index 659f615193e60ea8d39228d898554395633de5ae..26cc6111dfcb6db2ed42f07fb9964a7d11527fee 100644 --- a/include/aidge/utils/DynamicAttributes.hpp +++ b/include/aidge/utils/DynamicAttributes.hpp @@ -350,6 +350,11 @@ struct DynamicAttributes::AnyUtils<py::object> : public DynamicAttributes::AnyUt inline bool operator<(const DynamicAttributes& lhs, const DynamicAttributes& rhs) { return (lhs.mAttrs < rhs.mAttrs); } + +// Combine the hashes (boost-like hash combining, see boost::hash_combine()) +inline void hash_combine(std::size_t& seed, const std::size_t& value) { + seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2); +} } namespace std { @@ -360,12 +365,21 @@ namespace std { size_t operator()(const Aidge::DynamicAttributes& attrs) const { std::size_t seed = 0; for (const auto& pair : attrs.mAttrs) { - const std::size_t key_hash = std::hash<std::string>()(pair.first); - // Combine the hashes (boost-like hash combining, see boost::hash_combine()) - seed ^= key_hash + 0x9e3779b9 + (seed << 6) + (seed >> 2); - const std::size_t value_hash = Aidge::DynamicAttributes::mAnyUtils.at(pair.second.type())->hash(pair.second); - // Combine the hashes (boost-like hash combining, see boost::hash_combine()) - seed ^= value_hash + 0x9e3779b9 + (seed << 6) + (seed >> 2); + Aidge::hash_combine(seed, std::hash<std::string>()(pair.first)); + Aidge::hash_combine(seed, Aidge::DynamicAttributes::mAnyUtils.at(pair.second.type())->hash(pair.second)); + } + return seed; + } + }; + + // General specialization of std::hash for any container that has iterators (e.g., std::vector, std::list, std::set) + template <template <typename...> class Container, typename T, typename... Args> + struct hash<Container<T, Args...>> { + std::size_t operator()(const Container<T, Args...>& iterable) const { + std::size_t seed = 0; + for (const auto& v : iterable) { + // Recursively hash the value pointed by the iterator + Aidge::hash_combine(seed, std::hash<T>()(v)); } return seed; }