From 248b18a2d04867d53d4f826f15b348b0ddaaadad Mon Sep 17 00:00:00 2001 From: Jesse Beder Date: Tue, 6 Sep 2011 23:11:38 -0500 Subject: [PATCH] Sketched more of the implementation --- CMakeLists.txt | 6 +- include/yaml-cpp/value/detail/memory.h | 71 ++++++++++ include/yaml-cpp/value/detail/node.h | 44 ++++++ include/yaml-cpp/value/detail/nodedata.h | 0 include/yaml-cpp/value/impl.h | 168 +++++++++++++++++++++++ include/yaml-cpp/value/ptr.h | 27 ++++ include/yaml-cpp/value/value.h | 29 +++- 7 files changed, 339 insertions(+), 6 deletions(-) create mode 100644 include/yaml-cpp/value/detail/memory.h create mode 100644 include/yaml-cpp/value/detail/node.h create mode 100644 include/yaml-cpp/value/detail/nodedata.h create mode 100644 include/yaml-cpp/value/impl.h create mode 100644 include/yaml-cpp/value/ptr.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b34518d..c8ac8dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,7 +56,11 @@ option(MSVC_STHREADED_RT "MSVC: Build with single-threaded static runtime libs ( ### Sources, headers, directories and libs ### file(GLOB sources "src/[a-zA-Z]*.cpp") -file(GLOB public_headers "include/yaml-cpp/[a-zA-Z]*.h") +file(GLOB public_headers + "include/yaml-cpp/[a-zA-Z]*.h" + "include/yaml-cpp/value/[a-zA-Z]*.h" + "include/yaml-cpp/value/detail/[a-zA-Z]*.h" +) file(GLOB private_headers "src/[a-zA-Z]*.h") if(YAML_CPP_BUILD_CONTRIB) diff --git a/include/yaml-cpp/value/detail/memory.h b/include/yaml-cpp/value/detail/memory.h new file mode 100644 index 0000000..2d35b08 --- /dev/null +++ b/include/yaml-cpp/value/detail/memory.h @@ -0,0 +1,71 @@ +#ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/value/ptr.h" +#include +#include + +namespace YAML +{ + namespace detail + { + class memory; + + class memory_holder { + public: + memory_holder(); + + shared_node create_node(); + void merge(memory_holder& rhs); + + private: + boost::shared_ptr m_pMemory; + }; + + class memory { + public: + shared_node create_node(); + void merge(const memory& rhs); + + private: + typedef std::set Nodes; + Nodes m_nodes; + }; + + inline memory_holder::memory_holder(): m_pMemory(new memory) + { + } + + inline shared_node memory_holder::create_node() + { + return m_pMemory->create_node(); + } + + inline void memory_holder::merge(memory_holder& rhs) + { + if(m_pMemory == rhs.m_pMemory) + return; + + m_pMemory->merge(*rhs.m_pMemory); + rhs.m_pMemory = m_pMemory; + } + + shared_node memory::create_node() + { + shared_node pNode(new node); + m_nodes.insert(pNode); + return pNode; + } + + inline void memory::merge(const memory& rhs) + { + m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end()); + } + } +} + +#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/value/detail/node.h b/include/yaml-cpp/value/detail/node.h new file mode 100644 index 0000000..49c4422 --- /dev/null +++ b/include/yaml-cpp/value/detail/node.h @@ -0,0 +1,44 @@ +#ifndef VALUE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/value/ptr.h" + +namespace YAML +{ + namespace detail + { + class node + { + public: + node(); + + void assign_data(const node& rhs); + void set_scalar(const std::string& data); + + private: + shared_node_data m_pData; + }; + + inline node::node() + { + } + + inline void node::assign_data(const node& rhs) + { + m_pData = rhs.m_pData; + } + + inline void node::set_scalar(const std::string& data) + { + m_pData.reset(new node_data(data)); + } + } +} + +#endif // VALUE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/value/detail/nodedata.h b/include/yaml-cpp/value/detail/nodedata.h new file mode 100644 index 0000000..e69de29 diff --git a/include/yaml-cpp/value/impl.h b/include/yaml-cpp/value/impl.h new file mode 100644 index 0000000..d813d93 --- /dev/null +++ b/include/yaml-cpp/value/impl.h @@ -0,0 +1,168 @@ +#ifndef VALUE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + + +#include "yaml-cpp/value/value.h" + +namespace YAML +{ + inline Value::Value(): m_pMemory(new detail::memory_holder) + { + } + + template + inline Value::Value(const T& rhs): m_pMemory(new detail::memory_holder) + { + operator=(rhs); + } + + inline Value::Value(const Value& rhs): m_pNode(rhs.m_pNode), m_pMemory(rhs.m_pMemory) + { + } + + // access + template + inline const T Value::as() const + { + T t; + if(convert(*this, t)) + return t; + throw std::runtime_error("Unable to convert to type"); + } + + // assignment + template + inline Value& Value::operator=(const T& rhs) + { + AssignData(convert(rhs)); + return *this; + } + + template<> + inline Value& Value::operator=(const std::string& rhs) + { + EnsureNodeExists(); + m_pNode->set_scalar(rhs); + } + + inline Value& Value::operator=(const Value& rhs) + { + if(is(*this, rhs)) + return *this; + AssignNode(rhs); + } + + void Value::EnsureNodeExists() + { + if(!m_pNode) + m_pNode = m_pMemory->create_node(); + } + + void Value::AssignData(const Value& rhs) + { + EnsureNodeExists(); + if(!rhs.m_pNode) + throw std::runtime_error("Tried to assign an undefined value"); + + m_pNode->assign_data(*rhs.m_pNode); + m_pMemory->merge(*rhs.m_pMemory); + } + + void Value::AssignNode(const Value& rhs) + { + m_pNode = rhs.m_pNode; + m_pMemory->merge(*rhs.m_pMemory); + } + + // size/iterator + inline std::size_t Value::size() const + { + } + + inline const_iterator Value::begin() const + { + } + + inline iterator Value::begin() + { + } + + inline const_iterator Value::end() const + { + } + + inline iterator Value::end() + { + } + + // indexing + template + inline const Value Value::operator[](const Key& key) const + { + } + + template + inline Value Value::operator[](const Key& key) + { + } + + template + inline bool Value::remove(const Key& key) + { + } + + inline const Value Value::operator[](const Value& key) const + { + } + + inline Value Value::operator[](const Value& key) + { + } + + inline bool Value::remove(const Value& key) + { + } + + inline const Value Value::operator[](const char *key) const + { + } + + inline Value Value::operator[](const char *key) + { + } + + inline bool Value::remove(const char *key) + { + } + + inline const Value Value::operator[](char *key) const + { + } + + inline Value Value::operator[](char *key) + { + } + + inline bool Value::remove(char *key) + { + } + + // free functions + inline int compare(const Value& lhs, const Value& rhs) + { + } + + inline bool operator<(const Value& lhs, const Value& rhs) + { + } + + inline bool is(const Value& lhs, const Value& rhs) + { + } +} + +#endif // VALUE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/value/ptr.h b/include/yaml-cpp/value/ptr.h new file mode 100644 index 0000000..7a9d35e --- /dev/null +++ b/include/yaml-cpp/value/ptr.h @@ -0,0 +1,27 @@ +#ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + + +#include "yaml-cpp/dll.h" +#include + +namespace YAML +{ + namespace detail { + class node; + class node_data; + class memory; + class memory_holder; + + typedef boost::shared_ptr shared_node; + typedef boost::shared_ptr shared_node_data; + typedef boost::shared_ptr shared_memory_holder; + typedef boost::shared_ptr shared_memory; + } +} + +#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/value/value.h b/include/yaml-cpp/value/value.h index f7c1b2c..d3a4146 100644 --- a/include/yaml-cpp/value/value.h +++ b/include/yaml-cpp/value/value.h @@ -1,5 +1,5 @@ -#ifndef VALUE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#ifndef VALUE_VALUE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_VALUE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #pragma once @@ -7,7 +7,7 @@ #include "yaml-cpp/dll.h" -#include "yaml-cpp/node_ptr.h" +#include "yaml-cpp/value/ptr.h" namespace YAML { @@ -18,6 +18,8 @@ namespace YAML public: Value(); explicit Value(ValueType::value type); + explicit template Value(const T& rhs); + explicit Value(const Value& rhs); ~Value(); ValueType::value Type() const; @@ -26,7 +28,7 @@ namespace YAML template const T as() const; // assignment - template Value& operator=(const T& rhs) const; + template Value& operator=(const T& rhs); Value& operator=(const Value& rhs); // size/iterator @@ -54,12 +56,29 @@ namespace YAML const Value operator[](char *key) const; Value operator[](char *key); bool remove(char *key); + + private: + void EnsureNodeExists(); + void AssignData(const Value& rhs); + void AssignNode(const Value& rhs); + + private: + shared_node m_pNode; + shared_memory_holder m_pMemory; }; int compare(const Value& lhs, const Value& rhs); bool operator<(const Value& lhs, const Value& rhs); bool is(const Value& lhs, const Value& rhs); + + template + Value convert(const T& rhs); + + template + bool convert(const Value& value, T& rhs); } -#endif // VALUE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#include "yaml-cpp/value/impl.h" + +#endif // VALUE_VALUE_H_62B23520_7C8E_11DE_8A39_0800200C9A66