From d494a889da4e0a4164ad2909937cc51c30873b4c Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Wed, 22 Jun 2016 17:37:22 +0200
Subject: [PATCH] simplify RTE xml representation parsing

---
 alib2data/src/rte/RTEBase.h                   | 12 ---
 alib2data/src/rte/common/RTEFromXMLParser.cpp | 73 +++++++++----------
 alib2data/src/rte/common/RTEFromXMLParser.h   | 12 +--
 alib2data/src/rte/formal/FormalRTE.cpp        |  8 +-
 alib2data/src/rte/formal/FormalRTEElement.cpp | 12 +--
 alib2data/src/rte/formal/FormalRTEElement.h   | 11 +--
 alib2std/src/extensions/utility.hpp           | 13 ++++
 7 files changed, 63 insertions(+), 78 deletions(-)

diff --git a/alib2data/src/rte/RTEBase.h b/alib2data/src/rte/RTEBase.h
index 7143ec467d..51d730b0e6 100644
--- a/alib2data/src/rte/RTEBase.h
+++ b/alib2data/src/rte/RTEBase.h
@@ -25,16 +25,4 @@ public:
 
 } /* namespace rte */
 
-namespace std {
-
-template < >
-struct compare < rte::RTEBase > {
-	int operator ()( const rte::RTEBase & first, const rte::RTEBase & second ) const {
-		return first.compare ( second );
-	}
-
-};
-
-} /* namespace std */
-
 #endif /* RTE_BASE_H_ */
diff --git a/alib2data/src/rte/common/RTEFromXMLParser.cpp b/alib2data/src/rte/common/RTEFromXMLParser.cpp
index d3797c4a39..76ee828aab 100644
--- a/alib2data/src/rte/common/RTEFromXMLParser.cpp
+++ b/alib2data/src/rte/common/RTEFromXMLParser.cpp
@@ -113,7 +113,7 @@ std::pair < std::set < alphabet::RankedSymbol >, std::set < alphabet::RankedSymb
  *  return empty;
  * }
  */
-FormalRTEElement * RTEFromXMLParser::parseFormalRTEElement ( std::deque < sax::Token >::iterator & input ) {
+std::rvalue_ref < FormalRTEElement > RTEFromXMLParser::parseFormalRTEElement ( std::deque < sax::Token >::iterator & input ) {
 	if ( sax::FromXMLParserHelper::isToken ( input, sax::Token::TokenType::START_ELEMENT, "empty" ) )
 		return parseFormalRTEEmpty ( input );
 	else if ( sax::FromXMLParserHelper::isToken ( input, sax::Token::TokenType::START_ELEMENT, "iteration" ) )
@@ -128,73 +128,68 @@ FormalRTEElement * RTEFromXMLParser::parseFormalRTEElement ( std::deque < sax::T
 		throw exception::CommonException ( "Invalid token" );
 }
 
-FormalRTESymbol * RTEFromXMLParser::parseFormalRTESymbol ( std::deque < sax::Token >::iterator & input ) {
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "symbol" );
-	alphabet::RankedSymbol symbol = alib::xmlApi < alphabet::RankedSymbol >::parse ( input );
-	std::vector < FormalRTESymbol * > elements ( symbol.getRank ( ).getData ( ) );
-
-	FormalRTESymbol * ret = new FormalRTESymbol ( symbol );
-
-	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
-		ret->appendElement ( std::move ( * parseFormalRTESymbol ( input ) ) );
-
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "symbol" );
-
-	return ret;
-}
-
-FormalRTEAlternation * RTEFromXMLParser::parseFormalRTEAlternation ( std::deque < sax::Token >::iterator & input ) {
+std::rvalue_ref < FormalRTEAlternation > RTEFromXMLParser::parseFormalRTEAlternation ( std::deque < sax::Token >::iterator & input ) {
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "alternation" );
 
-	FormalRTEElement * element1 = parseFormalRTEElement ( input );
-	FormalRTEElement * element2 = parseFormalRTEElement ( input );
-
-	FormalRTEAlternation * alternation = new FormalRTEAlternation ( std::move ( * element1 ), std::move ( * element2 ) );
+	std::rvalue_ref < FormalRTEElement > element1 = parseFormalRTEElement ( input );
+	std::rvalue_ref < FormalRTEElement > element2 = parseFormalRTEElement ( input );
 
-	delete element1;
-	delete element2;
+	std::rvalue_ref < FormalRTEAlternation > alternation ( new FormalRTEAlternation ( std::move ( element1 ), std::move ( element2 ) ) );
 
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "alternation" );
 	return alternation;
 }
 
