Browse Source

Move iterators to separate file

Michael Ragazzon 6 years ago
parent
commit
68eefcaeb0

+ 2 - 0
Build/cmake/FileList.cmake

@@ -164,6 +164,7 @@ set(Core_PUB_HDR_FILES
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/Property.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/PropertyDefinition.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/PropertyDictionary.h
+    ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/PropertyIterators.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/PropertyParser.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/PropertySpecification.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/ReferenceCountable.h
@@ -290,6 +291,7 @@ set(Core_SRC_FILES
     ${PROJECT_SOURCE_DIR}/Source/Core/Property.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/PropertyDefinition.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/PropertyDictionary.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyIterators.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserAnimation.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserColour.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserKeyword.cpp

+ 1 - 0
Include/Rocket/Core/Core.h

@@ -64,6 +64,7 @@
 #include "Property.h"
 #include "PropertyDefinition.h"
 #include "PropertyDictionary.h"
+#include "PropertyIterators.h"
 #include "PropertyParser.h"
 #include "PropertySpecification.h"
 #include "RenderInterface.h"

+ 124 - 0
Include/Rocket/Core/PropertyIterators.h

@@ -0,0 +1,124 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+#ifndef ROCKETCOREPROPERTYITERATORS_H
+#define ROCKETCOREPROPERTYITERATORS_H
+
+#include "Types.h"
+
+namespace Rocket {
+namespace Core {
+
+/**
+	Provides iterators for properties defined in the element's style or definition.
+	@author Michael R. P. Ragazzon
+ */
+
+
+// Iterates over the properties of an element definition matching the given pseudo classes.
+// Note: Modifying the underlying definition invalidates the iterator.
+// Note: 'pseudo_classes' must outlive the iterator.
+class ROCKETCORE_API ElementDefinitionIterator {
+public:
+	using difference_type = std::ptrdiff_t;
+	using value_type = std::pair<const String&, const Property&>;
+	using pointer = value_type*;
+	using reference = value_type&;
+	using iterator_category = std::input_iterator_tag;
+
+	using PropertyIt = PropertyMap::const_iterator;
+	using PseudoIt = PseudoClassPropertyDictionary::const_iterator;
+
+	ElementDefinitionIterator();
+	ElementDefinitionIterator(const StringList& pseudo_classes, PropertyIt it_properties, PseudoIt it_pseudo_class_properties, PropertyIt it_properties_end, PseudoIt it_pseudo_class_properties_end);
+	ElementDefinitionIterator& operator++();
+	bool operator==(const ElementDefinitionIterator& other) const { return pseudo_classes == other.pseudo_classes && it_properties == other.it_properties && it_pseudo_class_properties == other.it_pseudo_class_properties && i_pseudo_class == other.i_pseudo_class; }
+	bool operator!=(const ElementDefinitionIterator& other) const { return !(*this == other); }
+	
+	value_type operator*() const 
+	{
+		if (it_properties != it_properties_end)
+			return { it_properties->first, it_properties->second };
+		return { it_pseudo_class_properties->first,  it_pseudo_class_properties->second[i_pseudo_class].second };
+	}
+
+	// Return the list of pseudo classes which defines the current property, possibly null
+	const PseudoClassList* pseudo_class_list() const;
+
+private:
+	const StringList* pseudo_classes;
+	PropertyIt it_properties, it_properties_end;
+	PseudoIt it_pseudo_class_properties, it_pseudo_class_properties_end;
+	size_t i_pseudo_class = 0;
+
+	void proceed_to_next_valid();
+};
+
+
+
+// An iterator for local properties defined on an element.
+// Note: Modifying the underlying style invalidates the iterator.
+class ROCKETCORE_API ElementStyleIterator {
+public:
+	using difference_type = std::ptrdiff_t;
+	using value_type = std::pair<const String&, const Property&>;
+	using pointer = value_type *;
+	using reference = value_type &;
+	using iterator_category = std::input_iterator_tag;
+
+	using PropertyIt = PropertyMap::const_iterator;
+	using DefinitionIt = ElementDefinitionIterator;
+
+	ElementStyleIterator();
+	ElementStyleIterator(const PropertyMap* property_map, PropertyIt it_properties, DefinitionIt it_definition, PropertyIt it_properties_end, DefinitionIt it_definition_end);
+
+	ElementStyleIterator& operator++();
+	bool operator==(const ElementStyleIterator& other) const { return property_map == other.property_map && it_properties == other.it_properties && it_definition == other.it_definition; }
+	bool operator!=(const ElementStyleIterator& other) const { return !(*this == other); }
+
+	value_type operator*() const 
+	{
+		if (it_properties != it_properties_end)
+			return { it_properties->first, it_properties->second };
+		return *it_definition;
+	}
+
+	// Return the list of pseudo classes which defines the current property, possibly null
+	const PseudoClassList* pseudo_class_list() const;
+
+private:
+	const PropertyMap* property_map;
+	PropertyIt it_properties, it_properties_end;
+	DefinitionIt it_definition, it_definition_end;
+
+	void proceed_to_next_valid();
+};
+
+
+}
+}
+
+#endif

+ 9 - 0
Include/Rocket/Core/Types.h

@@ -132,6 +132,15 @@ typedef std::shared_ptr< Transform > TransformRef;
 struct Transition;
 struct TransitionList;
 
+// Pseudo class properties
+// Defines for the optimised version of the pseudo-class properties (note the difference from the
+// PseudoClassPropertyMap defined in StyleSheetNode.h ... bit clumsy). Here the properties are stored as a list
+// of definitions against each property name in specificity-order, along with the pseudo-class requirements for each
+// one. This makes it much more straight-forward to query at run-time.
+typedef std::pair< StringList, Property > PseudoClassProperty;
+typedef std::vector< PseudoClassProperty > PseudoClassPropertyList;
+typedef SmallUnorderedMap< String, PseudoClassPropertyList > PseudoClassPropertyDictionary;
+
 }
 }
 

