File indexing completed on 2025-01-18 10:15:43
0001 #ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
0002 #define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
0003
0004 #if defined(_MSC_VER) || \
0005 (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
0006 (__GNUC__ >= 4))
0007 #pragma once
0008 #endif
0009
0010 #include "yaml-cpp/dll.h"
0011 #include "yaml-cpp/node/ptr.h"
0012 #include <cstddef>
0013 #include <iterator>
0014 #include <memory>
0015 #include <map>
0016 #include <utility>
0017 #include <vector>
0018
0019 namespace YAML {
0020 namespace detail {
0021 struct iterator_type {
0022 enum value { NoneType, Sequence, Map };
0023 };
0024
0025 template <typename V>
0026 struct node_iterator_value : public std::pair<V*, V*> {
0027 using kv = std::pair<V*, V*>;
0028
0029 node_iterator_value() : kv(), pNode(nullptr) {}
0030 explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {}
0031 explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(nullptr) {}
0032
0033 V& operator*() const { return *pNode; }
0034 V& operator->() const { return *pNode; }
0035
0036 V* pNode;
0037 };
0038
0039 using node_seq = std::vector<node *>;
0040 using node_map = std::vector<std::pair<node*, node*>>;
0041
0042 template <typename V>
0043 struct node_iterator_type {
0044 using seq = node_seq::iterator;
0045 using map = node_map::iterator;
0046 };
0047
0048 template <typename V>
0049 struct node_iterator_type<const V> {
0050 using seq = node_seq::const_iterator;
0051 using map = node_map::const_iterator;
0052 };
0053
0054 template <typename V>
0055 class node_iterator_base {
0056 private:
0057 struct enabler {};
0058
0059 struct proxy {
0060 explicit proxy(const node_iterator_value<V>& x) : m_ref(x) {}
0061 node_iterator_value<V>* operator->() { return std::addressof(m_ref); }
0062 operator node_iterator_value<V>*() { return std::addressof(m_ref); }
0063
0064 node_iterator_value<V> m_ref;
0065 };
0066
0067 public:
0068 using iterator_category = std::forward_iterator_tag;
0069 using value_type = node_iterator_value<V>;
0070 using difference_type = std::ptrdiff_t;
0071 using pointer = node_iterator_value<V>*;
0072 using reference = node_iterator_value<V>;
0073 using SeqIter = typename node_iterator_type<V>::seq;
0074 using MapIter = typename node_iterator_type<V>::map;
0075
0076 node_iterator_base()
0077 : m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {}
0078 explicit node_iterator_base(SeqIter seqIt)
0079 : m_type(iterator_type::Sequence),
0080 m_seqIt(seqIt),
0081 m_mapIt(),
0082 m_mapEnd() {}
0083 explicit node_iterator_base(MapIter mapIt, MapIter mapEnd)
0084 : m_type(iterator_type::Map),
0085 m_seqIt(),
0086 m_mapIt(mapIt),
0087 m_mapEnd(mapEnd) {
0088 m_mapIt = increment_until_defined(m_mapIt);
0089 }
0090
0091 template <typename W>
0092 node_iterator_base(const node_iterator_base<W>& rhs,
0093 typename std::enable_if<std::is_convertible<W*, V*>::value,
0094 enabler>::type = enabler())
0095 : m_type(rhs.m_type),
0096 m_seqIt(rhs.m_seqIt),
0097 m_mapIt(rhs.m_mapIt),
0098 m_mapEnd(rhs.m_mapEnd) {}
0099
0100 template <typename>
0101 friend class node_iterator_base;
0102
0103 template <typename W>
0104 bool operator==(const node_iterator_base<W>& rhs) const {
0105 if (m_type != rhs.m_type)
0106 return false;
0107
0108 switch (m_type) {
0109 case iterator_type::NoneType:
0110 return true;
0111 case iterator_type::Sequence:
0112 return m_seqIt == rhs.m_seqIt;
0113 case iterator_type::Map:
0114 return m_mapIt == rhs.m_mapIt;
0115 }
0116 return true;
0117 }
0118
0119 template <typename W>
0120 bool operator!=(const node_iterator_base<W>& rhs) const {
0121 return !(*this == rhs);
0122 }
0123
0124 node_iterator_base<V>& operator++() {
0125 switch (m_type) {
0126 case iterator_type::NoneType:
0127 break;
0128 case iterator_type::Sequence:
0129 ++m_seqIt;
0130 break;
0131 case iterator_type::Map:
0132 ++m_mapIt;
0133 m_mapIt = increment_until_defined(m_mapIt);
0134 break;
0135 }
0136 return *this;
0137 }
0138
0139 node_iterator_base<V> operator++(int) {
0140 node_iterator_base<V> iterator_pre(*this);
0141 ++(*this);
0142 return iterator_pre;
0143 }
0144
0145 value_type operator*() const {
0146 switch (m_type) {
0147 case iterator_type::NoneType:
0148 return value_type();
0149 case iterator_type::Sequence:
0150 return value_type(**m_seqIt);
0151 case iterator_type::Map:
0152 return value_type(*m_mapIt->first, *m_mapIt->second);
0153 }
0154 return value_type();
0155 }
0156
0157 proxy operator->() const { return proxy(**this); }
0158
0159 MapIter increment_until_defined(MapIter it) {
0160 while (it != m_mapEnd && !is_defined(it))
0161 ++it;
0162 return it;
0163 }
0164
0165 bool is_defined(MapIter it) const {
0166 return it->first->is_defined() && it->second->is_defined();
0167 }
0168
0169 private:
0170 typename iterator_type::value m_type;
0171
0172 SeqIter m_seqIt;
0173 MapIter m_mapIt, m_mapEnd;
0174 };
0175
0176 using node_iterator = node_iterator_base<node>;
0177 using const_node_iterator = node_iterator_base<const node>;
0178 }
0179 }
0180
0181 #endif