diff --git a/include/yaml-cpp/value/detail/node_data.h b/include/yaml-cpp/value/detail/node_data.h index ab5de66..44287b0 100644 --- a/include/yaml-cpp/value/detail/node_data.h +++ b/include/yaml-cpp/value/detail/node_data.h @@ -41,6 +41,9 @@ namespace YAML node& get(node& key, shared_memory_holder pMemory); bool remove(node& key, shared_memory_holder pMemory); + public: + static std::string empty_scalar; + private: void convert_sequence_to_map(shared_memory_holder pMemory); diff --git a/include/yaml-cpp/value/detail/node_ref.h b/include/yaml-cpp/value/detail/node_ref.h index 84dbbdb..fca208c 100644 --- a/include/yaml-cpp/value/detail/node_ref.h +++ b/include/yaml-cpp/value/detail/node_ref.h @@ -19,27 +19,30 @@ namespace YAML class node_ref: private boost::noncopyable { public: - node_ref(): m_pData(new node_data) {} + node_ref() {} - ValueType::value type() const { return m_pData->type(); } - const std::string& scalar() const { return m_pData->scalar(); } + ValueType::value type() const { return m_pData ? m_pData->type() : ValueType::Undefined; } + const std::string& scalar() const { return m_pData ? m_pData->scalar() : node_data::empty_scalar; } void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; } - void set_type(ValueType::value type) { m_pData->set_type(type); } - void set_null() { m_pData->set_null(); } - void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); } + void set_type(ValueType::value type) { ensure_data_exists(); m_pData->set_type(type); } + void set_null() { ensure_data_exists(); m_pData->set_null(); } + void set_scalar(const std::string& scalar) { ensure_data_exists(); m_pData->set_scalar(scalar); } - void append(node& node, shared_memory_holder pMemory) { m_pData->append(node, pMemory); } + void append(node& node, shared_memory_holder pMemory) { ensure_data_exists(); m_pData->append(node, pMemory); } // indexing - template node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast(*m_pData).get(key, pMemory); } - template node& get(const Key& key, shared_memory_holder pMemory) { return m_pData->get(key, pMemory); } - template bool remove(const Key& key, shared_memory_holder pMemory) { return m_pData->remove(key, pMemory); } + template node& get(const Key& key, shared_memory_holder pMemory) const { return m_pData ? static_cast(*m_pData).get(key, pMemory) : pMemory->create_node(); } + template node& get(const Key& key, shared_memory_holder pMemory) { ensure_data_exists(); return m_pData->get(key, pMemory); } + template bool remove(const Key& key, shared_memory_holder pMemory) { return m_pData ? m_pData->remove(key, pMemory) : false; } - node& get(node& key, shared_memory_holder pMemory) const { return static_cast(*m_pData).get(key, pMemory); } - node& get(node& key, shared_memory_holder pMemory) { return m_pData->get(key, pMemory); } - bool remove(node& key, shared_memory_holder pMemory) { return m_pData->remove(key, pMemory); } + node& get(node& key, shared_memory_holder pMemory) const { return m_pData ? static_cast(*m_pData).get(key, pMemory) : pMemory->create_node(); } + node& get(node& key, shared_memory_holder pMemory) { ensure_data_exists(); return m_pData->get(key, pMemory); } + bool remove(node& key, shared_memory_holder pMemory) { return m_pData ? m_pData->remove(key, pMemory) : false; } + + private: + void ensure_data_exists() { if(!m_pData) m_pData.reset(new node_data); } private: shared_node_data m_pData; diff --git a/include/yaml-cpp/value/impl.h b/include/yaml-cpp/value/impl.h index 071b76d..7bf6edc 100644 --- a/include/yaml-cpp/value/impl.h +++ b/include/yaml-cpp/value/impl.h @@ -15,7 +15,6 @@ namespace YAML { inline Value::Value(): m_pMemory(new detail::memory_holder), m_pNode(&m_pMemory->create_node()) { - m_pNode->set_null(); } inline Value::Value(ValueType::value type): m_pMemory(new detail::memory_holder), m_pNode(&m_pMemory->create_node()) diff --git a/src/value/detail/node_data.cpp b/src/value/detail/node_data.cpp index 5107811..cb85c77 100644 --- a/src/value/detail/node_data.cpp +++ b/src/value/detail/node_data.cpp @@ -8,6 +8,8 @@ namespace YAML { namespace detail { + std::string node_data::empty_scalar; + node_data::node_data(): m_isDefined(false), m_type(ValueType::Null) { }