From bb1a816a3a57792ec7d8691a8b95e6dd9571ab30 Mon Sep 17 00:00:00 2001 From: beder Date: Sun, 11 Sep 2011 15:59:53 -0500 Subject: [PATCH] Added dependency management (to cause nodes to become defined if their children do) --- include/yaml-cpp/node/detail/node.h | 69 +++++++++++++++++++++--- include/yaml-cpp/node/detail/node_data.h | 2 + include/yaml-cpp/node/detail/node_ref.h | 2 + src/node/detail/node_data.cpp | 7 +++ 4 files changed, 72 insertions(+), 8 deletions(-) diff --git a/include/yaml-cpp/node/detail/node.h b/include/yaml-cpp/node/detail/node.h index 28ce475..41f7c51 100644 --- a/include/yaml-cpp/node/detail/node.h +++ b/include/yaml-cpp/node/detail/node.h @@ -10,6 +10,7 @@ #include "yaml-cpp/node/type.h" #include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/detail/node_ref.h" +#include #include namespace YAML @@ -24,16 +25,52 @@ namespace YAML bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; } const node_ref *ref() const { return m_pRef.get(); } + bool is_defined() const { return m_pRef->is_defined(); } NodeType::value type() const { return m_pRef->type(); } const std::string& scalar() const { return m_pRef->scalar(); } - void set_ref(const node& rhs) { m_pRef = rhs.m_pRef; } - void set_data(const node& rhs) { m_pRef->set_data(*rhs.m_pRef); } + void mark_defined() { + if(is_defined()) + return; - void set_type(NodeType::value type) { m_pRef->set_type(type); } - void set_null() { m_pRef->set_null(); } - void set_scalar(const std::string& scalar) { m_pRef->set_scalar(scalar); } + m_pRef->mark_defined(); + for(nodes::iterator it=m_dependencies.begin();it!=m_dependencies.end();++it) + (*it)->mark_defined(); + m_dependencies.clear(); + } + + void add_dependency(node& rhs) { + if(is_defined()) + rhs.mark_defined(); + else + m_dependencies.insert(&rhs); + } + + void set_ref(const node& rhs) { + if(rhs.is_defined()) + mark_defined(); + m_pRef = rhs.m_pRef; + } + void set_data(const node& rhs) { + if(rhs.is_defined()) + mark_defined(); + m_pRef->set_data(*rhs.m_pRef); + } + + void set_type(NodeType::value type) { + if(type != NodeType::Undefined) + mark_defined(); + m_pRef->set_type(type); + } + void set_null() { + mark_defined(); + m_pRef->set_null(); + } + void set_scalar(const std::string& scalar) { + mark_defined(); + m_pRef->set_scalar(scalar); + } // size/iterator std::size_t size() const { return m_pRef->size(); } @@ -45,22 +82,38 @@ namespace YAML node_iterator end() { return m_pRef->end(); } // sequence - void append(node& node, shared_memory_holder pMemory) { m_pRef->append(node, pMemory); } + void append(node& node, shared_memory_holder pMemory) { + m_pRef->append(node, pMemory); + node.add_dependency(*this); + } void insert(node& key, node& value, shared_memory_holder pMemory) { m_pRef->insert(key, value, pMemory); + key.add_dependency(*this); + value.add_dependency(*this); } // indexing template node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast(*m_pRef).get(key, pMemory); } - template node& get(const Key& key, shared_memory_holder pMemory) { return m_pRef->get(key, pMemory); } + template node& get(const Key& key, shared_memory_holder pMemory) { + node& value = m_pRef->get(key, pMemory); + value.add_dependency(*this); + return value; + } template bool remove(const Key& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); } node& get(node& key, shared_memory_holder pMemory) const { return static_cast(*m_pRef).get(key, pMemory); } - node& get(node& key, shared_memory_holder pMemory) { return m_pRef->get(key, pMemory); } + node& get(node& key, shared_memory_holder pMemory) { + node& value = m_pRef->get(key, pMemory); + key.add_dependency(*this); + value.add_dependency(*this); + return value; + } bool remove(node& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); } private: shared_node_ref m_pRef; + typedef std::set nodes; + nodes m_dependencies; }; } } diff --git a/include/yaml-cpp/node/detail/node_data.h b/include/yaml-cpp/node/detail/node_data.h index 9cdfbd0..b7d9910 100644 --- a/include/yaml-cpp/node/detail/node_data.h +++ b/include/yaml-cpp/node/detail/node_data.h @@ -24,10 +24,12 @@ namespace YAML public: node_data(); + void mark_defined(); void set_type(NodeType::value type); void set_null(); void set_scalar(const std::string& scalar); + bool is_defined() const { return m_isDefined; } NodeType::value type() const { return m_isDefined ? m_type : NodeType::Undefined; } const std::string& scalar() const { return m_scalar; } diff --git a/include/yaml-cpp/node/detail/node_ref.h b/include/yaml-cpp/node/detail/node_ref.h index 09cf5cf..2e3ca90 100644 --- a/include/yaml-cpp/node/detail/node_ref.h +++ b/include/yaml-cpp/node/detail/node_ref.h @@ -21,9 +21,11 @@ namespace YAML public: node_ref() {} + bool is_defined() const { return m_pData ? m_pData->is_defined() : false; } NodeType::value type() const { return m_pData ? m_pData->type() : NodeType::Undefined; } const std::string& scalar() const { return m_pData ? m_pData->scalar() : node_data::empty_scalar; } + void mark_defined() { ensure_data_exists(); m_pData->mark_defined(); } void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; } void set_type(NodeType::value type) { ensure_data_exists(); m_pData->set_type(type); } diff --git a/src/node/detail/node_data.cpp b/src/node/detail/node_data.cpp index ae7e056..04565c9 100644 --- a/src/node/detail/node_data.cpp +++ b/src/node/detail/node_data.cpp @@ -14,6 +14,13 @@ namespace YAML { } + void node_data::mark_defined() + { + if(m_type == NodeType::Undefined) + m_type = NodeType::Null; + m_isDefined = true; + } + void node_data::set_type(NodeType::value type) { if(type == NodeType::Undefined) {