diff --git a/include/yaml-cpp/node/detail/node.h b/include/yaml-cpp/node/detail/node.h index dd12332..e5b45c7 100644 --- a/include/yaml-cpp/node/detail/node.h +++ b/include/yaml-cpp/node/detail/node.h @@ -24,6 +24,8 @@ class node { }; public: + friend struct std::hash; + node() : m_pRef(new node_ref), m_dependencies{} {} node(const node&) = delete; node& operator=(const node&) = delete; diff --git a/include/yaml-cpp/node/hash.h b/include/yaml-cpp/node/hash.h new file mode 100644 index 0000000..8d5f9b0 --- /dev/null +++ b/include/yaml-cpp/node/hash.h @@ -0,0 +1,23 @@ +#ifndef NODE_HASH_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_HASH_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#include "yaml-cpp/node/detail/node.h" +#include "yaml-cpp/node/node.h" + +namespace std { +template <> +struct hash { + size_t operator()(const YAML::detail::node& key) const noexcept { + return hash()(key.m_pRef); + } +}; + +template <> +struct hash { + size_t operator()(const YAML::Node& key) const noexcept { + return hash()(*key.m_pNode); + } +}; +} // namespace std + +#endif // NODE_HASH_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/node/node.h b/include/yaml-cpp/node/node.h index c9e9a0a..0f5861e 100644 --- a/include/yaml-cpp/node/node.h +++ b/include/yaml-cpp/node/node.h @@ -37,6 +37,7 @@ class YAML_CPP_API Node { friend class detail::iterator_base; template friend struct as_if; + friend struct std::hash; using iterator = YAML::iterator; using const_iterator = YAML::const_iterator; diff --git a/include/yaml-cpp/yaml.h b/include/yaml-cpp/yaml.h index 7f515ef..6a754ec 100644 --- a/include/yaml-cpp/yaml.h +++ b/include/yaml-cpp/yaml.h @@ -20,5 +20,6 @@ #include "yaml-cpp/node/detail/impl.h" #include "yaml-cpp/node/parse.h" #include "yaml-cpp/node/emit.h" +#include "yaml-cpp/node/hash.h" #endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/test/node/node_test.cpp b/test/node/node_test.cpp index 4f577c8..e2c434e 100644 --- a/test/node/node_test.cpp +++ b/test/node/node_test.cpp @@ -3,6 +3,7 @@ #include "yaml-cpp/node/convert.h" #include "yaml-cpp/node/detail/impl.h" #include "yaml-cpp/node/emit.h" +#include "yaml-cpp/node/hash.h" #include "yaml-cpp/node/impl.h" #include "yaml-cpp/node/iterator.h" @@ -645,6 +646,17 @@ TEST(NodeTest, AccessNonexistentKeyOnConstNode) { ASSERT_FALSE(other["5"]); } +TEST(NodeTest, NodeIsHashable) { + YAML::Node node1(YAML::NodeType::value::Null); + YAML::Node node2(YAML::NodeType::value::Null); + YAML::Node node3 = node1; + std::hash hash_func; + auto node1_digest = hash_func(node1); + ASSERT_EQ(hash_func(node1), node1_digest); + ASSERT_NE(hash_func(node2), node1_digest); + ASSERT_EQ(hash_func(node3), node1_digest); +} + class NodeEmitterTest : public ::testing::Test { protected: void ExpectOutput(const std::string& output, const Node& node) {