Free Electron
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>
43 struct node_iterator_type {
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>
55 class node_iterator_base {
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->() { return std::addressof(m_ref); }
62  operator node_iterator_value<V>*() { return std::addressof(m_ref); }
63 
64  node_iterator_value<V> m_ref;
65  };
66 
67  public:
68  using iterator_category = std::forward_iterator_tag;
69  using value_type = node_iterator_value<V>;
70  using difference_type = std::ptrdiff_t;
71  using pointer = node_iterator_value<V>*;
72  using reference = node_iterator_value<V>;
73  using SeqIter = typename node_iterator_type<V>::seq;
74  using MapIter = typename node_iterator_type<V>::map;
75 
76  node_iterator_base()
77  : m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {}
78  explicit node_iterator_base(SeqIter seqIt)
79  : m_type(iterator_type::Sequence),
80  m_seqIt(seqIt),
81  m_mapIt(),
82  m_mapEnd() {}
83  explicit node_iterator_base(MapIter mapIt, MapIter mapEnd)
84  : m_type(iterator_type::Map),
85  m_seqIt(),
86  m_mapIt(mapIt),
87  m_mapEnd(mapEnd) {
88  m_mapIt = increment_until_defined(m_mapIt);
89  }
90 
91  template <typename W>
92  node_iterator_base(const node_iterator_base<W>& rhs,
93  typename std::enable_if<std::is_convertible<W*, V*>::value,
94  enabler>::type = enabler())
95  : m_type(rhs.m_type),
96  m_seqIt(rhs.m_seqIt),
97  m_mapIt(rhs.m_mapIt),
98  m_mapEnd(rhs.m_mapEnd) {}
99 
100  template <typename>
101  friend class node_iterator_base;
102 
103  template <typename W>
104  bool operator==(const node_iterator_base<W>& rhs) const {
105  if (m_type != rhs.m_type)
106  return false;
107 
108  switch (m_type) {
109  case iterator_type::NoneType:
110  return true;
111  case iterator_type::Sequence:
112  return m_seqIt == rhs.m_seqIt;
113  case iterator_type::Map:
114  return m_mapIt == rhs.m_mapIt;
115  }
116  return true;
117  }
118 
119  template <typename W>
120  bool operator!=(const node_iterator_base<W>& rhs) const {
121  return !(*this == rhs);
122  }
123 
124  node_iterator_base<V>& operator++() {
125  switch (m_type) {
126  case iterator_type::NoneType:
127  break;
128  case iterator_type::Sequence:
129  ++m_seqIt;
130  break;
131  case iterator_type::Map:
132  ++m_mapIt;
133  m_mapIt = increment_until_defined(m_mapIt);
134  break;
135  }
136  return *this;
137  }
138 
139  node_iterator_base<V> operator++(int) {
140  node_iterator_base<V> iterator_pre(*this);
141  ++(*this);
142  return iterator_pre;
143  }
144 
145  value_type operator*() const {
146  switch (m_type) {
147  case iterator_type::NoneType:
148  return value_type();
149  case iterator_type::Sequence:
150  return value_type(**m_seqIt);
151  case iterator_type::Map:
152  return value_type(*m_mapIt->first, *m_mapIt->second);
153  }
154  return value_type();
155  }
156 
157  proxy operator->() const { return proxy(**this); }
158 
159  MapIter increment_until_defined(MapIter it) {
160  while (it != m_mapEnd && !is_defined(it))
161  ++it;
162  return it;
163  }
164 
165  bool is_defined(MapIter it) const {
166  return it->first->is_defined() && it->second->is_defined();
167  }
168 
169  private:
170  typename iterator_type::value m_type;
171 
172  SeqIter m_seqIt;
173  MapIter m_mapIt, m_mapEnd;
174 };
175 
176 using node_iterator = node_iterator_base<node>;
177 using const_node_iterator = node_iterator_base<const node>;
178 }
179 }
180 
181 #endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
Definition: anchor.h:12