From 93bb5dcb43a8f80044a12fab962ba546bcb5df6a Mon Sep 17 00:00:00 2001
From: "arseny.kapoulkine"
 <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640>
Date: Thu, 22 Jul 2010 07:54:34 +0000
Subject: XPath: Restored document order sorting optimization (it's now
 automatic for nodes that were loaded and not significantly altered), minor
 traversal optimizations

git-svn-id: http://pugixml.googlecode.com/svn/trunk@613 99668b35-9821-0410-8761-19e4c4f06640
---
 src/pugixml.cpp   | 14 ++++++++++--
 src/pugixml.hpp   |  6 ++---
 src/pugixpath.cpp | 67 +++++++++++++++++++++++++------------------------------
 3 files changed, 44 insertions(+), 43 deletions(-)

(limited to 'src')

diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 3f37e65..3792c40 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -3216,8 +3216,13 @@ namespace pugi
 		return (_attr && _attr->value) ? _attr->value : PUGIXML_TEXT("");
 	}
 
-	unsigned int xml_attribute::document_order() const
+	const void* xml_attribute::document_order() const
 	{
+		if (!_attr) return 0;
+
+		if ((_attr->header & xml_memory_page_name_allocated_mask) == 0) return _attr->name;
+		if ((_attr->header & xml_memory_page_value_allocated_mask) == 0) return _attr->value;
+
 		return 0;
 	}
 
@@ -4014,8 +4019,13 @@ namespace pugi
 		return walker.end(arg_end);
 	}
 
-	unsigned int xml_node::document_order() const
+	const void* xml_node::document_order() const
 	{
+		if (!_root) return 0;
+
+		if (_root->name && (_root->header & xml_memory_page_name_allocated_mask) == 0) return _root->name;
+		if (_root->value && (_root->header & xml_memory_page_value_allocated_mask) == 0) return _root->value;
+
 		return 0;
 	}
 
diff --git a/src/pugixml.hpp b/src/pugixml.hpp
index 281a0ea..81f5769 100644
--- a/src/pugixml.hpp
+++ b/src/pugixml.hpp
@@ -646,8 +646,7 @@ namespace pugi
 		bool as_bool() const;
 
 		/// \internal Document order or 0 if not set
-		/// \deprecated This function is deprecated
-		PUGIXML_DEPRECATED unsigned int document_order() const;
+		const void* document_order() const;
 
 	public:
 		/**
@@ -1466,8 +1465,7 @@ namespace pugi
 	#endif
 		
 		/// \internal Document order or 0 if not set
-		/// \deprecated This function is deprecated
-		PUGIXML_DEPRECATED unsigned int document_order() const;
+		const void* document_order() const;
 
 		/**
 		 * Print subtree to writer
diff --git a/src/pugixpath.cpp b/src/pugixpath.cpp
index 775706c..e9b7bc0 100644
--- a/src/pugixpath.cpp
+++ b/src/pugixpath.cpp
@@ -143,28 +143,22 @@ namespace
 
 				xml_node cur = n.first_child();
 				
-				if (cur)
+				while (cur && cur != n)
 				{
-					do 
+					if (cur.type() == node_pcdata || cur.type() == node_cdata)
+						result += cur.value();
+
+					if (cur.first_child())
+						cur = cur.first_child();
+					else if (cur.next_sibling())
+						cur = cur.next_sibling();
+					else
 					{
-						if (cur.type() == node_pcdata || cur.type() == node_cdata)
-							result += cur.value();
-						
-						if (cur.first_child())
-							cur = cur.first_child();
-						else if (cur.next_sibling())
-							cur = cur.next_sibling();
-						else
-						{
-							// Borland C++ workaround
-							while (!cur.next_sibling() && cur != n && (bool)cur.parent())
-								cur = cur.parent();
-						
-							if (cur != n)
-								cur = cur.next_sibling();
-						}
+						while (!cur.next_sibling() && cur != n)
+							cur = cur.parent();
+
+						if (cur != n) cur = cur.next_sibling();
 					}
-					while (cur && cur != n);
 				}
 				
 				return result;
@@ -228,6 +222,11 @@ namespace
 		{
 			xml_node ln = lhs.node(), rn = rhs.node();
 
+			const void* lo = lhs.attribute() ? lhs.attribute().document_order() : ln.document_order();
+			const void* ro = rhs.attribute() ? rhs.attribute().document_order() : rn.document_order();
+
+			if (lo && ro) return lo < ro;
+
 			if (lhs.attribute() && rhs.attribute())
 			{
 				if (lhs.parent() == rhs.parent())
@@ -1642,27 +1641,21 @@ namespace pugi
 					
 				xml_node cur = n.first_child();
 				
-				if (cur)
+				while (cur && cur != n)
 				{
-					do 
+					step_push(ns, cur);
+					
+					if (cur.first_child())
+						cur = cur.first_child();
+					else if (cur.next_sibling())
+						cur = cur.next_sibling();
+					else
 					{
-						step_push(ns, cur);
-						
-						if (cur.first_child())
-							cur = cur.first_child();
-						else if (cur.next_sibling())
-							cur = cur.next_sibling();
-						else
-						{
-							// Borland C++ workaround
-							while (!cur.next_sibling() && cur != n && (bool)cur.parent())
-								cur = cur.parent();
-						
-							if (cur != n)
-								cur = cur.next_sibling();
-						}
+						while (!cur.next_sibling() && cur != n)
+							cur = cur.parent();
+					
+						if (cur != n) cur = cur.next_sibling();
 					}
-					while (cur && cur != n);
 				}
 				
 				break;
-- 
cgit v1.2.3