From a10bb9d7660637aa23ee86cb4a741f1b7c334357 Mon Sep 17 00:00:00 2001
From: "arseny.kapoulkine@gmail.com"
 <arseny.kapoulkine@gmail.com@99668b35-9821-0410-8761-19e4c4f06640>
Date: Tue, 27 Mar 2012 05:23:24 +0000
Subject: Introduced xml_named_node_iterator, introduced xml_node::children()
 and xml_node::attributes() for C++11 range-based for loop

git-svn-id: http://pugixml.googlecode.com/svn/trunk@889 99668b35-9821-0410-8761-19e4c4f06640
---
 src/pugixml.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/pugixml.hpp | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 113 insertions(+), 1 deletion(-)

diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index bee8f4a..f6e5b5c 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -3950,6 +3950,21 @@ namespace pugi
 	{
 		return attribute_iterator(0, _root);
 	}
+    
+    PUGI__FN xml_object_range<xml_node_iterator> xml_node::children() const
+    {
+        return xml_object_range<xml_node_iterator>(begin(), end());
+    }
+
+    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());
+    }
+
+    PUGI__FN xml_object_range<xml_attribute_iterator> xml_node::attributes() const
+    {
+        return xml_object_range<xml_attribute_iterator>(attributes_begin(), attributes_end());
+    }
 
 	PUGI__FN bool xml_node::operator==(const xml_node& r) const
 	{
@@ -4982,6 +4997,47 @@ namespace pugi
 		return temp;
 	}
 
+    PUGI__FN xml_named_node_iterator::xml_named_node_iterator(): _name(0)
+    {
+    }
+
+    PUGI__FN xml_named_node_iterator::xml_named_node_iterator(const xml_node& node, const char_t* name): _node(node), _name(name)
+    {
+    }
+
+    PUGI__FN bool xml_named_node_iterator::operator==(const xml_named_node_iterator& rhs) const
+    {
+        return _node == rhs._node;
+    }
+
+    PUGI__FN bool xml_named_node_iterator::operator!=(const xml_named_node_iterator& rhs) const
+    {
+        return _node != rhs._node;
+    }
+
+    PUGI__FN xml_node& xml_named_node_iterator::operator*() const
+    {
+        return _node;
+    }
+
+    PUGI__FN xml_node* xml_named_node_iterator::operator->() const
+    {
+        return &_node;
+    }
+
+    PUGI__FN const xml_named_node_iterator& xml_named_node_iterator::operator++()
+    {
+        _node = _node.next_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)
     {
     }
@@ -5197,7 +5253,7 @@ namespace pugi
         {
             // BOM always represents the codepoint U+FEFF, so just write it in native encoding
         #ifdef PUGIXML_WCHAR_MODE
-            uint16_t bom = 0xfeff;
+            unsigned int bom = 0xfeff;
             buffered_writer.write(static_cast<wchar_t>(bom));
         #else
             buffered_writer.write('\xef', '\xbb', '\xbf');
diff --git a/src/pugixml.hpp b/src/pugixml.hpp
index 4b7a655..f4dfdf2 100644
--- a/src/pugixml.hpp
+++ b/src/pugixml.hpp
@@ -197,6 +197,7 @@ namespace pugi
 
 	class xml_node_iterator;
 	class xml_attribute_iterator;
+    class xml_named_node_iterator;
 
 	class xml_tree_walker;
 
@@ -211,6 +212,21 @@ namespace pugi
 	class xpath_variable_set;
 	#endif
 
+    // Range-based for loop support
+    template <typename It> class xml_object_range
+    {
+    public:
+        xml_object_range(It b, It e): _begin(b), _end(e)
+        {
+        }
+
+        It begin() const { return _begin; }
+        It end() const { return _end; }
+
+    private:
+        It _begin, _end;
+    };
+
 	// Writer interface for node printing (see xml_node::print)
 	class PUGIXML_CLASS xml_writer
 	{
@@ -544,6 +560,11 @@ namespace pugi
 		attribute_iterator attributes_begin() const;
 		attribute_iterator attributes_end() const;
 
+        // Range-based for support
+        xml_object_range<xml_node_iterator> children() const;
+        xml_object_range<xml_named_node_iterator> children(const char_t* name) const;
+        xml_object_range<xml_attribute_iterator> attributes() const;
+
 		// Get node offset in parsed file/string (in char_t units) for debugging purposes
 		ptrdiff_t offset_debug() const;
 
@@ -709,6 +730,41 @@ namespace pugi
 		xml_attribute_iterator operator--(int);
 	};
 
+    // Named node range helper
+    class xml_named_node_iterator
+    {
+    public:
+        // Iterator traits
+        typedef ptrdiff_t difference_type;
+        typedef xml_node value_type;
+        typedef xml_node* pointer;
+        typedef xml_node& reference;
+
+    #ifndef PUGIXML_NO_STL
+        typedef std::forward_iterator_tag iterator_category;
+    #endif
+
+        // Default constructor
+        xml_named_node_iterator();
+
+        // Construct an iterator which points to the specified node
+        xml_named_node_iterator(const xml_node& node, const char_t* name);
+
+        // Iterator operators
+        bool operator==(const xml_named_node_iterator& rhs) const;
+        bool operator!=(const xml_named_node_iterator& rhs) const;
+
+        xml_node& operator*() const;
+        xml_node* operator->() const;
+
+        const xml_named_node_iterator& operator++();
+        xml_named_node_iterator operator++(int);
+
+    private:
+        mutable xml_node _node;
+        const char_t* _name;
+    };
+
 	// Abstract tree walker class (see xml_node::traverse)
 	class PUGIXML_CLASS xml_tree_walker
 	{
-- 
cgit v1.2.3