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
This commit is contained in:
parent
4d8974f1fd
commit
0938714fa0
@ -4038,7 +4038,7 @@ namespace pugi
|
|||||||
|
|
||||||
PUGI__FN xml_object_range<xml_named_node_iterator> xml_node::children(const char_t* name_) const
|
PUGI__FN xml_object_range<xml_named_node_iterator> xml_node::children(const char_t* name_) const
|
||||||
{
|
{
|
||||||
return xml_object_range<xml_named_node_iterator>(xml_named_node_iterator(child(name_), name_), xml_named_node_iterator());
|
return xml_object_range<xml_named_node_iterator>(xml_named_node_iterator(child(name_)._root, _root, name_), xml_named_node_iterator(0, _root, name_));
|
||||||
}
|
}
|
||||||
|
|
||||||
PUGI__FN xml_object_range<xml_attribute_iterator> xml_node::attributes() const
|
PUGI__FN xml_object_range<xml_attribute_iterator> 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
|
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
|
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
|
PUGI__FN xml_node& xml_named_node_iterator::operator*() const
|
||||||
{
|
{
|
||||||
assert(_node._root);
|
assert(_wrap._root);
|
||||||
return _node;
|
return _wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
PUGI__FN xml_node* xml_named_node_iterator::operator->() const
|
PUGI__FN xml_node* xml_named_node_iterator::operator->() const
|
||||||
{
|
{
|
||||||
assert(_node._root);
|
assert(_wrap._root);
|
||||||
return const_cast<xml_node*>(&_node); // BCC32 workaround
|
return const_cast<xml_node*>(&_wrap); // BCC32 workaround
|
||||||
}
|
}
|
||||||
|
|
||||||
PUGI__FN const xml_named_node_iterator& xml_named_node_iterator::operator++()
|
PUGI__FN const xml_named_node_iterator& xml_named_node_iterator::operator++()
|
||||||
{
|
{
|
||||||
assert(_node._root);
|
assert(_wrap._root);
|
||||||
_node = _node.next_sibling(_name);
|
_wrap = _wrap.next_sibling(_name);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5173,6 +5177,28 @@ namespace pugi
|
|||||||
return temp;
|
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)
|
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();
|
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
|
#endif
|
||||||
@ -5502,9 +5528,9 @@ namespace std
|
|||||||
return std::bidirectional_iterator_tag();
|
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
|
#endif
|
||||||
|
|||||||
@ -753,6 +753,8 @@ namespace pugi
|
|||||||
// Named node range helper
|
// Named node range helper
|
||||||
class PUGIXML_CLASS xml_named_node_iterator
|
class PUGIXML_CLASS xml_named_node_iterator
|
||||||
{
|
{
|
||||||
|
friend class xml_node;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Iterator traits
|
// Iterator traits
|
||||||
typedef ptrdiff_t difference_type;
|
typedef ptrdiff_t difference_type;
|
||||||
@ -761,7 +763,7 @@ namespace pugi
|
|||||||
typedef xml_node& reference;
|
typedef xml_node& reference;
|
||||||
|
|
||||||
#ifndef PUGIXML_NO_STL
|
#ifndef PUGIXML_NO_STL
|
||||||
typedef std::forward_iterator_tag iterator_category;
|
typedef std::bidirectional_iterator_tag iterator_category;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Default constructor
|
// Default constructor
|
||||||
@ -780,9 +782,15 @@ namespace pugi
|
|||||||
const xml_named_node_iterator& operator++();
|
const xml_named_node_iterator& operator++();
|
||||||
xml_named_node_iterator operator++(int);
|
xml_named_node_iterator operator++(int);
|
||||||
|
|
||||||
|
const xml_named_node_iterator& operator--();
|
||||||
|
xml_named_node_iterator operator--(int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable xml_node _node;
|
mutable xml_node _wrap;
|
||||||
|
xml_node _parent;
|
||||||
const char_t* _name;
|
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)
|
// 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)
|
// 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_node_iterator&);
|
||||||
std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_attribute_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
|
#endif
|
||||||
|
|
||||||
@ -1244,7 +1252,7 @@ namespace std
|
|||||||
// Workarounds for (non-standard) iterator category detection
|
// 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_node_iterator&);
|
||||||
std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_attribute_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
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -22,12 +22,6 @@ template <typename I> static I move_iter(I base, int n)
|
|||||||
else while (n++) --base;
|
else while (n++) --base;
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static xml_named_node_iterator move_iter(xml_named_node_iterator base, int n)
|
|
||||||
{
|
|
||||||
while (n--) ++base;
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
template <typename I> static I move_iter(I base, int n)
|
template <typename I> static I move_iter(I base, int n)
|
||||||
{
|
{
|
||||||
@ -919,36 +913,51 @@ TEST_XML(dom_hash_value, "<node attr='value'>value</node>")
|
|||||||
CHECK(attr_copy.hash_value() == attr.hash_value());
|
CHECK(attr_copy.hash_value() == attr.hash_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_XML(dom_node_named_iterator, "<node><node1><child/></node1><node2><child/><child/></node2><node3/></node>")
|
TEST_XML(dom_node_named_iterator, "<node><node1><child/></node1><node2><child/><child/></node2><node3/><node4><child/><x/></node4></node>")
|
||||||
{
|
{
|
||||||
xml_node node1 = doc.child(STR("node")).child(STR("node1"));
|
xml_node node1 = doc.child(STR("node")).child(STR("node1"));
|
||||||
xml_node node2 = doc.child(STR("node")).child(STR("node2"));
|
xml_node node2 = doc.child(STR("node")).child(STR("node2"));
|
||||||
xml_node node3 = doc.child(STR("node")).child(STR("node3"));
|
xml_node node3 = doc.child(STR("node")).child(STR("node3"));
|
||||||
|
xml_node node4 = doc.child(STR("node")).child(STR("node4"));
|
||||||
|
|
||||||
CHECK(xml_named_node_iterator(xml_node(), STR("child")) == xml_named_node_iterator());
|
CHECK(xml_named_node_iterator(xml_node(), STR("child")) == xml_named_node_iterator());
|
||||||
|
|
||||||
xml_named_node_iterator it1(node1.child(STR("child")), STR("child"));
|
xml_object_range<xml_named_node_iterator> r1 = node1.children(STR("child"));
|
||||||
CHECK(move_iter(it1, 1) == xml_named_node_iterator());
|
xml_object_range<xml_named_node_iterator> r2 = node2.children(STR("child"));
|
||||||
CHECK(*it1 == node1.child(STR("child")));
|
xml_object_range<xml_named_node_iterator> r3 = node3.children(STR("child"));
|
||||||
CHECK_STRING(it1->name(), STR("child"));
|
xml_object_range<xml_named_node_iterator> r4 = node4.children(STR("child"));
|
||||||
|
|
||||||
xml_named_node_iterator it2(node2.child(STR("child")), STR("child"));
|
CHECK(r1.begin() != r1.end());
|
||||||
CHECK(move_iter(it2, 1) != xml_named_node_iterator());
|
CHECK(*r1.begin() == node1.first_child());
|
||||||
CHECK(move_iter(it2, 2) == xml_named_node_iterator());
|
CHECK(r1.begin() == move_iter(r1.end(), -1));
|
||||||
CHECK(*it2 == node2.first_child());
|
CHECK(move_iter(r1.begin(), 1) == r1.end());
|
||||||
CHECK(*move_iter(it2, 1) == node2.last_child());
|
|
||||||
|
|
||||||
xml_named_node_iterator it3(node3.child(STR("child")), STR("child"));
|
CHECK(r2.begin() != r2.end());
|
||||||
CHECK(it3 == xml_named_node_iterator());
|
CHECK(*r2.begin() == node2.first_child());
|
||||||
|
CHECK(*move_iter(r2.begin(), 1) == node2.last_child());
|
||||||
|
CHECK(r2.begin() == move_iter(r2.end(), -2));
|
||||||
|
CHECK(move_iter(r2.begin(), 1) == move_iter(r2.end(), -1));
|
||||||
|
CHECK(move_iter(r2.begin(), 2) == r2.end());
|
||||||
|
|
||||||
xml_named_node_iterator it = xml_named_node_iterator(node1.child(STR("child")), STR("child"));
|
CHECK(r3.begin() == r3.end());
|
||||||
|
CHECK(!(r3.begin() != r3.end()));
|
||||||
|
|
||||||
|
CHECK(r4.begin() != r4.end());
|
||||||
|
CHECK(*r4.begin() == node4.first_child());
|
||||||
|
CHECK(r4.begin() == move_iter(r4.end(), -1));
|
||||||
|
CHECK(move_iter(r4.begin(), 1) == r4.end());
|
||||||
|
|
||||||
|
xml_named_node_iterator it = r1.begin();
|
||||||
xml_named_node_iterator itt = it;
|
xml_named_node_iterator itt = it;
|
||||||
|
|
||||||
CHECK(itt == it);
|
CHECK(itt == it);
|
||||||
|
|
||||||
CHECK(itt++ == it);
|
CHECK(itt++ == it);
|
||||||
CHECK(itt == xml_named_node_iterator());
|
CHECK(itt == r1.end());
|
||||||
|
|
||||||
CHECK(itt != it);
|
CHECK(itt != it);
|
||||||
CHECK(itt == ++it);
|
CHECK(itt == ++it);
|
||||||
|
|
||||||
|
CHECK(itt-- == r1.end());
|
||||||
|
CHECK(itt == r1.begin());
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user