From 0938714fa010b23e2d2a43606ae0eb8280c481fe Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 27 Jan 2014 03:54:05 +0000 Subject: Change xml_named_node_iterator to be bidirectional and to match xml_node_iterator in terms of internals git-svn-id: http://pugixml.googlecode.com/svn/trunk@960 99668b35-9821-0410-8761-19e4c4f06640 --- src/pugixml.cpp | 54 ++++++++++++++++++++++++++++++++++++++++-------------- src/pugixml.hpp | 16 ++++++++++++---- 2 files changed, 52 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 848b4cb..149b5d9 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -4038,7 +4038,7 @@ namespace pugi PUGI__FN xml_object_range xml_node::children(const char_t* name_) const { - return xml_object_range(xml_named_node_iterator(child(name_), name_), xml_named_node_iterator()); + return xml_object_range(xml_named_node_iterator(child(name_)._root, _root, name_), xml_named_node_iterator(0, _root, name_)); } PUGI__FN xml_object_range xml_node::attributes() const @@ -5133,36 +5133,40 @@ namespace pugi { } - PUGI__FN xml_named_node_iterator::xml_named_node_iterator(const xml_node& node, const char_t* name): _node(node), _name(name) + PUGI__FN xml_named_node_iterator::xml_named_node_iterator(const xml_node& node, const char_t* name): _wrap(node), _parent(node.parent()), _name(name) + { + } + + PUGI__FN xml_named_node_iterator::xml_named_node_iterator(xml_node_struct* ref, xml_node_struct* parent, const char_t* name): _wrap(ref), _parent(parent), _name(name) { } PUGI__FN bool xml_named_node_iterator::operator==(const xml_named_node_iterator& rhs) const { - return _node == rhs._node; + return _wrap._root == rhs._wrap._root && _parent._root == rhs._parent._root; } PUGI__FN bool xml_named_node_iterator::operator!=(const xml_named_node_iterator& rhs) const { - return _node != rhs._node; + return _wrap._root != rhs._wrap._root || _parent._root != rhs._parent._root; } PUGI__FN xml_node& xml_named_node_iterator::operator*() const { - assert(_node._root); - return _node; + assert(_wrap._root); + return _wrap; } PUGI__FN xml_node* xml_named_node_iterator::operator->() const { - assert(_node._root); - return const_cast(&_node); // BCC32 workaround + assert(_wrap._root); + return const_cast(&_wrap); // BCC32 workaround } PUGI__FN const xml_named_node_iterator& xml_named_node_iterator::operator++() { - assert(_node._root); - _node = _node.next_sibling(_name); + assert(_wrap._root); + _wrap = _wrap.next_sibling(_name); return *this; } @@ -5173,6 +5177,28 @@ namespace pugi return temp; } + PUGI__FN const xml_named_node_iterator& xml_named_node_iterator::operator--() + { + if (_wrap._root) + _wrap = _wrap.previous_sibling(_name); + else + { + _wrap = _parent.last_child(); + + if (!impl::strequal(_wrap.name(), _name)) + _wrap = _wrap.previous_sibling(_name); + } + + return *this; + } + + PUGI__FN xml_named_node_iterator xml_named_node_iterator::operator--(int) + { + xml_named_node_iterator temp = *this; + --*this; + return temp; + } + PUGI__FN xml_parse_result::xml_parse_result(): status(status_internal_error), offset(0), encoding(encoding_auto) { } @@ -5481,9 +5507,9 @@ namespace std return std::bidirectional_iterator_tag(); } - PUGI__FN std::forward_iterator_tag _Iter_cat(const pugi::xml_named_node_iterator&) + PUGI__FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_named_node_iterator&) { - return std::forward_iterator_tag(); + return std::bidirectional_iterator_tag(); } } #endif @@ -5502,9 +5528,9 @@ namespace std return std::bidirectional_iterator_tag(); } - PUGI__FN std::forward_iterator_tag __iterator_category(const pugi::xml_named_node_iterator&) + PUGI__FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_named_node_iterator&) { - return std::forward_iterator_tag(); + return std::bidirectional_iterator_tag(); } } #endif diff --git a/src/pugixml.hpp b/src/pugixml.hpp index f14c710..db1507a 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -753,6 +753,8 @@ namespace pugi // Named node range helper class PUGIXML_CLASS xml_named_node_iterator { + friend class xml_node; + public: // Iterator traits typedef ptrdiff_t difference_type; @@ -761,7 +763,7 @@ namespace pugi typedef xml_node& reference; #ifndef PUGIXML_NO_STL - typedef std::forward_iterator_tag iterator_category; + typedef std::bidirectional_iterator_tag iterator_category; #endif // Default constructor @@ -780,9 +782,15 @@ namespace pugi const xml_named_node_iterator& operator++(); xml_named_node_iterator operator++(int); + const xml_named_node_iterator& operator--(); + xml_named_node_iterator operator--(int); + private: - mutable xml_node _node; + mutable xml_node _wrap; + xml_node _parent; const char_t* _name; + + xml_named_node_iterator(xml_node_struct* ref, xml_node_struct* parent, const char_t* name); }; // Abstract tree walker class (see xml_node::traverse) @@ -1234,7 +1242,7 @@ namespace std // Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier) std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_node_iterator&); std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_attribute_iterator&); - std::forward_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_named_node_iterator&); + std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_named_node_iterator&); } #endif @@ -1244,7 +1252,7 @@ namespace std // Workarounds for (non-standard) iterator category detection std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_node_iterator&); std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_attribute_iterator&); - std::forward_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_named_node_iterator&); + std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_named_node_iterator&); } #endif -- cgit v1.2.3