use custom shared pointer
- simplify memory management
This commit is contained in:
parent
c8b1e9d7c5
commit
7a52c16563
@ -15,7 +15,6 @@
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
struct iterator_value;
|
||||
|
||||
template <typename V>
|
||||
class iterator_base : public std::iterator<std::forward_iterator_tag, V,
|
||||
@ -39,7 +38,7 @@ class iterator_base : public std::iterator<std::forward_iterator_tag, V,
|
||||
typedef typename iterator_base::value_type value_type;
|
||||
|
||||
public:
|
||||
iterator_base() : m_iterator(), m_pMemory() {}
|
||||
iterator_base() : m_iterator(), m_pMemory(nullptr) {}
|
||||
explicit iterator_base(base_type rhs, shared_memory_holder pMemory)
|
||||
: m_iterator(rhs), m_pMemory(pMemory) {}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <set>
|
||||
#include <list>
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
@ -15,31 +15,43 @@
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class node;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace YAML
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class YAML_CPP_API memory {
|
||||
|
||||
class YAML_CPP_API memory : public ref_counted {
|
||||
public:
|
||||
node& create_node();
|
||||
void merge(const memory& rhs);
|
||||
void merge(memory&& rhs);
|
||||
|
||||
memory();
|
||||
~memory();
|
||||
|
||||
private:
|
||||
typedef std::set<shared_node> Nodes;
|
||||
typedef std::list<node> Nodes;
|
||||
Nodes m_nodes;
|
||||
};
|
||||
|
||||
class YAML_CPP_API memory_holder {
|
||||
typedef ref_holder<memory> shared_memory;
|
||||
|
||||
class YAML_CPP_API memory_holder : public ref_counted {
|
||||
public:
|
||||
memory_holder() : m_pMemory(new memory) {}
|
||||
memory_holder();
|
||||
~memory_holder();
|
||||
|
||||
node& create_node() { return m_pMemory->create_node(); }
|
||||
void merge(memory_holder& rhs);
|
||||
|
||||
private:
|
||||
shared_memory m_pMemory;
|
||||
|
||||
};
|
||||
|
||||
typedef ref_holder<memory_holder> shared_memory_holder;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -12,13 +12,19 @@
|
||||
#include "yaml-cpp/node/type.h"
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
#include "yaml-cpp/node/detail/node_data.h"
|
||||
#include "yaml-cpp/node/detail/memory.h"
|
||||
#include <set>
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class node {
|
||||
|
||||
using node_data_ref = ref_holder<node_data>;
|
||||
|
||||
public:
|
||||
node() : m_pRef(new node_data) {}
|
||||
|
||||
node() : m_pRef(new node_data){}
|
||||
|
||||
node(const node&) = delete;
|
||||
node& operator=(const node&) = delete;
|
||||
|
||||
@ -37,24 +43,6 @@ class node {
|
||||
bool equals(const T& rhs, shared_memory_holder pMemory);
|
||||
bool equals(const char* rhs, shared_memory_holder pMemory);
|
||||
|
||||
void mark_defined() {
|
||||
if (is_defined())
|
||||
return;
|
||||
|
||||
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();
|
||||
@ -159,7 +147,25 @@ class node {
|
||||
}
|
||||
|
||||
private:
|
||||
shared_node_data m_pRef;
|
||||
void mark_defined() {
|
||||
if (is_defined())
|
||||
return;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
mutable node_data_ref m_pRef;
|
||||
typedef std::set<node*> nodes;
|
||||
nodes m_dependencies;
|
||||
};
|
||||
|
||||
@ -27,7 +27,7 @@ class node;
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class YAML_CPP_API node_data {
|
||||
class YAML_CPP_API node_data : public ref_counted {
|
||||
public:
|
||||
node_data();
|
||||
node_data(const node_data&) = delete;
|
||||
@ -121,6 +121,7 @@ class YAML_CPP_API node_data {
|
||||
typedef std::pair<node*, node*> kv_pair;
|
||||
typedef std::list<kv_pair> kv_pairs;
|
||||
mutable kv_pairs m_undefinedPairs;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,12 +15,16 @@
|
||||
#include <string>
|
||||
|
||||
namespace YAML {
|
||||
inline Node::Node() : m_isValid(true), m_pNode(NULL) {}
|
||||
inline Node::Node()
|
||||
: m_isValid(true),
|
||||
//m_pMemory(nullptr),
|
||||
m_pMemory(new detail::memory_holder),
|
||||
m_pNode(NULL) {}
|
||||
|
||||
inline Node::Node(NodeType::value type)
|
||||
: m_isValid(true),
|
||||
m_pMemory(new detail::memory_holder),
|
||||
m_pNode(&m_pMemory->create_node()) {
|
||||
m_pNode(&(m_pMemory->create_node())) {
|
||||
m_pNode->set_type(type);
|
||||
}
|
||||
|
||||
@ -28,7 +32,7 @@ template <typename T>
|
||||
inline Node::Node(const T& rhs)
|
||||
: m_isValid(true),
|
||||
m_pMemory(new detail::memory_holder),
|
||||
m_pNode(&m_pMemory->create_node()) {
|
||||
m_pNode(&(m_pMemory->create_node())) {
|
||||
Assign(rhs);
|
||||
}
|
||||
|
||||
@ -42,10 +46,15 @@ inline Node::Node(const Node& rhs)
|
||||
m_pMemory(rhs.m_pMemory),
|
||||
m_pNode(rhs.m_pNode) {}
|
||||
|
||||
inline Node::Node(Zombie) : m_isValid(false), m_pNode(NULL) {}
|
||||
inline Node::Node(Zombie)
|
||||
: m_isValid(false),
|
||||
m_pMemory(nullptr),
|
||||
m_pNode(NULL) {}
|
||||
|
||||
inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory)
|
||||
: m_isValid(true), m_pMemory(pMemory), m_pNode(&node) {}
|
||||
: m_isValid(true),
|
||||
m_pMemory(pMemory),
|
||||
m_pNode(&node) {}
|
||||
|
||||
inline Node::~Node() {}
|
||||
|
||||
|
||||
@ -24,6 +24,12 @@ struct iterator_value : public Node, std::pair<Node, Node> {
|
||||
std::pair<Node, Node>(Node(Node::ZombieNode), Node(Node::ZombieNode)) {}
|
||||
explicit iterator_value(const Node& key, const Node& value)
|
||||
: Node(Node::ZombieNode), std::pair<Node, Node>(key, value) {}
|
||||
|
||||
explicit iterator_value(Node&& rhs)
|
||||
: Node(std::move(rhs)),
|
||||
std::pair<Node, Node>(Node(Node::ZombieNode), Node(Node::ZombieNode)) {}
|
||||
explicit iterator_value(Node&& key, Node&& value)
|
||||
: Node(Node::ZombieNode), std::pair<Node, Node>(std::move(key), std::move(value)) {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
#include "yaml-cpp/mark.h"
|
||||
#include "yaml-cpp/node/detail/bool_type.h"
|
||||
#include "yaml-cpp/node/detail/iterator_fwd.h"
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
#include "yaml-cpp/node/detail/memory.h"
|
||||
#include "yaml-cpp/node/type.h"
|
||||
|
||||
namespace YAML {
|
||||
|
||||
@ -8,19 +8,105 @@
|
||||
#endif
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include <memory>
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class node;
|
||||
class node_data;
|
||||
class memory;
|
||||
class memory_holder;
|
||||
|
||||
typedef std::shared_ptr<node> shared_node;
|
||||
typedef std::shared_ptr<node_data> shared_node_data;
|
||||
typedef std::shared_ptr<memory_holder> shared_memory_holder;
|
||||
typedef std::shared_ptr<memory> shared_memory;
|
||||
template <typename T>
|
||||
struct ref_holder {
|
||||
~ref_holder<T>() {
|
||||
if (m_ptr)
|
||||
m_ptr->release();
|
||||
}
|
||||
ref_holder<T>(T* ptr) {
|
||||
if (ptr) {
|
||||
ptr->hold();
|
||||
}
|
||||
m_ptr = ptr;
|
||||
}
|
||||
|
||||
ref_holder<T>(const ref_holder<T>& ref) {
|
||||
if (ref.m_ptr) {
|
||||
ref.m_ptr->hold();
|
||||
}
|
||||
m_ptr = ref.m_ptr;
|
||||
}
|
||||
|
||||
ref_holder<T>(ref_holder<T>&& ref) {
|
||||
m_ptr = ref.m_ptr;
|
||||
ref.m_ptr = nullptr;
|
||||
}
|
||||
|
||||
ref_holder<T>& operator=(const ref_holder<T>& ref) {
|
||||
if (ref.m_ptr == m_ptr) {
|
||||
return *this;
|
||||
}
|
||||
if (ref.m_ptr) {
|
||||
ref.m_ptr->hold();
|
||||
}
|
||||
if (m_ptr) {
|
||||
m_ptr->release();
|
||||
}
|
||||
m_ptr = ref.m_ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ref_holder<T>& operator=(ref_holder<T>&& ref) {
|
||||
if (ref.m_ptr == m_ptr) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (m_ptr) {
|
||||
m_ptr->release();
|
||||
}
|
||||
m_ptr = ref.m_ptr;
|
||||
ref.m_ptr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const ref_holder<T>& ref) const { return m_ptr == ref.m_ptr; }
|
||||
bool operator!=(const ref_holder<T>& ref) const { return m_ptr != ref.m_ptr; }
|
||||
|
||||
const T* operator->() const { return m_ptr; }
|
||||
T* operator->() { return m_ptr; }
|
||||
|
||||
const T& operator*() const { return *m_ptr; }
|
||||
T& operator*() { return *m_ptr; }
|
||||
|
||||
const T* get() { return m_ptr; }
|
||||
|
||||
void reset(T* ptr) {
|
||||
if (ptr == m_ptr) {
|
||||
return;
|
||||
}
|
||||
if (m_ptr) {
|
||||
m_ptr->release();
|
||||
}
|
||||
if (ptr) {
|
||||
ptr->hold();
|
||||
}
|
||||
m_ptr = ptr;
|
||||
}
|
||||
|
||||
operator bool() const { return m_ptr != nullptr; }
|
||||
|
||||
private:
|
||||
T* m_ptr;
|
||||
};
|
||||
|
||||
struct ref_counted {
|
||||
|
||||
void hold() { m_refs++; }
|
||||
void release() {
|
||||
if (--m_refs == 0) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
virtual ~ref_counted() {}
|
||||
|
||||
private:
|
||||
std::size_t m_refs = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,22 +5,27 @@
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
|
||||
typedef ref_holder<node> node_ref;
|
||||
|
||||
void memory_holder::merge(memory_holder& rhs) {
|
||||
if (m_pMemory == rhs.m_pMemory)
|
||||
return;
|
||||
|
||||
m_pMemory->merge(*rhs.m_pMemory);
|
||||
m_pMemory->merge(std::move(*rhs.m_pMemory));
|
||||
rhs.m_pMemory = m_pMemory;
|
||||
}
|
||||
|
||||
node& memory::create_node() {
|
||||
shared_node pNode(new node);
|
||||
m_nodes.insert(pNode);
|
||||
return *pNode;
|
||||
m_nodes.emplace_back();
|
||||
return m_nodes.back();
|
||||
}
|
||||
|
||||
void memory::merge(const memory& rhs) {
|
||||
m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end());
|
||||
}
|
||||
void memory::merge(memory&& rhs) { m_nodes.splice(m_nodes.end(), rhs.m_nodes); }
|
||||
|
||||
memory_holder::memory_holder() : m_pMemory(new memory) {}
|
||||
memory_holder::~memory_holder() {}
|
||||
|
||||
memory::memory() {}
|
||||
memory::~memory() {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
#include "yaml-cpp/anchor.h"
|
||||
#include "yaml-cpp/emitterstyle.h"
|
||||
#include "yaml-cpp/eventhandler.h"
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
#include "yaml-cpp/node/detail/memory.h"
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
|
||||
@ -11,11 +11,12 @@
|
||||
#include <vector>
|
||||
|
||||
#include "yaml-cpp/anchor.h"
|
||||
#include "yaml-cpp/node/ptr.h"
|
||||
#include "yaml-cpp/node/detail/memory.h"
|
||||
|
||||
namespace YAML {
|
||||
namespace detail {
|
||||
class node;
|
||||
class node_data;
|
||||
} // namespace detail
|
||||
} // namespace YAML
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user