My Project
node_iterator.h
1 #ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
2 #define VALUE_DETAIL_NODE_ITERATOR_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/node/ptr.h"
12 #include <cstddef>
13 #include <iterator>
14 #include <memory>
15 #include <map>
16 #include <utility>
17 #include <vector>
18 
19 namespace YAML {
20 namespace detail {
21 struct iterator_type {
22  enum value { NoneType, Sequence, Map };
23 };
24 
25 template <typename V>
26 struct node_iterator_value : public std::pair<V*, V*> {
27  using kv = std::pair<V*, V*>;
28 
29  node_iterator_value() : kv(), pNode(nullptr) {}
30  explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {}
31  explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(nullptr) {}
32 
33  V& operator*() const { return *pNode; }
34  V& operator->() const { return *pNode; }
35 
36  V* pNode;
37 };
38 
39 using node_seq = std::vector<node *>;
40 using node_map = std::vector<std::pair<node*, node*>>;
41 
42 template <typename V>
44  using seq = node_seq::iterator;
45  using map = node_map::iterator;
46 };
47 
48 template <typename V>
49 struct node_iterator_type<const V> {
50  using seq = node_seq::const_iterator;
51  using map = node_map::const_iterator;
52 };
53 
54 template <typename V>
56  private:
57  struct enabler {};
58 
59  struct proxy {
60  explicit proxy(const node_iterator_value<V>& x) : m_ref(x) {}
61  node_iterator_value<V>* operator->() YAML_ATTRIBUTE_LIFETIME_BOUND {
62  return std::addressof(m_ref);
63  }
64  operator node_iterator_value<V>*() YAML_ATTRIBUTE_LIFETIME_BOUND {
65  return std::addressof(m_ref);
66  }
67 
69  };
70 
71  public:
72  using iterator_category = std::forward_iterator_tag;
74  using difference_type = std::ptrdiff_t;
77  using SeqIter = typename node_iterator_type<V>::seq;
78  using MapIter = typename node_iterator_type<V>::map;
79 
81  : m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {}
82  explicit node_iterator_base(SeqIter seqIt)
83  : m_type(iterator_type::Sequence),
84  m_seqIt(seqIt),
85  m_mapIt(),
86  m_mapEnd() {}
87  explicit node_iterator_base(MapIter mapIt, MapIter mapEnd)
88  : m_type(iterator_type::Map),
89  m_seqIt(),
90  m_mapIt(mapIt),
91  m_mapEnd(mapEnd) {
92  m_mapIt = increment_until_defined(m_mapIt);
93  }
94 
95  template <typename W>
97  typename std::enable_if<std::is_convertible<W*, V*>::value,
98  enabler>::type = enabler())
99  : m_type(rhs.m_type),
100  m_seqIt(rhs.m_seqIt),
101  m_mapIt(rhs.m_mapIt),
102  m_mapEnd(rhs.m_mapEnd) {}
103 
104  template <typename>
105  friend class node_iterator_base;
106 
107  template <typename W>
108  bool operator==(const node_iterator_base<W>& rhs) const {
109  if (m_type != rhs.m_type)
110  return false;
111 
112  switch (m_type) {
113  case iterator_type::NoneType:
114  return true;
115  case iterator_type::Sequence:
116  return m_seqIt == rhs.m_seqIt;
117  case iterator_type::Map:
118  return m_mapIt == rhs.m_mapIt;
119  }
120  return true;
121  }
122 
123  template <typename W>
124  bool operator!=(const node_iterator_base<W>& rhs) const {
125  return !(*this == rhs);
126  }
127 
128  node_iterator_base<V>& operator++() {
129  switch (m_type) {
130  case iterator_type::NoneType:
131  break;
132  case iterator_type::Sequence:
133  ++m_seqIt;
134  break;
135  case iterator_type::Map:
136  ++m_mapIt;
137  m_mapIt = increment_until_defined(m_mapIt);
138  break;
139  }
140  return *this;
141  }
142 
143  node_iterator_base<V> operator++(int) {
144  node_iterator_base<V> iterator_pre(*this);
145  ++(*this);
146  return iterator_pre;
147  }
148 
149  value_type operator*() const {
150  switch (m_type) {
151  case iterator_type::NoneType:
152  return value_type();
153  case iterator_type::Sequence:
154  return value_type(**m_seqIt);
155  case iterator_type::Map:
156  return value_type(*m_mapIt->first, *m_mapIt->second);
157  }
158  return value_type();
159  }
160 
161  proxy operator->() const { return proxy(**this); }
162 
163  MapIter increment_until_defined(MapIter it) {
164  while (it != m_mapEnd && !is_defined(it))
165  ++it;
166  return it;
167  }
168 
169  bool is_defined(MapIter it) const {
170  return it->first->is_defined() && it->second->is_defined();
171  }
172 
173  private:
174  typename iterator_type::value m_type;
175 
176  SeqIter m_seqIt;
177  MapIter m_mapIt, m_mapEnd;
178 };
179 
182 }
183 }
184 
185 #endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
Definition: node_iterator.h:43
Definition: node_iterator.h:26
Definition: node_iterator.h:55
Definition: node_iterator.h:21
Definition: anchor.h:12