iterator.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
  2. #define VALUE_DETAIL_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/detail/node_iterator.h"
  10. #include "yaml-cpp/node/node.h"
  11. #include "yaml-cpp/node/ptr.h"
  12. #include <cstddef>
  13. #include <iterator>
  14. namespace YAML {
  15. namespace detail {
  16. struct iterator_value;
  17. template <typename V>
  18. class iterator_base {
  19. private:
  20. template <typename>
  21. friend class iterator_base;
  22. struct enabler {};
  23. using base_type = node_iterator;
  24. struct proxy {
  25. explicit proxy(const V& x) : m_ref(x) {}
  26. V* operator->() { return std::addressof(m_ref); }
  27. operator V*() { return std::addressof(m_ref); }
  28. V m_ref;
  29. };
  30. public:
  31. using iterator_category = std::forward_iterator_tag;
  32. using value_type = V;
  33. using difference_type = std::ptrdiff_t;
  34. using pointer = V*;
  35. using reference = V;
  36. public:
  37. iterator_base() : m_iterator(), m_pMemory() {}
  38. explicit iterator_base(base_type rhs, shared_memory_holder pMemory)
  39. : m_iterator(rhs), m_pMemory(pMemory) {}
  40. template <class W>
  41. iterator_base(const iterator_base<W>& rhs,
  42. typename std::enable_if<std::is_convertible<W*, V*>::value,
  43. enabler>::type = enabler())
  44. : m_iterator(rhs.m_iterator), m_pMemory(rhs.m_pMemory) {}
  45. iterator_base<V>& operator++() {
  46. ++m_iterator;
  47. return *this;
  48. }
  49. iterator_base<V> operator++(int) {
  50. iterator_base<V> iterator_pre(*this);
  51. ++(*this);
  52. return iterator_pre;
  53. }
  54. template <typename W>
  55. bool operator==(const iterator_base<W>& rhs) const {
  56. return m_iterator == rhs.m_iterator;
  57. }
  58. template <typename W>
  59. bool operator!=(const iterator_base<W>& rhs) const {
  60. return m_iterator != rhs.m_iterator;
  61. }
  62. value_type operator*() const {
  63. const typename base_type::value_type& v = *m_iterator;
  64. if (v.pNode)
  65. return value_type(Node(*v, m_pMemory));
  66. if (v.first && v.second)
  67. return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory));
  68. return value_type();
  69. }
  70. proxy operator->() const { return proxy(**this); }
  71. private:
  72. base_type m_iterator;
  73. shared_memory_holder m_pMemory;
  74. };
  75. } // namespace detail
  76. } // namespace YAML
  77. #endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66