My Project
impl.h
1 #ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
2 #define NODE_IMPL_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/exceptions.h"
11 #include "yaml-cpp/node/detail/memory.h"
12 #include "yaml-cpp/node/detail/node.h"
13 #include "yaml-cpp/node/iterator.h"
14 #include "yaml-cpp/node/node.h"
15 #include <sstream>
16 #include <string>
17 
18 namespace YAML {
19 inline Node::Node()
20  : m_isValid(true), m_invalidKey{}, m_pMemory(nullptr), m_pNode(nullptr) {}
21 
22 inline Node::Node(NodeType::value type)
23  : m_isValid(true),
24  m_invalidKey{},
25  m_pMemory(std::make_shared<detail::memory_holder>()),
26  m_pNode(&m_pMemory->create_node()) {
27  m_pNode->set_type(type);
28 }
29 
30 template <typename T>
31 inline Node::Node(const T& rhs)
32  : m_isValid(true),
33  m_invalidKey{},
34  m_pMemory(std::make_shared<detail::memory_holder>()),
35  m_pNode(&m_pMemory->create_node()) {
36  Assign(rhs);
37 }
38 
39 inline Node::Node(const detail::iterator_value& rhs)
40  : m_isValid(rhs.m_isValid),
41  m_invalidKey(rhs.m_invalidKey),
42  m_pMemory(rhs.m_pMemory),
43  m_pNode(rhs.m_pNode) {}
44 
45 inline Node::Node(const Node&) = default;
46 
47 inline Node::Node(Zombie)
48  : m_isValid(false), m_invalidKey{}, m_pMemory{}, m_pNode(nullptr) {}
49 
50 inline Node::Node(Zombie, const std::string& key)
51  : m_isValid(false), m_invalidKey(key), m_pMemory{}, m_pNode(nullptr) {}
52 
53 inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory)
54  : m_isValid(true), m_invalidKey{}, m_pMemory(pMemory), m_pNode(&node) {}
55 
56 inline Node::~Node() = default;
57 
58 inline void Node::EnsureNodeExists() const {
59  if (!m_isValid)
60  throw InvalidNode(m_invalidKey);
61  if (!m_pNode) {
62  m_pMemory.reset(new detail::memory_holder);
63  m_pNode = &m_pMemory->create_node();
64  m_pNode->set_null();
65  }
66 }
67 
68 inline void Node::Invalidate() {
69  m_isValid = false;
70  m_pNode = nullptr;
71  m_pMemory = nullptr;
72 }
73 
74 inline bool Node::IsDefined() const {
75  if (!m_isValid) {
76  return false;
77  }
78  return m_pNode ? m_pNode->is_defined() : true;
79 }
80 
81 inline Mark Node::Mark() const {
82  if (!m_isValid) {
83  throw InvalidNode(m_invalidKey);
84  }
85  return m_pNode ? m_pNode->mark() : Mark::null_mark();
86 }
87 
88 inline NodeType::value Node::Type() const {
89  if (!m_isValid)
90  throw InvalidNode(m_invalidKey);
91  return m_pNode ? m_pNode->type() : NodeType::Null;
92 }
93 
94 // access
95 
96 // template helpers
97 template <typename T, typename S>
98 struct as_if {
99  explicit as_if(const Node& node_) : node(node_) {}
100  const Node& node;
101 
102  T operator()(const S& fallback) const {
103  if (!node.m_pNode)
104  return fallback;
105 
106  T t = fallback;
107  if (convert<T>::decode(node, t))
108  return t;
109  return fallback;
110  }
111 };
112 
113 template <typename S>
114 struct as_if<std::string, S> {
115  explicit as_if(const Node& node_) : node(node_) {}
116  const Node& node;
117 
118  std::string operator()(const S& fallback) const {
119  if (node.Type() == NodeType::Null)
120  return "null";
121  if (node.Type() != NodeType::Scalar)
122  return fallback;
123  return node.Scalar();
124  }
125 };
126 
127 template <typename T>
128 struct as_if<T, void> {
129  explicit as_if(const Node& node_) : node(node_) {}
130  const Node& node;
131 
132  T operator()() const {
133  if (!node.m_pNode) // no fallback
134  throw InvalidNode(node.m_invalidKey);
135 
136  T t;
137  if (convert<T>::decode(node, t))
138  return t;
139  throw TypedBadConversion<T>(node.Mark());
140  }
141 };
142 
143 template <>
144 struct as_if<std::string, void> {
145  explicit as_if(const Node& node_) : node(node_) {}
146  const Node& node;
147 
148  std::string operator()() const {
149  if (node.Type() == NodeType::Undefined) // no fallback
150  throw InvalidNode(node.m_invalidKey);
151  if (node.Type() == NodeType::Null)
152  return "null";
153  if (node.Type() != NodeType::Scalar)
154  throw TypedBadConversion<std::string>(node.Mark());
155  return node.Scalar();
156  }
157 };
158 
159 // access functions
160 template <typename T>
161 inline T Node::as() const {
162  if (!m_isValid)
163  throw InvalidNode(m_invalidKey);
164  return as_if<T, void>(*this)();
165 }
166 
167 template <typename T, typename S>
168 inline T Node::as(const S& fallback) const {
169  if (!m_isValid)
170  return fallback;
171  return as_if<T, S>(*this)(fallback);
172 }
173 
174 inline const std::string& Node::Scalar() const {
175  if (!m_isValid)
176  throw InvalidNode(m_invalidKey);
177  return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar();
178 }
179 
180 YAML_ATTRIBUTE_NO_SANITIZE_ADDRESS
181 inline const std::string& Node::UninstrumentedScalarForTesting() const {
182  if (m_isValid && m_pMemory != nullptr && m_pNode != nullptr)
183  throw InvalidNode("use-after-free");
184  else
185  throw BadDereference();
186 }
187 
188 inline const std::string& Node::Tag() const {
189  if (!m_isValid)
190  throw InvalidNode(m_invalidKey);
191  return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar();
192 }
193 
194 inline void Node::SetTag(const std::string& tag) {
195  EnsureNodeExists();
196  m_pNode->set_tag(tag);
197 }
198 
199 inline EmitterStyle::value Node::Style() const {
200  if (!m_isValid)
201  throw InvalidNode(m_invalidKey);
202  return m_pNode ? m_pNode->style() : EmitterStyle::Default;
203 }
204 
205 inline void Node::SetStyle(EmitterStyle::value style) {
206  EnsureNodeExists();
207  m_pNode->set_style(style);
208 }
209 
210 // assignment
211 inline bool Node::is(const Node& rhs) const {
212  if (!m_isValid || !rhs.m_isValid)
213  throw InvalidNode(m_invalidKey);
214  if (!m_pNode || !rhs.m_pNode)
215  return false;
216  return m_pNode->is(*rhs.m_pNode);
217 }
218 
219 template <typename T>
220 inline Node& Node::operator=(const T& rhs) {
221  Assign(rhs);
222  return *this;
223 }
224 
225 inline Node& Node::operator=(const Node& rhs) {
226  if (is(rhs))
227  return *this;
228  AssignNode(rhs);
229  return *this;
230 }
231 
232 inline void Node::reset(const YAML::Node& rhs) {
233  if (!m_isValid || !rhs.m_isValid)
234  throw InvalidNode(m_invalidKey);
235  m_pMemory = rhs.m_pMemory;
236  m_pNode = rhs.m_pNode;
237 }
238 
239 template <typename T>
240 inline void Node::Assign(const T& rhs) {
241  if (!m_isValid)
242  throw InvalidNode(m_invalidKey);
243  AssignData(convert<T>::encode(rhs));
244 }
245 
246 template <>
247 inline void Node::Assign(const std::string& rhs) {
248  EnsureNodeExists();
249  m_pNode->set_scalar(rhs);
250 }
251 
252 inline void Node::Assign(const char* rhs) {
253  EnsureNodeExists();
254  m_pNode->set_scalar(rhs);
255 }
256 
257 inline void Node::Assign(char* rhs) {
258  EnsureNodeExists();
259  m_pNode->set_scalar(rhs);
260 }
261 
262 inline void Node::AssignData(const Node& rhs) {
263  EnsureNodeExists();
264  rhs.EnsureNodeExists();
265 
266  m_pNode->set_data(*rhs.m_pNode);
267  m_pMemory->merge(*rhs.m_pMemory);
268 }
269 
270 inline void Node::AssignNode(const Node& rhs) {
271  if (!m_isValid)
272  throw InvalidNode(m_invalidKey);
273  rhs.EnsureNodeExists();
274 
275  if (!m_pNode) {
276  m_pNode = rhs.m_pNode;
277  m_pMemory = rhs.m_pMemory;
278  return;
279  }
280 
281  m_pNode->set_ref(*rhs.m_pNode);
282  m_pMemory->merge(*rhs.m_pMemory);
283  m_pNode = rhs.m_pNode;
284 }
285 
286 // size/iterator
287 inline std::size_t Node::size() const {
288  if (!m_isValid)
289  throw InvalidNode(m_invalidKey);
290  return m_pNode ? m_pNode->size() : 0;
291 }
292 
293 inline const_iterator Node::begin() const {
294  if (!m_isValid)
295  return const_iterator();
296  return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory)
297  : const_iterator();
298 }
299 
300 inline iterator Node::begin() {
301  if (!m_isValid)
302  return iterator();
303  return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator();
304 }
305 
306 inline const_iterator Node::end() const {
307  if (!m_isValid)
308  return const_iterator();
309  return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator();
310 }
311 
312 inline iterator Node::end() {
313  if (!m_isValid)
314  return iterator();
315  return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator();
316 }
317 
318 // sequence
319 template <typename T>
320 inline void Node::push_back(const T& rhs) {
321  if (!m_isValid)
322  throw InvalidNode(m_invalidKey);
323  push_back(Node(rhs));
324 }
325 
326 inline void Node::push_back(const Node& rhs) {
327  EnsureNodeExists();
328  rhs.EnsureNodeExists();
329 
330  m_pNode->push_back(*rhs.m_pNode, m_pMemory);
331  m_pMemory->merge(*rhs.m_pMemory);
332 }
333 
334 template<typename Key>
335 std::string key_to_string(const Key& key) {
337 }
338 
339 // indexing
340 template <typename Key>
341 inline const Node Node::operator[](const Key& key) const {
342  EnsureNodeExists();
343  detail::node* value =
344  static_cast<const detail::node&>(*m_pNode).get(key, m_pMemory);
345  if (!value) {
346  return Node(ZombieNode, key_to_string(key));
347  }
348  return Node(*value, m_pMemory);
349 }
350 
351 template <typename Key>
352 inline Node Node::operator[](const Key& key) {
353  EnsureNodeExists();
354  detail::node& value = m_pNode->get(key, m_pMemory);
355  return Node(value, m_pMemory);
356 }
357 
358 template <typename Key>
359 inline bool Node::remove(const Key& key) {
360  EnsureNodeExists();
361  return m_pNode->remove(key, m_pMemory);
362 }
363 
364 inline const Node Node::operator[](const Node& key) const {
365  EnsureNodeExists();
366  key.EnsureNodeExists();
367  m_pMemory->merge(*key.m_pMemory);
368  detail::node* value =
369  static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory);
370  if (!value) {
371  return Node(ZombieNode, key_to_string(key));
372  }
373  return Node(*value, m_pMemory);
374 }
375 
376 inline Node Node::operator[](const Node& key) {
377  EnsureNodeExists();
378  key.EnsureNodeExists();
379  m_pMemory->merge(*key.m_pMemory);
380  detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory);
381  return Node(value, m_pMemory);
382 }
383 
384 inline bool Node::remove(const Node& key) {
385  EnsureNodeExists();
386  key.EnsureNodeExists();
387  return m_pNode->remove(*key.m_pNode, m_pMemory);
388 }
389 
390 // map
391 template <typename Key, typename Value>
392 inline void Node::force_insert(const Key& key, const Value& value) {
393  EnsureNodeExists();
394  m_pNode->force_insert(key, value, m_pMemory);
395 }
396 
397 // free functions
398 inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); }
399 } // namespace YAML
400 
401 #endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
Definition: impl.h:128
Definition: iterator.h:23
Definition: exceptions.h:251
Definition: convert.h:38
Definition: node.h:20
Definition: impl.h:98
Definition: exceptions.h:233
Definition: anchor.h:12
Definition: node.h:29
Definition: exceptions.h:256
Definition: traits.h:121