LCOV - code coverage report
Current view: top level - usr/include/yaml-cpp/node/detail - node_iterator.h (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 37 46 80.4 %
Date: 2025-08-24 09:11:10 Functions: 10 11 90.9 %

          Line data    Source code
       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             :   using kv = std::pair<V*, V*>;
      28             : 
      29           0 :   node_iterator_value() : kv(), pNode(nullptr) {}
      30          30 :   explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {}
      31        2814 :   explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(nullptr) {}
      32             : 
      33          30 :   V& operator*() const { return *pNode; }
      34             :   V& operator->() const { return *pNode; }
      35             : 
      36             :   V* pNode;
      37             : };
      38             : 
      39             : using node_seq = std::vector<node *>;
      40             : using node_map = std::vector<std::pair<node*, node*>>;
      41             : 
      42             : template <typename V>
      43             : struct node_iterator_type {
      44             :   using seq = node_seq::iterator;
      45             :   using map = node_map::iterator;
      46             : };
      47             : 
      48             : template <typename V>
      49             : struct node_iterator_type<const V> {
      50             :   using seq = node_seq::const_iterator;
      51             :   using map = node_map::const_iterator;
      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             :   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;
      75             : 
      76          12 :   node_iterator_base()
      77          12 :       : 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        3963 :   bool operator==(const node_iterator_base<W>& rhs) const {
     105        3963 :     if (m_type != rhs.m_type)
     106           0 :       return false;
     107             : 
     108        3963 :     switch (m_type) {
     109           6 :       case iterator_type::NoneType:
     110           6 :         return true;
     111         140 :       case iterator_type::Sequence:
     112         140 :         return m_seqIt == rhs.m_seqIt;
     113        3817 :       case iterator_type::Map:
     114        3817 :         return m_mapIt == rhs.m_mapIt;
     115             :     }
     116           0 :     return true;
     117             :   }
     118             : 
     119             :   template <typename W>
     120        3963 :   bool operator!=(const node_iterator_base<W>& rhs) const {
     121        3963 :     return !(*this == rhs);
     122             :   }
     123             : 
     124        2844 :   node_iterator_base<V>& operator++() {
     125        2844 :     switch (m_type) {
     126           0 :       case iterator_type::NoneType:
     127           0 :         break;
     128          30 :       case iterator_type::Sequence:
     129          30 :         ++m_seqIt;
     130          30 :         break;
     131        2814 :       case iterator_type::Map:
     132        2814 :         ++m_mapIt;
     133        2814 :         m_mapIt = increment_until_defined(m_mapIt);
     134        2814 :         break;
     135             :     }
     136        2844 :     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        2844 :   value_type operator*() const {
     146        2844 :     switch (m_type) {
     147           0 :       case iterator_type::NoneType:
     148           0 :         return value_type();
     149          30 :       case iterator_type::Sequence:
     150          30 :         return value_type(**m_seqIt);
     151        2814 :       case iterator_type::Map:
     152        2814 :         return value_type(*m_mapIt->first, *m_mapIt->second);
     153             :     }
     154           0 :     return value_type();
     155             :   }
     156             : 
     157             :   proxy operator->() const { return proxy(**this); }
     158             : 
     159        2814 :   MapIter increment_until_defined(MapIter it) {
     160        2814 :     while (it != m_mapEnd && !is_defined(it))
     161           0 :       ++it;
     162        2814 :     return it;
     163             :   }
     164             : 
     165        1811 :   bool is_defined(MapIter it) const {
     166        1811 :     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             : using node_iterator = node_iterator_base<node>;
     177             : using const_node_iterator = node_iterator_base<const node>;
     178             : }
     179             : }
     180             : 
     181             : #endif  // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

Generated by: LCOV version 1.14