Back to home page

EIC code displayed by LXR

 
 

    


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))  // GCC supports "pragma once" correctly since 3.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  // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66