Line data Source code
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 2025 : inline Node::Node()
20 2025 : : 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 8616 : inline Node::Node(const T& rhs)
32 8616 : : m_isValid(true),
33 8616 : m_invalidKey{},
34 8616 : m_pMemory(new detail::memory_holder),
35 8616 : m_pNode(&m_pMemory->create_node()) {
36 8616 : Assign(rhs);
37 8616 : }
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 5718 : inline Node::Node(const Node& rhs) = default;
46 :
47 2874 : inline Node::Node(Zombie)
48 2874 : : m_isValid(false), m_invalidKey{}, m_pMemory{}, m_pNode(nullptr) {}
49 :
50 12 : inline Node::Node(Zombie, const std::string& key)
51 12 : : m_isValid(false), m_invalidKey(key), m_pMemory{}, m_pNode(nullptr) {}
52 :
53 46513 : inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory)
54 46513 : : m_isValid(true), m_invalidKey{}, m_pMemory(pMemory), m_pNode(&node) {}
55 :
56 66011 : inline Node::~Node() = default;
57 :
58 36803 : inline void Node::EnsureNodeExists() const {
59 36803 : if (!m_isValid)
60 6 : throw InvalidNode(m_invalidKey);
61 36797 : if (!m_pNode) {
62 1442 : m_pMemory.reset(new detail::memory_holder);
63 1442 : m_pNode = &m_pMemory->create_node();
64 1442 : m_pNode->set_null();
65 : }
66 36797 : }
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 0 : inline Mark Node::Mark() const {
76 0 : if (!m_isValid) {
77 0 : throw InvalidNode(m_invalidKey);
78 : }
79 0 : return m_pNode ? m_pNode->mark() : Mark::null_mark();
80 : }
81 :
82 42681 : inline NodeType::value Node::Type() const {
83 42681 : if (!m_isValid)
84 0 : throw InvalidNode(m_invalidKey);
85 42681 : 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 0 : explicit as_if(const Node& node_) : node(node_) {}
110 : const Node& node;
111 :
112 0 : std::string operator()(const S& fallback) const {
113 0 : if (node.Type() == NodeType::Null)
114 0 : return "null";
115 0 : if (node.Type() != NodeType::Scalar)
116 0 : return fallback;
117 0 : return node.Scalar();
118 : }
119 : };
120 :
121 : template <typename T>
122 : struct as_if<T, void> {
123 1359 : explicit as_if(const Node& node_) : node(node_) {}
124 : const Node& node;
125 :
126 1359 : T operator()() const {
127 1359 : if (!node.m_pNode)
128 0 : throw TypedBadConversion<T>(node.Mark());
129 :
130 609 : T t;
131 1359 : if (convert<T>::decode(node, t))
132 1359 : return t;
133 0 : throw TypedBadConversion<T>(node.Mark());
134 0 : }
135 : };
136 :
137 : template <>
138 : struct as_if<std::string, void> {
139 5876 : explicit as_if(const Node& node_) : node(node_) {}
140 : const Node& node;
141 :
142 5876 : std::string operator()() const {
143 5876 : if (node.Type() == NodeType::Null)
144 0 : return "null";
145 5876 : if (node.Type() != NodeType::Scalar)
146 0 : throw TypedBadConversion<std::string>(node.Mark());
147 5876 : return node.Scalar();
148 : }
149 : };
150 :
151 : // access functions
152 : template <typename T>
153 7235 : inline T Node::as() const {
154 7235 : if (!m_isValid)
155 0 : throw InvalidNode(m_invalidKey);
156 13720 : return as_if<T, void>(*this)();
157 : }
158 :
159 : template <typename T, typename S>
160 0 : inline T Node::as(const S& fallback) const {
161 0 : if (!m_isValid)
162 0 : return fallback;
163 0 : return as_if<T, S>(*this)(fallback);
164 : }
165 :
166 36154 : inline const std::string& Node::Scalar() const {
167 36154 : if (!m_isValid)
168 0 : throw InvalidNode(m_invalidKey);
169 36154 : 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 8616 : inline Node& Node::operator=(const T& rhs) {
205 8616 : Assign(rhs);
206 8616 : 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 589 : inline void Node::reset(const YAML::Node& rhs) {
217 589 : if (!m_isValid || !rhs.m_isValid)
218 0 : throw InvalidNode(m_invalidKey);
219 589 : m_pMemory = rhs.m_pMemory;
220 589 : m_pNode = rhs.m_pNode;
221 589 : }
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 8616 : inline void Node::Assign(const std::string& rhs) {
232 8616 : EnsureNodeExists();
233 8616 : m_pNode->set_scalar(rhs);
234 8616 : }
235 :
236 8616 : inline void Node::Assign(const char* rhs) {
237 8616 : EnsureNodeExists();
238 8616 : m_pNode->set_scalar(rhs);
239 8616 : }
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 0 : inline std::size_t Node::size() const {
272 0 : if (!m_isValid)
273 0 : throw InvalidNode(m_invalidKey);
274 0 : return m_pNode ? m_pNode->size() : 0;
275 : }
276 :
277 116 : inline const_iterator Node::begin() const {
278 116 : if (!m_isValid)
279 6 : return const_iterator();
280 330 : return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory)
281 110 : : const_iterator();
282 : }
283 :
284 1003 : inline iterator Node::begin() {
285 1003 : if (!m_isValid)
286 0 : return iterator();
287 1003 : return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator();
288 : }
289 :
290 116 : inline const_iterator Node::end() const {
291 116 : if (!m_isValid)
292 6 : return const_iterator();
293 110 : return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator();
294 : }
295 :
296 1003 : inline iterator Node::end() {
297 1003 : if (!m_isValid)
298 0 : return iterator();
299 1003 : 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 12 : std::string key_to_string(const Key& key) {
320 12 : return streamable_to_string<Key, is_streamable<std::stringstream, Key>::value>().impl(key);
321 : }
322 :
323 : // indexing
324 : template <typename Key>
325 1548 : inline const Node Node::operator[](const Key& key) const {
326 1548 : EnsureNodeExists();
327 : detail::node* value =
328 1542 : static_cast<const detail::node&>(*m_pNode).get(key, m_pMemory);
329 1542 : if (!value) {
330 12 : return Node(ZombieNode, key_to_string(key));
331 : }
332 1530 : return Node(*value, m_pMemory);
333 : }
334 :
335 : template <typename Key>
336 9407 : inline Node Node::operator[](const Key& key) {
337 9407 : EnsureNodeExists();
338 9407 : detail::node& value = m_pNode->get(key, m_pMemory);
339 9407 : 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
|