+ 9 - 0
Source/Core/ElementDefinition.cpp

@@ -31,6 +31,7 @@
 #include "../../Include/Rocket/Core/Factory.h"
 #include "../../Include/Rocket/Core/FontDatabase.h"
 #include "../../Include/Rocket/Core/Log.h"
+#include "../../Include/Rocket/Core/PropertyIterators.h"
 
 namespace Rocket {
 namespace Core {
@@ -337,6 +338,14 @@ bool ElementDefinition::IsStructurallyVolatile() const
 	return structurally_volatile;
 }
 
+ElementDefinitionIterator ElementDefinition::begin(const StringList& pseudo_classes) const {
+	return ElementDefinitionIterator(pseudo_classes, properties.GetProperties().begin(), pseudo_class_properties.begin(), properties.GetProperties().end(), pseudo_class_properties.end());
+}
+
+ElementDefinitionIterator ElementDefinition::end(const StringList& pseudo_classes) const {
+	return ElementDefinitionIterator(pseudo_classes, properties.GetProperties().end(), pseudo_class_properties.end(), properties.GetProperties().end(), pseudo_class_properties.end());
+}
+
 // Destroys the definition.
 void ElementDefinition::OnReferenceDeactivate()
 {

+ 5 - 97
Source/Core/ElementDefinition.h

@@ -39,14 +39,7 @@ namespace Core {
 
 class Decorator;
 class FontEffect;
-
-// Defines for the optimised version of the pseudo-class properties (note the difference from the
-// PseudoClassPropertyMap defined in StyleSheetNode.h ... bit clumsy). Here the properties are stored as a list
-// of definitions against each property name in specificity-order, along with the pseudo-class requirements for each
-// one. This makes it much more straight-forward to query at run-time.
-typedef std::pair< StringList, Property > PseudoClassProperty;
-typedef std::vector< PseudoClassProperty > PseudoClassPropertyList;
-typedef SmallUnorderedMap< String, PseudoClassPropertyList > PseudoClassPropertyDictionary;
+class ElementDefinitionIterator;
 
 typedef SmallUnorderedMap< String, Decorator* > DecoratorMap;
 typedef std::map< StringList, DecoratorMap > PseudoClassDecoratorMap;
@@ -121,95 +114,13 @@ public:
 	/// @return True if this definition is structurally volatile.
 	bool IsStructurallyVolatile() const;
 
-
-	class Iterator {
-	public:
-		using difference_type = std::ptrdiff_t;
-		using value_type = std::pair<const String&, const Property&>;
-		using pointer = value_type*;
-		using reference = value_type&;
-		using iterator_category = std::input_iterator_tag;
-
-		using PropertyIt = PropertyMap::const_iterator;
-		using PseudoIt = PseudoClassPropertyDictionary::const_iterator;
-
-		Iterator() : pseudo_classes(nullptr) {}
-		Iterator(const StringList& pseudo_classes, PropertyIt it_properties, PseudoIt it_pseudo_class_properties, PropertyIt it_properties_end, PseudoIt it_pseudo_class_properties_end)
-			: pseudo_classes(&pseudo_classes), it_properties(it_properties), it_pseudo_class_properties(it_pseudo_class_properties), it_properties_end(it_properties_end), it_pseudo_class_properties_end(it_pseudo_class_properties_end)
-		{
-			proceed_to_next_valid();
-		}
-		Iterator& operator++()
-		{
-			// The iteration proceeds as follows:
-			//  1. Iterate over all the default properties of the element (with no pseudo classes)
-			//  2. Iterate over each pseudo class that has a definition for this property,
-			//      testing each one to see if it matches the currently set pseudo classes.
-			if (it_properties != it_properties_end)
-			{
-				++it_properties;
-				proceed_to_next_valid();
-				return *this;
-			}
-			++i_pseudo_class;
-			proceed_to_next_valid();
-			return *this;
-		}
-		bool operator==(Iterator other) const { return pseudo_classes == other.pseudo_classes && it_properties == other.it_properties && it_pseudo_class_properties == other.it_pseudo_class_properties && i_pseudo_class == other.i_pseudo_class; }
-		bool operator!=(Iterator other) const { return !(*this == other); }
-		value_type operator*() const {
-			if (it_properties != it_properties_end)
-				return { it_properties->first, it_properties->second };
-			return { it_pseudo_class_properties->first,  it_pseudo_class_properties->second[i_pseudo_class].second };
-		}
-
-		// Return the list of pseudo classes which defines the current property, possibly null
-		const PseudoClassList* pseudo_class_list() const
-		{
-			if (it_properties != it_properties_end)
-				return nullptr;
-			return &it_pseudo_class_properties->second[i_pseudo_class].first;
-		}
-
-	private:
-		const StringList* pseudo_classes;
-		PropertyIt it_properties, it_properties_end;
-		PseudoIt it_pseudo_class_properties, it_pseudo_class_properties_end;
-		size_t i_pseudo_class = 0;
-
-		void proceed_to_next_valid()
-		{
-			if (it_properties == it_properties_end)
-			{
-				// Iterate over all the pseudo classes and match the applicable rules
-				for (; it_pseudo_class_properties != it_pseudo_class_properties_end; ++it_pseudo_class_properties)
-				{
-					const PseudoClassPropertyList& pseudo_list = it_pseudo_class_properties->second;
-					for (; i_pseudo_class < pseudo_list.size(); ++i_pseudo_class)
-					{
-						if (IsPseudoClassRuleApplicable(pseudo_list[i_pseudo_class].first, *pseudo_classes))
-						{
-							return;
-						}
-					}
-					i_pseudo_class = 0;
-				}
-			}
-		}
-	};
-
-
 	/// Returns an iterator to the first property matching the active set of pseudo_classes.
-	/// Note: Modifying the element definition or pseudo classes invalidates the iterators.
-	/// Note: The lifetime of pseudo_classes must extend beyond the iterators.
-	Iterator begin(const StringList& pseudo_classes) const {
-		return Iterator(pseudo_classes, properties.GetProperties().begin(), pseudo_class_properties.begin(), properties.GetProperties().end(), pseudo_class_properties.end());
-	}
+	ElementDefinitionIterator begin(const StringList& pseudo_classes) const;
 	/// Returns an iterator to the property following the last property matching the active set of pseudo_classes.
-	Iterator end(const StringList& pseudo_classes) const {
-		return Iterator(pseudo_classes, properties.GetProperties().end(), pseudo_class_properties.end(), properties.GetProperties().end(), pseudo_class_properties.end());
-	}
+	ElementDefinitionIterator end(const StringList& pseudo_classes) const;
 
+	/// Returns true if the pseudo-class requirement of a rule is met by a list of an element's pseudo-classes.
+	static bool IsPseudoClassRuleApplicable(const StringList& rule_pseudo_classes, const PseudoClassList& element_pseudo_classes);
 
 protected:
 	/// Destroys the definition.
@@ -241,9 +152,6 @@ private:
 	// Attempts to instance a font effect.
 	bool InstanceFontEffect(const String& name, const String& type, const PropertyDictionary& properties, const StringList& pseudo_class = StringList());
 
-	// Returns true if the pseudo-class requirement of a rule is met by a list of an element's pseudo-classes.
-	static bool IsPseudoClassRuleApplicable(const StringList& rule_pseudo_classes, const PseudoClassList& element_pseudo_classes);
-
 	// The attributes for the default state of the element, with no pseudo-classes.
 	PropertyDictionary properties;
 	// The overridden attributes for the element's pseudo-classes.

+ 2 - 2
Source/Core/ElementStyle.cpp

@@ -607,7 +607,7 @@ ElementStyleIterator ElementStyle::begin() const {
 		it_local_begin = local->begin();
 		it_local_end = local->end();
 	}
-	ElementDefinition::Iterator it_definition_begin, it_definition_end;
+	ElementDefinitionIterator it_definition_begin, it_definition_end;
 	if (definition)
 	{
 		it_definition_begin = definition->begin(pseudo_classes);
@@ -624,7 +624,7 @@ ElementStyleIterator ElementStyle::end() const {
 		local = &local_properties->GetProperties();
 		it_local_end = local->end();
 	}
-	ElementDefinition::Iterator it_definition_end;
+	ElementDefinitionIterator it_definition_end;
 	if (definition)
 	{
 		it_definition_end = definition->end(pseudo_classes);

+ 0 - 72
Source/Core/ElementStyle.h

@@ -56,7 +56,6 @@ public:
 		all_dirty = true;
 		dirty_list.clear();
 	}
-
 	void Clear() {
 		all_dirty = false;
 		dirty_list.clear();
@@ -65,18 +64,15 @@ public:
 	bool Empty() const {
 		return !all_dirty && dirty_list.empty();
 	}
-
 	bool Contains(const String & name) const {
 		if (all_dirty)
 			return true;
 		auto it = dirty_list.find(name);
 		return (it != dirty_list.end());
 	}
-
 	bool AllDirty() const {
 		return all_dirty;
 	}
-
 	const PropertyNameList& GetList() const {
 		return dirty_list;
 	}
@@ -84,74 +80,6 @@ public:
 
 
 
-class ElementStyleIterator {
-public:
-	using difference_type = std::ptrdiff_t;
-	using value_type = std::pair<const String&, const Property&>;
-	using pointer = value_type *;
-	using reference = value_type &;
-	using iterator_category = std::input_iterator_tag;
-
-	using PropertyIt = PropertyMap::const_iterator;
-	using DefinitionIt = ElementDefinition::Iterator;
-
-	ElementStyleIterator() : property_map(nullptr) {}
-	ElementStyleIterator(const PropertyMap* property_map, PropertyIt it_properties, DefinitionIt it_definition, PropertyIt it_properties_end, DefinitionIt it_definition_end)
-		: property_map(property_map), it_properties(it_properties), it_definition(it_definition), it_properties_end(it_properties_end), it_definition_end(it_definition_end)
-	{
-		proceed_to_next_valid();
-	}
-	ElementStyleIterator& operator++()
-	{
-		// First, we iterate over the local properties
-		if (it_properties != it_properties_end)
-		{
-			++it_properties;
-			proceed_to_next_valid();
-			return *this;
-		}
-		// Then, we iterate over the properties given by the element's definition
-		++it_definition;
-		proceed_to_next_valid();
-		return *this;
-	}
-	bool operator==(ElementStyleIterator other) const { return property_map == other.property_map && it_properties == other.it_properties && it_definition == other.it_definition; }
-	bool operator!=(ElementStyleIterator other) const { return !(*this == other); }
-	value_type operator*() const {
-		if (it_properties != it_properties_end)
-			return { it_properties->first, it_properties->second };
-		return *it_definition;
-	}
-
-	// Return the list of pseudo classes which defines the current property, possibly null
-	const PseudoClassList* pseudo_class_list() const
-	{
-		if (it_properties != it_properties_end)
-			return nullptr;
-		return it_definition.pseudo_class_list();
-	}
-
-private:
-	const PropertyMap* property_map;
-	PropertyIt it_properties, it_properties_end;
-	DefinitionIt it_definition, it_definition_end;
-
-	void proceed_to_next_valid()
-	{
-		// If we've reached the end of the local properties, continue iteration on the definition
-		if (it_properties == it_properties_end)
-		{
-			for (; it_definition != it_definition_end; ++it_definition)
-			{
-				// Skip this property if it has been overridden by the element's local properties
-				if (property_map && property_map->count((*it_definition).first))
-					continue;
-				return;
-			}
-		}
-	}
-};
-
 
 /**
 	Manages an element's style and property information.

+ 139 - 0
Source/Core/PropertyIterators.cpp

@@ -0,0 +1,139 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "precompiled.h"
+#include "../../Include/Rocket/Core/PropertyIterators.h"
+#include "ElementDefinition.h"
+
+namespace Rocket {
+namespace Core {
+
+
+// Return the list of pseudo classes which defines the current property, possibly null
+ElementDefinitionIterator::ElementDefinitionIterator() : pseudo_classes(nullptr) {}
+
+ElementDefinitionIterator::ElementDefinitionIterator(const StringList& pseudo_classes, PropertyIt it_properties, PseudoIt it_pseudo_class_properties, PropertyIt it_properties_end, PseudoIt it_pseudo_class_properties_end)
+	: pseudo_classes(&pseudo_classes), it_properties(it_properties), it_pseudo_class_properties(it_pseudo_class_properties), it_properties_end(it_properties_end), it_pseudo_class_properties_end(it_pseudo_class_properties_end)
+{
+	proceed_to_next_valid();
+}
+
+const PseudoClassList* ElementDefinitionIterator::pseudo_class_list() const
+{
+	if (it_properties != it_properties_end)
+		return nullptr;
+	return &it_pseudo_class_properties->second[i_pseudo_class].first;
+}
+
+ElementDefinitionIterator& ElementDefinitionIterator::operator++()
+{
+	// The iteration proceeds as follows:
+	//  1. Iterate over all the default properties of the element (with no pseudo classes)
+	//  2. Iterate over each pseudo class that has a definition for this property,
+	//      testing each one to see if it matches the currently set pseudo classes.
+	if (it_properties != it_properties_end)
+	{
+		++it_properties;
+		proceed_to_next_valid();
+		return *this;
+	}
+	++i_pseudo_class;
+	proceed_to_next_valid();
+	return *this;
+}
+
+void ElementDefinitionIterator::proceed_to_next_valid()
+{
+	if (it_properties == it_properties_end)
+	{
+		// Iterate over all the pseudo classes and match the applicable rules
+		for (; it_pseudo_class_properties != it_pseudo_class_properties_end; ++it_pseudo_class_properties)
+		{
+			const PseudoClassPropertyList& pseudo_list = it_pseudo_class_properties->second;
+			for (; i_pseudo_class < pseudo_list.size(); ++i_pseudo_class)
+			{
+				if (ElementDefinition::IsPseudoClassRuleApplicable(pseudo_list[i_pseudo_class].first, *pseudo_classes))
+				{
+					return;
+				}
+			}
+			i_pseudo_class = 0;
+		}
+	}
+}
+
+ElementStyleIterator& ElementStyleIterator::operator++()
+{
+	// First, we iterate over the local properties
+	if (it_properties != it_properties_end)
+	{
+		++it_properties;
+		proceed_to_next_valid();
+		return *this;
+	}
+	// Then, we iterate over the properties given by the element's definition
+	++it_definition;
+	proceed_to_next_valid();
+	return *this;
+}
+
+
+void ElementStyleIterator::proceed_to_next_valid()
+{
+	// If we've reached the end of the local properties, continue iteration on the definition
+	if (it_properties == it_properties_end)
+	{
+		for (; it_definition != it_definition_end; ++it_definition)
+		{
+			// Skip this property if it has been overridden by the element's local properties
+			if (property_map && property_map->count((*it_definition).first))
+				continue;
+			return;
+		}
+	}
+}
+
+
+// Return the list of pseudo classes which defines the current property, possibly null
+
+const PseudoClassList* ElementStyleIterator::pseudo_class_list() const
+{
+	if (it_properties != it_properties_end)
+		return nullptr;
+	return it_definition.pseudo_class_list();
+}
+
+ElementStyleIterator::ElementStyleIterator() : property_map(nullptr) {}
+
+ElementStyleIterator::ElementStyleIterator(const PropertyMap* property_map, PropertyIt it_properties, DefinitionIt it_definition, PropertyIt it_properties_end, DefinitionIt it_definition_end)
+	: property_map(property_map), it_properties(it_properties), it_definition(it_definition), it_properties_end(it_properties_end), it_definition_end(it_definition_end)
+{
+	proceed_to_next_valid();
+}
+
+}
+}