Loading [MathJax]/extensions/tex2jax.js
Free Electron
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
detail/impl.h
1 #ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
2 #define NODE_DETAIL_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/node/detail/node.h"
11 #include "yaml-cpp/node/detail/node_data.h"
12 
13 #include <algorithm>
14 #include <type_traits>
15 
16 namespace YAML {
17 namespace detail {
18 template <typename Key, typename Enable = void>
19 struct get_idx {
20  static node* get(const std::vector<node*>& /* sequence */,
21  const Key& /* key */, shared_memory_holder /* pMemory */) {
22  return nullptr;
23  }
24 };
25 
26 template <typename Key>
27 struct get_idx<Key,
28  typename std::enable_if<std::is_unsigned<Key>::value &&
29  !std::is_same<Key, bool>::value>::type> {
30  static node* get(const std::vector<node*>& sequence, const Key& key,
31  shared_memory_holder /* pMemory */) {
32  return key < sequence.size() ? sequence[key] : nullptr;
33  }
34 
35  static node* get(std::vector<node*>& sequence, const Key& key,
36  shared_memory_holder pMemory) {
37  if (key > sequence.size() || (key > 0 && !sequence[key - 1]->is_defined()))
38  return nullptr;
39  if (key == sequence.size())
40  sequence.push_back(&pMemory->create_node());
41  return sequence[key];
42  }
43 };
44 
45 template <typename Key>
46 struct get_idx<Key, typename std::enable_if<std::is_signed<Key>::value>::type> {
47  static node* get(const std::vector<node*>& sequence, const Key& key,
48  shared_memory_holder pMemory) {
49  return key >= 0 ? get_idx<std::size_t>::get(
50  sequence, static_cast<std::size_t>(key), pMemory)
51  : nullptr;
52  }
53  static node* get(std::vector<node*>& sequence, const Key& key,
54  shared_memory_holder pMemory) {
55  return key >= 0 ? get_idx<std::size_t>::get(
56  sequence, static_cast<std::size_t>(key), pMemory)
57  : nullptr;
58  }
59 };
60 
61 template <typename Key, typename Enable = void>
62 struct remove_idx {
63  static bool remove(std::vector<node*>&, const Key&, std::size_t&) {
64  return false;
65  }
66 };
67 
68 template <typename Key>
69 struct remove_idx<
70  Key, typename std::enable_if<std::is_unsigned<Key>::value &&
71  !std::is_same<Key, bool>::value>::type> {
72 
73  static bool remove(std::vector<node*>& sequence, const Key& key,
74  std::size_t& seqSize) {
75  if (key >= sequence.size()) {
76  return false;
77  } else {
78  sequence.erase(sequence.begin() + key);
79  if (seqSize > key) {
80  --seqSize;
81  }
82  return true;
83  }
84  }
85 };
86 
87 template <typename Key>
88 struct remove_idx<Key,
89  typename std::enable_if<std::is_signed<Key>::value>::type> {
90 
91  static bool remove(std::vector<node*>& sequence, const Key& key,
92  std::size_t& seqSize) {
93  return key >= 0 ? remove_idx<std::size_t>::remove(
94  sequence, static_cast<std::size_t>(key), seqSize)
95  : false;
96  }
97 };
98 
99 template <typename T>
100 inline bool node::equals(const T& rhs, shared_memory_holder pMemory) {
101  T lhs;
102  if (convert<T>::decode(Node(*this, pMemory), lhs)) {
103  return lhs == rhs;
104  }
105  return false;
106 }
107 
108 inline bool node::equals(const char* rhs, shared_memory_holder pMemory) {
109  std::string lhs;
110  if (convert<std::string>::decode(Node(*this, std::move(pMemory)), lhs)) {
111  return lhs == rhs;
112  }
113  return false;
114 }
115 
116 // indexing
117 template <typename Key>
118 inline node* node_data::get(const Key& key,
119  shared_memory_holder pMemory) const {
120  switch (m_type) {
121  case NodeType::Map:
122  break;
123  case NodeType::Undefined:
124  case NodeType::Null:
125  return nullptr;
126  case NodeType::Sequence:
127  if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory))
128  return pNode;
129  return nullptr;
130  case NodeType::Scalar:
131  throw BadSubscript(m_mark, key);
132  }
133 
134  auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) {
135  return m.first->equals(key, pMemory);
136  });
137 
138  return it != m_map.end() ? it->second : nullptr;
139 }
140 
141 template <typename Key>
142 inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
143  switch (m_type) {
144  case NodeType::Map:
145  break;
146  case NodeType::Undefined:
147  case NodeType::Null:
148  case NodeType::Sequence:
149  if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory)) {
150  m_type = NodeType::Sequence;
151  return *pNode;
152  }
153 
154  convert_to_map(pMemory);
155  break;
156  case NodeType::Scalar:
157  throw BadSubscript(m_mark, key);
158  }
159 
160  auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) {
161  return m.first->equals(key, pMemory);
162  });
163 
164  if (it != m_map.end()) {
165  return *it->second;
166  }
167 
168  node& k = convert_to_node(key, pMemory);
169  node& v = pMemory->create_node();
170  insert_map_pair(k, v);
171  return v;
172 }
173 
174 template <typename Key>
175 inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) {
176  if (m_type == NodeType::Sequence) {
177  return remove_idx<Key>::remove(m_sequence, key, m_seqSize);
178  }
179 
180  if (m_type == NodeType::Map) {
181  kv_pairs::iterator it = m_undefinedPairs.begin();
182  while (it != m_undefinedPairs.end()) {
183  kv_pairs::iterator jt = std::next(it);
184  if (it->first->equals(key, pMemory)) {
185  m_undefinedPairs.erase(it);
186  }
187  it = jt;
188  }
189 
190  auto iter = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) {
191  return m.first->equals(key, pMemory);
192  });
193 
194  if (iter != m_map.end()) {
195  m_map.erase(iter);
196  return true;
197  }
198  }
199 
200  return false;
201 }
202 
203 // map
204 template <typename Key, typename Value>
205 inline void node_data::force_insert(const Key& key, const Value& value,
206  shared_memory_holder pMemory) {
207  switch (m_type) {
208  case NodeType::Map:
209  break;
210  case NodeType::Undefined:
211  case NodeType::Null:
212  case NodeType::Sequence:
213  convert_to_map(pMemory);
214  break;
215  case NodeType::Scalar:
216  throw BadInsert();
217  }
218 
219  node& k = convert_to_node(key, pMemory);
220  node& v = convert_to_node(value, pMemory);
221  insert_map_pair(k, v);
222 }
223 
224 template <typename T>
225 inline node& node_data::convert_to_node(const T& rhs,
226  shared_memory_holder pMemory) {
227  Node value = convert<T>::encode(rhs);
228  value.EnsureNodeExists();
229  pMemory->merge(*value.m_pMemory);
230  return *value.m_pNode;
231 }
232 }
233 }
234 
235 #endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
Definition: gtest-internal.h:1322
Definition: anchor.h:12