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 typedef std::pair<V*, V*> kv; 28 node_iterator_valuenode_iterator_value29 node_iterator_value() : kv(), pNode(0) {} node_iterator_valuenode_iterator_value30 explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {} node_iterator_valuenode_iterator_value31 explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(0) {} 32 33 V& operator*() const { return *pNode; } 34 V& operator->() const { return *pNode; } 35 36 V* pNode; 37 }; 38 39 typedef std::vector<node*> node_seq; 40 typedef std::vector<std::pair<node*, node*>> node_map; 41 42 template <typename V> 43 struct node_iterator_type { 44 typedef node_seq::iterator seq; 45 typedef node_map::iterator map; 46 }; 47 48 template <typename V> 49 struct node_iterator_type<const V> { 50 typedef node_seq::const_iterator seq; 51 typedef node_map::const_iterator map; 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 typedef typename node_iterator_type<V>::seq SeqIter; 69 typedef typename node_iterator_type<V>::map MapIter; 70 using iterator_category = std::forward_iterator_tag; 71 using value_type = node_iterator_value<V>; 72 using difference_type = std::ptrdiff_t; 73 using pointer = node_iterator_value<V>*; 74 using reference = node_iterator_value<V>&; 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 typedef node_iterator_base<node> node_iterator; 177 typedef node_iterator_base<const node> const_node_iterator; 178 } 179 } 180 181 #endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 182