1 #ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
2 #define NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
3 
4 #if defined(_MSC_VER) ||                                            \
5     (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
6      (__GNUC__ >= 4))  // GCC supports "pragma once" correctly since 3.4
7 #pragma once
8 #endif
9 
10 #include "yaml-cpp/dll.h"
11 #include "yaml-cpp/emitterstyle.h"
12 #include "yaml-cpp/node/detail/node_ref.h"
13 #include "yaml-cpp/node/ptr.h"
14 #include "yaml-cpp/node/type.h"
15 #include <set>
16 
17 namespace YAML {
18 namespace detail {
19 class node {
20  public:
node()21   node() : m_pRef(new node_ref), m_dependencies{} {}
22   node(const node&) = delete;
23   node& operator=(const node&) = delete;
24 
is(const node & rhs) const25   bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; }
ref() const26   const node_ref* ref() const { return m_pRef.get(); }
27 
is_defined() const28   bool is_defined() const { return m_pRef->is_defined(); }
mark() const29   const Mark& mark() const { return m_pRef->mark(); }
type() const30   NodeType::value type() const { return m_pRef->type(); }
31 
scalar() const32   const std::string& scalar() const { return m_pRef->scalar(); }
tag() const33   const std::string& tag() const { return m_pRef->tag(); }
style() const34   EmitterStyle::value style() const { return m_pRef->style(); }
35 
36   template <typename T>
37   bool equals(const T& rhs, shared_memory_holder pMemory);
38   bool equals(const char* rhs, shared_memory_holder pMemory);
39 
mark_defined()40   void mark_defined() {
41     if (is_defined())
42       return;
43 
44     m_pRef->mark_defined();
45     for (nodes::iterator it = m_dependencies.begin();
46          it != m_dependencies.end(); ++it)
47       (*it)->mark_defined();
48     m_dependencies.clear();
49   }
50 
add_dependency(node & rhs)51   void add_dependency(node& rhs) {
52     if (is_defined())
53       rhs.mark_defined();
54     else
55       m_dependencies.insert(&rhs);
56   }
57 
set_ref(const node & rhs)58   void set_ref(const node& rhs) {
59     if (rhs.is_defined())
60       mark_defined();
61     m_pRef = rhs.m_pRef;
62   }
set_data(const node & rhs)63   void set_data(const node& rhs) {
64     if (rhs.is_defined())
65       mark_defined();
66     m_pRef->set_data(*rhs.m_pRef);
67   }
68 
set_mark(const Mark & mark)69   void set_mark(const Mark& mark) { m_pRef->set_mark(mark); }
70 
set_type(NodeType::value type)71   void set_type(NodeType::value type) {
72     if (type != NodeType::Undefined)
73       mark_defined();
74     m_pRef->set_type(type);
75   }
set_null()76   void set_null() {
77     mark_defined();
78     m_pRef->set_null();
79   }
set_scalar(const std::string & scalar)80   void set_scalar(const std::string& scalar) {
81     mark_defined();
82     m_pRef->set_scalar(scalar);
83   }
set_tag(const std::string & tag)84   void set_tag(const std::string& tag) {
85     mark_defined();
86     m_pRef->set_tag(tag);
87   }
88 
89   // style
set_style(EmitterStyle::value style)90   void set_style(EmitterStyle::value style) {
91     mark_defined();
92     m_pRef->set_style(style);
93   }
94 
95   // size/iterator
size() const96   std::size_t size() const { return m_pRef->size(); }
97 
begin() const98   const_node_iterator begin() const {
99     return static_cast<const node_ref&>(*m_pRef).begin();
100   }
begin()101   node_iterator begin() { return m_pRef->begin(); }
102 
end() const103   const_node_iterator end() const {
104     return static_cast<const node_ref&>(*m_pRef).end();
105   }
end()106   node_iterator end() { return m_pRef->end(); }
107 
108   // sequence
push_back(node & input,shared_memory_holder pMemory)109   void push_back(node& input, shared_memory_holder pMemory) {
110     m_pRef->push_back(input, pMemory);
111     input.add_dependency(*this);
112   }
insert(node & key,node & value,shared_memory_holder pMemory)113   void insert(node& key, node& value, shared_memory_holder pMemory) {
114     m_pRef->insert(key, value, pMemory);
115     key.add_dependency(*this);
116     value.add_dependency(*this);
117   }
118 
119   // indexing
120   template <typename Key>
get(const Key & key,shared_memory_holder pMemory) const121   node* get(const Key& key, shared_memory_holder pMemory) const {
122     // NOTE: this returns a non-const node so that the top-level Node can wrap
123     // it, and returns a pointer so that it can be NULL (if there is no such
124     // key).
125     return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
126   }
127   template <typename Key>
get(const Key & key,shared_memory_holder pMemory)128   node& get(const Key& key, shared_memory_holder pMemory) {
129     node& value = m_pRef->get(key, pMemory);
130     value.add_dependency(*this);
131     return value;
132   }
133   template <typename Key>
remove(const Key & key,shared_memory_holder pMemory)134   bool remove(const Key& key, shared_memory_holder pMemory) {
135     return m_pRef->remove(key, pMemory);
136   }
137 
get(node & key,shared_memory_holder pMemory) const138   node* get(node& key, shared_memory_holder pMemory) const {
139     // NOTE: this returns a non-const node so that the top-level Node can wrap
140     // it, and returns a pointer so that it can be NULL (if there is no such
141     // key).
142     return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
143   }
get(node & key,shared_memory_holder pMemory)144   node& get(node& key, shared_memory_holder pMemory) {
145     node& value = m_pRef->get(key, pMemory);
146     key.add_dependency(*this);
147     value.add_dependency(*this);
148     return value;
149   }
remove(node & key,shared_memory_holder pMemory)150   bool remove(node& key, shared_memory_holder pMemory) {
151     return m_pRef->remove(key, pMemory);
152   }
153 
154   // map
155   template <typename Key, typename Value>
force_insert(const Key & key,const Value & value,shared_memory_holder pMemory)156   void force_insert(const Key& key, const Value& value,
157                     shared_memory_holder pMemory) {
158     m_pRef->force_insert(key, value, pMemory);
159   }
160 
161  private:
162   shared_node_ref m_pRef;
163   typedef std::set<node*> nodes;
164   nodes m_dependencies;
165 };
166 }  // namespace detail
167 }  // namespace YAML
168 
169 #endif  // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
170