1 #ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 #define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 4 #if defined(_MSC_VER) || \ 5 (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 10 #include "yaml-cpp/dll.h" 11 #include "yaml-cpp/node/ptr.h" 21 struct iterator_type {
22 enum value { NoneType, Sequence, Map };
26 struct node_iterator_value :
public std::pair<V*, V*> {
27 using kv = std::pair<V*, V*>;
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) {}
33 V& operator*()
const {
return *pNode; }
34 V& operator->()
const {
return *pNode; }
39 using node_seq = std::vector<node *>;
40 using node_map = std::vector<std::pair<node*, node*>>;
43 struct node_iterator_type {
44 using seq = node_seq::iterator;
45 using map = node_map::iterator;
49 struct node_iterator_type<const V> {
50 using seq = node_seq::const_iterator;
51 using map = node_map::const_iterator;
55 class node_iterator_base {
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); }
64 node_iterator_value<V> m_ref;
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;
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),
83 explicit node_iterator_base(MapIter mapIt, MapIter mapEnd)
84 : m_type(iterator_type::Map),
88 m_mapIt = increment_until_defined(m_mapIt);
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())
98 m_mapEnd(rhs.m_mapEnd) {}
101 friend class node_iterator_base;
103 template <
typename W>
104 bool operator==(
const node_iterator_base<W>& rhs)
const {
105 if (m_type != rhs.m_type)
109 case iterator_type::NoneType:
111 case iterator_type::Sequence:
112 return m_seqIt == rhs.m_seqIt;
113 case iterator_type::Map:
114 return m_mapIt == rhs.m_mapIt;
119 template <
typename W>
120 bool operator!=(
const node_iterator_base<W>& rhs)
const {
121 return !(*
this == rhs);
124 node_iterator_base<V>& operator++() {
126 case iterator_type::NoneType:
128 case iterator_type::Sequence:
131 case iterator_type::Map:
133 m_mapIt = increment_until_defined(m_mapIt);
139 node_iterator_base<V> operator++(
int) {
140 node_iterator_base<V> iterator_pre(*
this);
145 value_type operator*()
const {
147 case iterator_type::NoneType:
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);
157 proxy operator->()
const {
return proxy(**
this); }
159 MapIter increment_until_defined(MapIter it) {
160 while (it != m_mapEnd && !is_defined(it))
165 bool is_defined(MapIter it)
const {
166 return it->first->is_defined() && it->second->is_defined();
170 typename iterator_type::value m_type;
173 MapIter m_mapIt, m_mapEnd;
176 using node_iterator = node_iterator_base<node>;
177 using const_node_iterator = node_iterator_base<const node>;
181 #endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66