Free Electron
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(new 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(new 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 bool Node::IsDefined() const {
69  if (!m_isValid) {
70  return false;
71  }
72  return m_pNode ? m_pNode->is_defined() : true;
73 }
74 
75 inline Mark Node::Mark() const {
76  if (!m_isValid) {
77  throw InvalidNode(m_invalidKey);
78  }
79  return m_pNode ? m_pNode->mark() : Mark::null_mark();
80 }
81 
82 inline NodeType::value Node::Type() const {
83  if (!m_isValid)
84  throw InvalidNode(m_invalidKey);
85  return m_pNode ? m_pNode->type() : NodeType::Null;
86 }
87 
88 // access
89 
90 // template helpers
91 template <typename T, typename S>
92 struct as_if {
93  explicit as_if(const Node& node_) : node(node_) {}
94  const Node& node;
95 
96  T operator()(const S& fallback) const {
97  if (!node.m_pNode)
98  return fallback;
99 
100  T t;
101  if (convert<T>::decode(node, t))
102  return t;
103  return fallback;
104  }
105 };
106 
107 template <typename S>
108 struct as_if<std::string, S> {
109  explicit as_if(const Node& node_) : node(node_) {}
110  const Node& node;
111 
112  std::string operator()(const S& fallback) const {
113  if (node.Type() == NodeType::Null)
114  return "null";
115  if (node.Type() != NodeType::Scalar)
116  return fallback;
117  return node.Scalar();
118  }
119 };
120 
121 template <typename T>
122 struct as_if<T, void> {
123  explicit as_if(const Node& node_) : node(node_) {}
124  const Node& node;
125 
126  T operator()() const {
127  if (!node.m_pNode)
128  throw TypedBadConversion<T>(node.Mark());
129 
130  T t;
131  if (convert<T>::decode(node, t))
132  return t;
133  throw TypedBadConversion<T>(node.Mark());
134  }
135 };
136 
137 template <>
138 struct as_if<std::string, void> {
139  explicit as_if(const Node& node_) : node(node_) {}
140  const Node& node;
141 
142  std::string operator()() const {
143  if (node.Type() == NodeType::Null)
144  return "null";
145  if (node.Type() != NodeType::Scalar)
146  throw TypedBadConversion<std::string>(node.Mark());
147  return node.Scalar();
148  }
149 };
150 
151 // access functions
152 template <typename T>
153 inline T Node::as() const {
154  if (!m_isValid)
155  throw InvalidNode(m_invalidKey);
156  return as_if<T, void>(*this)();
157 }
158 
159 template <typename T, typename S>
160 inline T Node::as(const S& fallback) const {
161  if (!m_isValid)
162  return fallback;
163  return as_if<T, S>(*this)(fallback);
164 }
165 
166 inline const std::string& Node::Scalar() const {
167  if (!m_isValid)
168  throw InvalidNode(m_invalidKey);
169  return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar();
170 }
171 
172 inline const std::string& Node::Tag() const {
173  if (!m_isValid)
174  throw InvalidNode(m_invalidKey);
175  return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar();
176 }
177 
178 inline void Node::SetTag(const std::string& tag) {
179  EnsureNodeExists();
180  m_pNode->set_tag(tag);
181 }
182 
183 inline EmitterStyle::value Node::Style() const {
184  if (!m_isValid)
185  throw InvalidNode(m_invalidKey);
186  return m_pNode ? m_pNode->style() : EmitterStyle::Default;
187 }
188 
189 inline void Node::SetStyle(EmitterStyle::value style) {
190  EnsureNodeExists();
191  m_pNode->set_style(style);
192 }
193 
194 // assignment
195 inline bool Node::is(const Node& rhs) const {
196  if (!m_isValid || !rhs.m_isValid)
197  throw InvalidNode(m_invalidKey);
198  if (!m_pNode || !rhs.m_pNode)
199  return false;
200  return m_pNode->is(*rhs.m_pNode);
201 }
202 
203 template <typename T>
204 inline Node& Node::operator=(const T& rhs) {
205  Assign(rhs);
206  return *this;
207 }
208 
209 inline Node& Node::operator=(const Node& rhs) {
210  if (is(rhs))
211  return *this;
212  AssignNode(rhs);
213  return *this;
214 }
215 
216 inline void Node::reset(const YAML::Node& rhs) {
217  if (!m_isValid || !rhs.m_isValid)
218  throw InvalidNode(m_invalidKey);
219  m_pMemory = rhs.m_pMemory;
220  m_pNode = rhs.m_pNode;
221 }
222 
223 template <typename T>
224 inline void Node::Assign(const T& rhs) {
225  if (!m_isValid)
226  throw InvalidNode(m_invalidKey);
227  AssignData(convert<T>::encode(rhs));
228 }
229 
230 template <>
231 inline void Node::Assign(const std::string& rhs) {
232  EnsureNodeExists();
233  m_pNode->set_scalar(rhs);
234 }
235 
236 inline void Node::Assign(const char* rhs) {
237  EnsureNodeExists();
238  m_pNode->set_scalar(rhs);
239 }
240 
241 inline void Node::Assign(char* rhs) {
242  EnsureNodeExists();
243  m_pNode->set_scalar(rhs);
244 }
245 
246 inline void Node::AssignData(const Node& rhs) {
247  EnsureNodeExists();
248  rhs.EnsureNodeExists();
249 
250  m_pNode->set_data(*rhs.m_pNode);
251  m_pMemory->merge(*rhs.m_pMemory);
252 }
253 
254 inline void Node::AssignNode(const Node& rhs) {
255  if (!m_isValid)
256  throw InvalidNode(m_invalidKey);
257  rhs.EnsureNodeExists();
258 
259  if (!m_pNode) {
260  m_pNode = rhs.m_pNode;
261  m_pMemory = rhs.m_pMemory;
262  return;
263  }
264 
265  m_pNode->set_ref(*rhs.m_pNode);
266  m_pMemory->merge(*rhs.m_pMemory);
267  m_pNode = rhs.m_pNode;
268 }
269 
270 // size/iterator
271 inline std::size_t Node::size() const {
272  if (!m_isValid)
273  throw InvalidNode(m_invalidKey);
274  return m_pNode ? m_pNode->size() : 0;
275 }
276 
277 inline const_iterator Node::begin() const {
278  if (!m_isValid)
279  return const_iterator();
280  return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory)
281  : const_iterator();
282 }
283 
284 inline iterator Node::begin() {
285  if (!m_isValid)
286  return iterator();
287  return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator();
288 }
289 
290 inline const_iterator Node::end() const {
291  if (!m_isValid)
292  return const_iterator();
293  return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator();
294 }
295 
296 inline iterator Node::end() {
297  if (!m_isValid)
298  return iterator();
299  return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator();
300 }
301 
302 // sequence
303 template <typename T>
304 inline void Node::push_back(const T& rhs) {
305  if (!m_isValid)
306  throw InvalidNode(m_invalidKey);
307  push_back(Node(rhs));
308 }
309 
310 inline void Node::push_back(const Node& rhs) {
311  EnsureNodeExists();
312  rhs.EnsureNodeExists();
313 
314  m_pNode->push_back(*rhs.m_pNode, m_pMemory);
315  m_pMemory->merge(*rhs.m_pMemory);
316 }
317 
318 template<typename Key>
319 std::string key_to_string(const Key& key) {
320  return streamable_to_string<Key, is_streamable<std::stringstream, Key>::value>().impl(key);
321 }
322 
323 // indexing
324 template <typename Key>
325 inline const Node Node::operator[](const Key& key) const {
326  EnsureNodeExists();
327  detail::node* value =
328  static_cast<const detail::node&>(*m_pNode).get(key, m_pMemory);
329  if (!value) {
330  return Node(ZombieNode, key_to_string(key));
331  }
332  return Node(*value, m_pMemory);
333 }
334 
335 template <typename Key>
336 inline Node Node::operator[](const Key& key) {
337  EnsureNodeExists();
338  detail::node& value = m_pNode->get(key, m_pMemory);
339  return Node(value, m_pMemory);
340 }
341 
342 template <typename Key>
343 inline bool Node::remove(const Key& key) {
344  EnsureNodeExists();
345  return m_pNode->remove(key, m_pMemory);
346 }
347 
348 inline const Node Node::operator[](const Node& key) const {
349  EnsureNodeExists();
350  key.EnsureNodeExists();
351  m_pMemory->merge(*key.m_pMemory);
352  detail::node* value =
353  static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory);
354  if (!value) {
355  return Node(ZombieNode, key_to_string(key));
356  }
357  return Node(*value, m_pMemory);
358 }
359 
360 inline Node Node::operator[](const Node& key) {
361  EnsureNodeExists();
362  key.EnsureNodeExists();
363  m_pMemory->merge(*key.m_pMemory);
364  detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory);
365  return Node(value, m_pMemory);
366 }
367 
368 inline bool Node::remove(const Node& key) {
369  EnsureNodeExists();
370  key.EnsureNodeExists();
371  return m_pNode->remove(*key.m_pNode, m_pMemory);
372 }
373 
374 // map
375 template <typename Key, typename Value>
376 inline void Node::force_insert(const Key& key, const Value& value) {
377  EnsureNodeExists();
378  m_pNode->force_insert(key, value, m_pMemory);
379 }
380 
381 // free functions
382 inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); }
383 } // namespace YAML
384 
385 #endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
Definition: gtest-internal.h:1322
BWORD operator==(const DualString &s1, const DualString &s2)
Compare two DualString&#39;s.
Definition: DualString.h:208
Definition: anchor.h:12