diff --git a/include/yaml-cpp/value/detail/iterator.h b/include/yaml-cpp/value/detail/iterator.h index 191056f..46013c0 100644 --- a/include/yaml-cpp/value/detail/iterator.h +++ b/include/yaml-cpp/value/detail/iterator.h @@ -8,79 +8,41 @@ #include "yaml-cpp/dll.h" #include "yaml-cpp/value/ptr.h" -#include +#include "yaml-cpp/value/detail/node_iterator.h" +#include #include namespace YAML { namespace detail { - struct iterator_type { enum value { None, Sequence, Map }; }; + template struct iterator_value; - template - class iterator_base: public boost::iterator_facade, V, std::bidirectional_iterator_tag> + template + class iterator_base: public boost::iterator_adaptor< + iterator_base, + node_iterator_base::seq, typename node_iterator::map>, + iterator_value, + std::bidirectional_iterator_tag> { private: - struct enabler {}; + template friend class iterator_base; public: - iterator_base(): m_type(iterator_type::None) {} - explicit iterator_base(shared_memory_holder pMemory, SeqIter seqIt): m_type(iterator_type::Sequence), m_pMemory(pMemory), m_seqIt(seqIt) {} - explicit iterator_base(shared_memory_holder pMemory, MapIter mapIt): m_type(iterator_type::Map), m_pMemory(pMemory), m_mapIt(mapIt) {} - - template - iterator_base(const iterator_base& rhs, typename boost::enable_if, enabler>::type = enabler()) - : m_type(rhs.m_type), m_pMemory(rhs.m_pMemory), m_seqIt(rhs.m_seqIt), m_mapIt(rhs.m_mapIt) {} + iterator_base() {} + explicit iterator_base(base_type rhs, shared_memory_holder pMemory): iterator_base::iterator_adaptor_(rhs), m_pMemory(pMemory) {} + template + iterator_base(const iterator_Base& rhs, typename boost::enable_if, enabler>::type = enabler()): iterator_Base::iterator_adaptor_(rhs.base()), m_pMemory(rhs.m_pMemory) {} + private: friend class boost::iterator_core_access; - template friend class iterator_base; - - template - bool equal(const iterator_base& rhs) const { - if(m_type != rhs.m_type || m_pMemory != rhs.m_pMemory) - return false; - - switch(m_type) { - case iterator_type::None: return true; - case iterator_type::Sequence: return m_seqIt == rhs.m_seqIt; - case iterator_type::Map: return m_mapIt == rhs.m_mapIt; - } - return true; - } - - void increment() { - switch(m_type) { - case iterator_type::None: break; - case iterator_type::Sequence: ++m_seqIt; break; - case iterator_type::Map: ++m_mapIt; break; - } - } - void decrement() { - switch(m_type) { - case iterator_type::None: break; - case iterator_type::Sequence: --m_seqIt; break; - case iterator_type::Map: --m_mapIt; break; - } - } - - V dereference() const { - switch(m_type) { - case iterator_type::None: return V(); - case iterator_type::Sequence: return V(Value(**m_seqIt, m_pMemory)); - case iterator_type::Map: return V(Value(*m_mapIt->first, m_pMemory), Value(*m_mapIt->second, m_pMemory)); - } - return V(); - } - + void increment() { this->base_reference() = this->base()->next(); } + void decrement() { this->base_reference() = this->base()->previous(); } + private: - typename iterator_type::value m_type; - shared_memory_holder m_pMemory; - - SeqIter m_seqIt; - MapIter m_mapIt; }; } } diff --git a/include/yaml-cpp/value/detail/node_iterator.h b/include/yaml-cpp/value/detail/node_iterator.h new file mode 100644 index 0000000..7d284f6 --- /dev/null +++ b/include/yaml-cpp/value/detail/node_iterator.h @@ -0,0 +1,120 @@ +#ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/value/ptr.h" +#include +#include +#include +#include +#include + +namespace YAML +{ + namespace detail + { + struct iterator_type { enum value { None, Sequence, Map }; }; + + template + struct node_iterator_value { + iterator_value(): pNode(0), pKey(0), pValue(0) {} + explicit iterator_value(V& rhs): pNode(&rhs), pKey(0), pValue(0) {} + explicit iterator_value(V& key, V& value): pNode(0), pKey(&key), pValue(&value) {} + + V *pNode; + V *pKey, *pValue; + }; + + template + class node_iterator_base: public boost::iterator_facade, node_iterator_value, std::bidirectional_iterator_tag> + { + private: + struct enabler {}; + + public: + typedef node_iterator_value value_type; + + iterator_base(): m_type(iterator_type::None) {} + explicit node_iterator_base(SeqIter seqIt): m_type(iterator_type::Sequence), m_seqIt(seqIt) {} + explicit node_iterator_base(MapIter mapIt): m_type(iterator_type::Map), m_mapIt(mapIt) {} + + template + node_iterator_base(const node_iterator_base& rhs, typename boost::enable_if, enabler>::type = enabler()) + : m_type(rhs.m_type), m_seqIt(rhs.m_seqIt), m_mapIt(rhs.m_mapIt) {} + + private: + friend class boost::iterator_core_access; + template friend class node_iterator_base; + + template + bool equal(const node_iterator_base& rhs) const { + if(m_type != rhs.m_type) + return false; + + switch(m_type) { + case iterator_type::None: return true; + case iterator_type::Sequence: return m_seqIt == rhs.m_seqIt; + case iterator_type::Map: return m_mapIt == rhs.m_mapIt; + } + return true; + } + + void increment() { + switch(m_type) { + case iterator_type::None: break; + case iterator_type::Sequence: ++m_seqIt; break; + case iterator_type::Map: ++m_mapIt; break; + } + } + + void decrement() { + switch(m_type) { + case iterator_type::None: break; + case iterator_type::Sequence: --m_seqIt; break; + case iterator_type::Map: --m_mapIt; break; + } + } + + value_type dereference() const { + switch(m_type) { + case iterator_type::None: return value_type(); + case iterator_type::Sequence: return value_type(**m_seqIt)); + case iterator_type::Map: return value_type(*m_mapIt->first, *m_mapIt->second); + } + return V(); + } + + private: + typename iterator_type::value m_type; + + SeqIter m_seqIt; + MapIter m_mapIt; + }; + + typedef std::vector node_seq; + typedef std::pair kv_pair; + typedef std::list node_map; + + template + struct node_iterator { + typedef node_seq::iterator seq; + typedef node_map::iterator map; + }; + + template + struct node_iterator { + typedef node_seq::const_iterator seq; + typedef node_map::const_iterator map; + }; + + typedef node_iterator_base node_iterator; + typedef node_iterator_base const_node_iterator; + } +} + +#endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66