From bb67c5fa2626784163e855ce054c376b64fbe14e Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Fri, 11 Apr 2014 09:41:44 +0200
Subject: [PATCH] transform internals of regexp elements

---
 alib2/src/regexp/Alternation.cpp         |  6 +++---
 alib2/src/regexp/Alternation.h           |  8 ++++----
 alib2/src/regexp/Concatenation.cpp       |  2 +-
 alib2/src/regexp/Concatenation.h         |  2 +-
 alib2/src/regexp/RegExpElement.h         |  7 +++++++
 alib2/src/regexp/RegExpFromXMLParser.cpp | 20 ++++++++++----------
 alib2/src/regexp/RegExpFromXMLParser.h   |  1 -
 7 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/alib2/src/regexp/Alternation.cpp b/alib2/src/regexp/Alternation.cpp
index 4c9fa359f1..1e37e35446 100644
--- a/alib2/src/regexp/Alternation.cpp
+++ b/alib2/src/regexp/Alternation.cpp
@@ -15,7 +15,7 @@ Alternation::Alternation() {
 
 Alternation::Alternation(const Alternation& other) {
 	for (const auto& element : other.elements) {
-		elements.push_back(element->clone());
+		elements.insert(element->clone());
 	}
 }
 
@@ -46,11 +46,11 @@ Alternation::~Alternation() noexcept {
 	elements.clear();
 }
 
-std::vector<RegExpElement*>& Alternation::getElements() {
+std::set<RegExpElement*, RegExpElement::PointerLess>& Alternation::getElements() {
 	return elements;
 }
 
-const std::vector<RegExpElement*>& Alternation::getElements() const {
+const std::set<RegExpElement*, RegExpElement::PointerLess>& Alternation::getElements() const {
 	return elements;
 }
 
diff --git a/alib2/src/regexp/Alternation.h b/alib2/src/regexp/Alternation.h
index f26963cab2..f417d3ad9e 100644
--- a/alib2/src/regexp/Alternation.h
+++ b/alib2/src/regexp/Alternation.h
@@ -8,7 +8,7 @@
 #ifndef ALTERNATION_H_
 #define ALTERNATION_H_
 
-#include <vector>
+#include <set>
 #include "RegExpElement.h"
 
 namespace regexp {
@@ -24,7 +24,7 @@ protected:
 	 */
 	virtual RegExpElement* clone() const;
 
-	std::vector<RegExpElement*> elements;
+	std::set<RegExpElement*, RegExpElement::PointerLess> elements;
 public:
 	Alternation();
 	Alternation(const Alternation& other);
@@ -36,12 +36,12 @@ public:
 	/**
 	 * @return list of operands
 	 */
-	std::vector<RegExpElement*>& getElements();
+	std::set<RegExpElement*, RegExpElement::PointerLess>& getElements();
 
 	/**
 	 * @return list of operands
 	 */
-	const std::vector<RegExpElement*>& getElements() const;
+	const std::set<RegExpElement*, RegExpElement::PointerLess>& getElements() const;
 
 	virtual bool operator<(const RegExpElement&) const;
 	virtual bool operator==(const RegExpElement&) const;
diff --git a/alib2/src/regexp/Concatenation.cpp b/alib2/src/regexp/Concatenation.cpp
index bc0db201f3..b7a1e29bb4 100644
--- a/alib2/src/regexp/Concatenation.cpp
+++ b/alib2/src/regexp/Concatenation.cpp
@@ -49,7 +49,7 @@ std::vector<RegExpElement*>& Concatenation::getElements() {
 	return elements;
 }
 
-const std::vector<const RegExpElement*>& Concatenation::getElements() const {
+const std::vector<RegExpElement*>& Concatenation::getElements() const {
 	return elements;
 }
 
diff --git a/alib2/src/regexp/Concatenation.h b/alib2/src/regexp/Concatenation.h
index de3b3c086b..648e45b1f8 100644
--- a/alib2/src/regexp/Concatenation.h
+++ b/alib2/src/regexp/Concatenation.h
@@ -41,7 +41,7 @@ public:
 	/**
 	 * @return list of operands
 	 */
-	const std::vector<const RegExpElement*>& getElements() const;
+	const std::vector<RegExpElement*>& getElements() const;
 
 	virtual bool operator<(const RegExpElement&) const;
 	virtual bool operator==(const RegExpElement&) const;
diff --git a/alib2/src/regexp/RegExpElement.h b/alib2/src/regexp/RegExpElement.h
index 57207bf229..2cea01515b 100644
--- a/alib2/src/regexp/RegExpElement.h
+++ b/alib2/src/regexp/RegExpElement.h
@@ -25,6 +25,13 @@ class RegExpEpsilon;
  * Abstract class representing element in the regular expression. Can be operator or symbol.
  */
 class RegExpElement : virtual public std::elementBase<std::visitor<Alternation, Concatenation, Iteration, RegExpSymbol, RegExpEmpty, RegExpEpsilon> > {
+protected:
+	class PointerLess {
+	public:
+		bool operator()(const RegExpElement* a, const RegExpElement* b) {
+			return *a < *b;
+		}
+	};
 public:
 	/**
 	 * Creates copy of the element.
diff --git a/alib2/src/regexp/RegExpFromXMLParser.cpp b/alib2/src/regexp/RegExpFromXMLParser.cpp
index a7a55400b7..d811fb692a 100644
--- a/alib2/src/regexp/RegExpFromXMLParser.cpp
+++ b/alib2/src/regexp/RegExpFromXMLParser.cpp
@@ -41,7 +41,11 @@ Alternation* RegExpFromXMLParser::parseAlternation(std::list<sax::Token>& input)
 	popToken(input, sax::Token::START_ELEMENT, "alternation");
 
 	Alternation* alternation = new Alternation;
-	parseContent(input, alternation->getElements());
+	while (true) {
+		RegExpElement* element = parseElement(input);
+		if(!element) break;
+		alternation->getElements().insert(element);
+	}
 
 	popToken(input, sax::Token::END_ELEMENT, "alternation");
 	return alternation;
@@ -51,7 +55,11 @@ Concatenation* RegExpFromXMLParser::parseConcatenation(std::list<sax::Token>& in
 	popToken(input, sax::Token::START_ELEMENT, "concatenation");
 
 	Concatenation* concatenation = new Concatenation();
-	parseContent(input, concatenation->getElements());
+	while (true) {
+		RegExpElement* element = parseElement(input);
+		if(!element) break;
+		concatenation->getElements().push_back(element);
+	}
 
 	popToken(input, sax::Token::END_ELEMENT, "concatenation");
 	return concatenation;
@@ -70,14 +78,6 @@ Iteration* RegExpFromXMLParser::parseIteration(std::list<sax::Token>& input) {
 	return iteration;
 }
 
-void RegExpFromXMLParser::parseContent(std::list<sax::Token>& input, std::list<RegExpElement*>& elements) {
-	while (true) {
-		RegExpElement* element = parseElement(input);
-		if(!element) return;
-		elements.push_back(element);
-	}
-}
-
 RegExpEpsilon* RegExpFromXMLParser::parseEpsilon(std::list<sax::Token>& input) {
 	popToken(input, sax::Token::START_ELEMENT, "epsilon");
 
diff --git a/alib2/src/regexp/RegExpFromXMLParser.h b/alib2/src/regexp/RegExpFromXMLParser.h
index a6cbac18d6..7fa7643398 100644
--- a/alib2/src/regexp/RegExpFromXMLParser.h
+++ b/alib2/src/regexp/RegExpFromXMLParser.h
@@ -18,7 +18,6 @@ namespace regexp {
  * Parser used to get RegExp from XML parsed into list of tokens.
  */
 class RegExpFromXMLParser {
-	void parseContent(std::list<sax::Token>& input, std::list<RegExpElement*>& elements);
 	RegExpElement* parseElement(std::list<sax::Token>& input);
 
 	RegExpEpsilon* parseEpsilon(std::list<sax::Token>& input);
-- 
GitLab