-FormalRTESubstitution * RTEFromXMLParser::parseFormalRTESubstitution ( std::deque < sax::Token >::iterator & input ) {
+std::rvalue_ref < FormalRTESubstitution > RTEFromXMLParser::parseFormalRTESubstitution ( std::deque < sax::Token >::iterator & input ) {
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "substitution" );
 
-	FormalRTESymbol * ssymb = new FormalRTESymbol ( alib::xmlApi < alphabet::RankedSymbol >::parse ( input ) );
-	FormalRTEElement * element1 = parseFormalRTEElement ( input );
-	FormalRTEElement * element2 = parseFormalRTEElement ( input );
-
-	FormalRTESubstitution * substitution = new FormalRTESubstitution ( std::move ( * element1 ), std::move ( * element2 ), std::move ( * ssymb ) );
+	std::rvalue_ref < FormalRTESymbol > ssymb ( new FormalRTESymbol ( alib::xmlApi < alphabet::RankedSymbol >::parse ( input ) ) );
+	std::rvalue_ref < FormalRTEElement > element1 = parseFormalRTEElement ( input );
+	std::rvalue_ref < FormalRTEElement > element2 = parseFormalRTEElement ( input );
 
-	delete element1;
-	delete element2;
+	std::rvalue_ref < FormalRTESubstitution > substitution ( new FormalRTESubstitution ( std::move ( element1 ), std::move ( element2 ), std::move ( ssymb ) ) );
 
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "substitution" );
 	return substitution;
 }
 
-FormalRTEIteration * RTEFromXMLParser::parseFormalRTEIteration ( std::deque < sax::Token >::iterator & input ) {
+std::rvalue_ref <FormalRTEIteration > RTEFromXMLParser::parseFormalRTEIteration ( std::deque < sax::Token >::iterator & input ) {
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "iteration" );
 
-	FormalRTESymbol * ssymb = new FormalRTESymbol ( alib::xmlApi < alphabet::RankedSymbol >::parse ( input ) );
-	FormalRTEElement * element = parseFormalRTEElement ( input );
-	FormalRTEIteration * iteration = new FormalRTEIteration ( std::move ( * element ), std::move ( * ssymb ) );
-
-	delete element;
+	std::rvalue_ref < FormalRTESymbol > ssymb ( new FormalRTESymbol ( alib::xmlApi < alphabet::RankedSymbol >::parse ( input ) ) );
+	std::rvalue_ref < FormalRTEElement > element = parseFormalRTEElement ( input );
+	std::rvalue_ref < FormalRTEIteration > iteration ( new FormalRTEIteration ( std::move ( element ), std::move ( ssymb ) ) );
 
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "iteration" );
 	return iteration;
 }
 
-FormalRTEEmpty * RTEFromXMLParser::parseFormalRTEEmpty ( std::deque < sax::Token >::iterator & input ) {
+std::rvalue_ref < FormalRTEEmpty > RTEFromXMLParser::parseFormalRTEEmpty ( std::deque < sax::Token >::iterator & input ) {
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "empty" );
 
-	FormalRTEEmpty * empty = new FormalRTEEmpty ( );
+	std::rvalue_ref < FormalRTEEmpty > empty ( new FormalRTEEmpty ( ) );
 
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "empty" );
 
 	return empty;
 }
 
+std::rvalue_ref < FormalRTESymbol > RTEFromXMLParser::parseFormalRTESymbol ( std::deque < sax::Token >::iterator & input ) {
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "symbol" );
+	alphabet::RankedSymbol symbol = alib::xmlApi < alphabet::RankedSymbol >::parse ( input );
+	std::vector < std::rvalue_ref < FormalRTESymbol > > elements;
+
+	std::rvalue_ref < FormalRTESymbol > ret ( new FormalRTESymbol ( symbol ) );
+
+	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
+		elements.push_back ( parseFormalRTESymbol ( input ) );
+
+	for ( std::rvalue_ref < FormalRTESymbol > & element : elements )
+		ret->appendElement ( std::move ( element ) );
+
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "symbol" );
+
+	return ret;
+}
+
 } /* namespace rte */
