node_iterator.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. #if defined(_MSC_VER) || \
  4. (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
  5. (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
  6. #pragma once
  7. #endif
  8. #include "yaml-cpp/dll.h"
  9. #include "yaml-cpp/node/ptr.h"
  10. #include <cstddef>
  11. #include <iterator>
  12. #include <memory>
  13. #include <map>
  14. #include <utility>
  15. #include <vector>
  16. namespace YAML {
  17. namespace detail {
  18. struct iterator_type {
  19. enum value { NoneType, Sequence, Map };
  20. };
  21. template <typename V>
  22. struct node_iterator_value : public std::pair<V*, V*> {
  23. using kv = std::pair<V*, V*>;
  24. node_iterator_value() : kv(), pNode(nullptr) {}
  25. explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {}
  26. explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(nullptr) {}
  27. V& operator*() const { return *pNode; }
  28. V& operator->() const { return *pNode; }
  29. V* pNode;
  30. };
  31. using node_seq = std::vector<node *>;
  32. using node_map = std::vector<std::pair<node*, node*>>;
  33. template <typename V>
  34. struct node_iterator_type {
  35. using seq = node_seq::iterator;
  36. using map = node_map::iterator;
  37. };
  38. template <typename V>
  39. struct node_iterator_type<const V> {
  40. using seq = node_seq::const_iterator;
  41. using map = node_map::const_iterator;
  42. };
  43. template <typename V>
  44. class node_iterator_base
  45. : public std::iterator<std::forward_iterator_tag, node_iterator_value<V>,
  46. std::ptrdiff_t, node_iterator_value<V>*,
  47. node_iterator_value<V>> {
  48. private:
  49. struct enabler {};
  50. struct proxy {
  51. explicit proxy(const node_iterator_value<V>& x) : m_ref(x) {}
  52. node_iterator_value<V>* operator->() { return std::addressof(m_ref); }
  53. operator node_iterator_value<V>*() { return std::addressof(m_ref); }
  54. node_iterator_value<V> m_ref;
  55. };
  56. public:
  57. using SeqIter = typename node_iterator_type<V>::seq;
  58. using MapIter = typename node_iterator_type<V>::map;
  59. using value_type = node_iterator_value<V>;
  60. node_iterator_base()
  61. : m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {}
  62. explicit node_iterator_base(SeqIter seqIt)
  63. : m_type(iterator_type::Sequence),
  64. m_seqIt(seqIt),
  65. m_mapIt(),
  66. m_mapEnd() {}
  67. explicit node_iterator_base(MapIter mapIt, MapIter mapEnd)
  68. : m_type(iterator_type::Map),
  69. m_seqIt(),
  70. m_mapIt(mapIt),
  71. m_mapEnd(mapEnd) {
  72. m_mapIt = increment_until_defined(m_mapIt);
  73. }
  74. template <typename W>
  75. node_iterator_base(const node_iterator_base<W>& rhs,
  76. typename std::enable_if<std::is_convertible<W*, V*>::value,
  77. enabler>::type = enabler())
  78. : m_type(rhs.m_type),
  79. m_seqIt(rhs.m_seqIt),
  80. m_mapIt(rhs.m_mapIt),
  81. m_mapEnd(rhs.m_mapEnd) {}
  82. template <typename>
  83. friend class node_iterator_base;
  84. template <typename W>
  85. bool operator==(const node_iterator_base<W>& rhs) const {
  86. if (m_type != rhs.m_type)
  87. return false;
  88. switch (m_type) {
  89. case iterator_type::NoneType:
  90. return true;
  91. case iterator_type::Sequence:
  92. return m_seqIt == rhs.m_seqIt;
  93. case iterator_type::Map:
  94. return m_mapIt == rhs.m_mapIt;
  95. }
  96. return true;
  97. }
  98. template <typename W>
  99. bool operator!=(const node_iterator_base<W>& rhs) const {
  100. return !(*this == rhs);
  101. }
  102. node_iterator_base<V>& operator++() {
  103. switch (m_type) {
  104. case iterator_type::NoneType:
  105. break;
  106. case iterator_type::Sequence:
  107. ++m_seqIt;
  108. break;
  109. case iterator_type::Map:
  110. ++m_mapIt;
  111. m_mapIt = increment_until_defined(m_mapIt);
  112. break;
  113. }
  114. return *this;
  115. }
  116. node_iterator_base<V> operator++(int) {
  117. node_iterator_base<V> iterator_pre(*this);
  118. ++(*this);
  119. return iterator_pre;
  120. }
  121. value_type operator*() const {
  122. switch (m_type) {
  123. case iterator_type::NoneType:
  124. return value_type();
  125. case iterator_type::Sequence:
  126. return value_type(**m_seqIt);
  127. case iterator_type::Map:
  128. return value_type(*m_mapIt->first, *m_mapIt->second);
  129. }
  130. return value_type();
  131. }
  132. proxy operator->() const { return proxy(**this); }
  133. MapIter increment_until_defined(MapIter it) {
  134. while (it != m_mapEnd && !is_defined(it))
  135. ++it;
  136. return it;
  137. }
  138. bool is_defined(MapIter it) const {
  139. return it->first->is_defined() && it->second->is_defined();
  140. }
  141. private:
  142. typename iterator_type::value m_type;
  143. SeqIter m_seqIt;
  144. MapIter m_mapIt, m_mapEnd;
  145. };
  146. using node_iterator = node_iterator_base<node>;
  147. using const_node_iterator = node_iterator_base<const node>;
  148. }
  149. }
  150. #endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66