diff --git a/alib2data/src/rte/common/RTEFromXMLParser.h b/alib2data/src/rte/common/RTEFromXMLParser.h
index c0c3447b98..57cbfe04c7 100644
--- a/alib2data/src/rte/common/RTEFromXMLParser.h
+++ b/alib2data/src/rte/common/RTEFromXMLParser.h
@@ -33,13 +33,13 @@ public:
 	 * static UnboundedRTESubstitution* parseUnboundedRTESubstitution(std::deque<sax::Token>::iterator& input);
 	 */
 
-	static FormalRTEElement * parseFormalRTEElement ( std::deque < sax::Token >::iterator & input );
+	static std::rvalue_ref < FormalRTEElement > parseFormalRTEElement ( std::deque < sax::Token >::iterator & input );
 
-	static FormalRTEEmpty * parseFormalRTEEmpty ( std::deque < sax::Token >::iterator & input );
-	static FormalRTEIteration * parseFormalRTEIteration ( std::deque < sax::Token >::iterator & input );
-	static FormalRTEAlternation * parseFormalRTEAlternation ( std::deque < sax::Token >::iterator & input );
-	static FormalRTESubstitution * parseFormalRTESubstitution ( std::deque < sax::Token >::iterator & input );
-	static FormalRTESymbol * parseFormalRTESymbol ( std::deque < sax::Token >::iterator & input );
+	static std::rvalue_ref < FormalRTEEmpty > parseFormalRTEEmpty ( std::deque < sax::Token >::iterator & input );
+	static std::rvalue_ref < FormalRTEIteration > parseFormalRTEIteration ( std::deque < sax::Token >::iterator & input );
+	static std::rvalue_ref < FormalRTEAlternation > parseFormalRTEAlternation ( std::deque < sax::Token >::iterator & input );
+	static std::rvalue_ref < FormalRTESubstitution > parseFormalRTESubstitution ( std::deque < sax::Token >::iterator & input );
+	static std::rvalue_ref < FormalRTESymbol > parseFormalRTESymbol ( std::deque < sax::Token >::iterator & input );
 };
 
 } /* namespace rte */
diff --git a/alib2data/src/rte/formal/FormalRTE.cpp b/alib2data/src/rte/formal/FormalRTE.cpp
index 1b7c52416a..60dfc704ca 100644
--- a/alib2data/src/rte/formal/FormalRTE.cpp
+++ b/alib2data/src/rte/formal/FormalRTE.cpp
@@ -169,10 +169,8 @@ FormalRTE FormalRTE::parse ( std::deque < sax::Token >::iterator & input ) {
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, FormalRTE::getXmlTagName() );
 
 	std::pair < std::set < alphabet::RankedSymbol >, std::set < alphabet::RankedSymbol > > alphabets = RTEFromXMLParser::parseAlphabet ( input );
-	FormalRTEElement * element = alib::xmlApi < rte::FormalRTEElement * >::parse ( input );
-	FormalRTE rte ( std::move ( alphabets.first ), std::move ( alphabets.second ), std::move ( * element ) );
-
-	delete element;
+	std::rvalue_ref < FormalRTEElement > element = alib::xmlApi < rte::FormalRTEElement >::parse ( input );
+	FormalRTE rte ( std::move ( alphabets.first ), std::move ( alphabets.second ), std::move ( element ) );
 
 	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, FormalRTE::getXmlTagName() );
 	return rte;
@@ -181,7 +179,7 @@ FormalRTE FormalRTE::parse ( std::deque < sax::Token >::iterator & input ) {
 void FormalRTE::compose ( std::deque < sax::Token > & out ) const {
 	out.emplace_back ( FormalRTE::getXmlTagName(), sax::Token::TokenType::START_ELEMENT );
 	RTEToXMLComposer::composeAlphabet ( out, this->getAlphabet ( ), this->getConstantAlphabet ( ) );
-	alib::xmlApi < FormalRTEElement * >::compose ( out, & this->getRTE ( ) );
+	alib::xmlApi < FormalRTEElement >::compose ( out, this->getRTE ( ) );
 	out.emplace_back ( FormalRTE::getXmlTagName(), sax::Token::TokenType::END_ELEMENT );
 }
 
diff --git a/alib2data/src/rte/formal/FormalRTEElement.cpp b/alib2data/src/rte/formal/FormalRTEElement.cpp
index 3050f43af8..7cfdffc521 100644
--- a/alib2data/src/rte/formal/FormalRTEElement.cpp
+++ b/alib2data/src/rte/formal/FormalRTEElement.cpp
@@ -16,20 +16,16 @@ FormalRTEElement::FormalRTEElement ( ) : parentRTE ( NULL ) {
 
 namespace alib {
 
-rte::FormalRTEElement * xmlApi < rte::FormalRTEElement * >::parse ( std::deque < sax::Token >::iterator & input ) {
+std::rvalue_ref < rte::FormalRTEElement > xmlApi < rte::FormalRTEElement >::parse ( std::deque < sax::Token >::iterator & input ) {
 	return rte::RTEFromXMLParser::parseFormalRTEElement ( input );
 }
 
-bool xmlApi < rte::FormalRTEElement * >::first ( const std::deque < sax::Token >::const_iterator & ) {
+bool xmlApi < rte::FormalRTEElement >::first ( const std::deque < sax::Token >::const_iterator & ) {
 	throw exception::CommonException ( "Unimplemented" );
 }
 
-void xmlApi < rte::FormalRTEElement * >::compose ( std::deque < sax::Token > & output, const rte::FormalRTEElement * const & data ) {
-	data->Accept ( ( void * ) & output, rte::RTEToXMLComposer::RTE_TO_XML_COMPOSER );
-}
-
-void xmlApi < const rte::FormalRTEElement * >::compose ( std::deque < sax::Token > & output, const rte::FormalRTEElement * const & data ) {
-	data->Accept ( ( void * ) & output, rte::RTEToXMLComposer::RTE_TO_XML_COMPOSER );
+void xmlApi < rte::FormalRTEElement >::compose ( std::deque < sax::Token > & output, const rte::FormalRTEElement & data ) {
+	data.Accept ( ( void * ) & output, rte::RTEToXMLComposer::RTE_TO_XML_COMPOSER );
 }
 
 } /* namespace alib */
diff --git a/alib2data/src/rte/formal/FormalRTEElement.h b/alib2data/src/rte/formal/FormalRTEElement.h
index 7daf6f6f68..d1b57396c7 100644
--- a/alib2data/src/rte/formal/FormalRTEElement.h
+++ b/alib2data/src/rte/formal/FormalRTEElement.h
@@ -84,15 +84,10 @@ public:
 namespace alib {
 
 template < >
-struct xmlApi < rte::FormalRTEElement * > {
-	static rte::FormalRTEElement * parse ( std::deque < sax::Token >::iterator & input );
+struct xmlApi < rte::FormalRTEElement > {
+	static std::rvalue_ref < rte::FormalRTEElement > parse ( std::deque < sax::Token >::iterator & input );
 	static bool first ( const std::deque < sax::Token >::const_iterator & input );
-	static void compose ( std::deque < sax::Token > & output, const rte::FormalRTEElement * const & data );
-};
-
-template < >
-struct xmlApi < const rte::FormalRTEElement * > {
-	static void compose ( std::deque < sax::Token > & output, const rte::FormalRTEElement * const & data );
+	static void compose ( std::deque < sax::Token > & output, const rte::FormalRTEElement & data );
 };
 
 } /* namespace alib */
diff --git a/alib2std/src/extensions/utility.hpp b/alib2std/src/extensions/utility.hpp
index 645f460403..0b7e1198c2 100644
--- a/alib2std/src/extensions/utility.hpp
+++ b/alib2std/src/extensions/utility.hpp
@@ -23,6 +23,11 @@ struct rvalue_ref {
 
 	}
 
+	template < class U >
+	rvalue_ref ( rvalue_ref < U > && other ) : holder ( other.holder ) {
+		other.holder = nullptr;
+	}
+
 	rvalue_ref ( const rvalue_ref & ) = delete;
 
 	rvalue_ref ( rvalue_ref && other) : holder( other.holder ) {
@@ -39,6 +44,14 @@ struct rvalue_ref {
 		delete holder;
 	}
 
+	T * operator ->( ) {
+		return holder;
+	}
+
+	T * operator ->( ) const {
+		return holder;
+	}
+
 	operator T && ( ) {
 		return std::move ( * holder );
 	}
-- 
GitLab