From 72ac0cc71bb72f5183335c2930cbc4df64aec980 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 24 May 2016 08:16:07 +0200
Subject: [PATCH] make optimize compile

---
 .../src/regexp/simplify/RegExpOptimize.cpp    |  30 +--
 .../simplify/RegExpOptimizeFormalPart.cxx     | 230 ++++++++----------
 .../simplify/RegExpOptimizeUnboundedPart.cxx  | 185 ++++++--------
 3 files changed, 193 insertions(+), 252 deletions(-)

diff --git a/alib2algo/src/regexp/simplify/RegExpOptimize.cpp b/alib2algo/src/regexp/simplify/RegExpOptimize.cpp
index 18d388c320..4ae3705cf0 100644
--- a/alib2algo/src/regexp/simplify/RegExpOptimize.cpp
+++ b/alib2algo/src/regexp/simplify/RegExpOptimize.cpp
@@ -27,11 +27,7 @@ FormalRegExp RegExpOptimize::optimize( FormalRegExp const & regexp )
 {
 	FormalRegExpElement* optimized = RegExpOptimize::REG_EXP_OPTIMIZE.optimize( & regexp.getRegExp( ) );
 
-	FormalRegExp ret( std::move( * optimized ) );
-
-	delete optimized;
-
-	return ret;
+	return FormalRegExp ( std::manage_move ( optimized ) );
 }
 
 auto RegExpOptimizeFormalRegEpx = RegExpOptimize::RegistratorWrapper<FormalRegExp, FormalRegExp>(RegExpOptimize::optimize);
@@ -47,8 +43,7 @@ void RegExpOptimize::optimize( FormalRegExpElement & element )
 			* alternation = std::move( * alternationOptimized );
 			delete alternationOptimized;
 		} else {
-			* alternation = FormalRegExpAlternation { std::move( * optimized ), FormalRegExpEmpty { } };
-			delete optimized;
+			* alternation = FormalRegExpAlternation { std::manage_move ( optimized ), FormalRegExpEmpty { } };
 		}
 		return;
 	}
@@ -60,8 +55,7 @@ void RegExpOptimize::optimize( FormalRegExpElement & element )
 			* concatenation = std::move( * concatenationOptimized );
 			delete concatenationOptimized;
 		} else {
-			* concatenation = FormalRegExpConcatenation { std::move( * optimized ), FormalRegExpEpsilon { } };
-			delete optimized;
+			* concatenation = FormalRegExpConcatenation { std::manage_move ( optimized ), FormalRegExpEpsilon { } };
 		}
 		return;
 	}
@@ -73,8 +67,7 @@ void RegExpOptimize::optimize( FormalRegExpElement & element )
 			* iteration = std::move( * iterationOptimized );
 			delete iterationOptimized;
 		} else {
-			* iteration = FormalRegExpIteration { std::move( * optimized ) };
-			delete optimized;
+			* iteration = FormalRegExpIteration { std::manage_move ( optimized ) };
 		}
 		return;
 	}
@@ -87,11 +80,7 @@ UnboundedRegExp RegExpOptimize::optimize( UnboundedRegExp const & regexp )
 {
 	UnboundedRegExpElement* optimized = RegExpOptimize::REG_EXP_OPTIMIZE.optimize( & regexp.getRegExp( ) );
 
-	UnboundedRegExp ret( std::move( * optimized ) );
-
-	delete optimized;
-
-	return ret;
+	return UnboundedRegExp ( std::manage_move ( optimized ) );
 }
 
 auto RegExpOptimizeUnboundedRegEpx = RegExpOptimize::RegistratorWrapper<UnboundedRegExp, UnboundedRegExp>(RegExpOptimize::optimize);
@@ -107,8 +96,7 @@ void RegExpOptimize::optimize( UnboundedRegExpElement & element ) {
 			delete alternationOptimized;
 		} else {
 			* alternation = UnboundedRegExpAlternation { };
-			alternation->appendElement( std::move( * optimized ) );
-			delete optimized;
+			alternation->appendElement( std::manage_move ( optimized ) );
 		}
 		return;
 	}
@@ -121,8 +109,7 @@ void RegExpOptimize::optimize( UnboundedRegExpElement & element ) {
 			delete concatenationOptimized;
 		} else {
 			* concatenation = UnboundedRegExpConcatenation { };
-			concatenation->appendElement( std::move( * optimized ) );
-			delete optimized;
+			concatenation->appendElement( std::manage_move ( optimized ) );
 		}
 		return;
 	}
@@ -134,8 +121,7 @@ void RegExpOptimize::optimize( UnboundedRegExpElement & element ) {
 			* iteration = std::move( * iterationOptimized );
 			delete iterationOptimized;
 		} else {
-			* iteration = UnboundedRegExpIteration { std::move( * optimized ) };
-			delete optimized;
+			* iteration = UnboundedRegExpIteration { std::manage_move ( optimized ) };
 		}
 		return;
 	}
diff --git a/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx b/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx
index 932e4cf8d2..a06ce7938f 100644
--- a/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx
+++ b/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx
@@ -26,35 +26,46 @@ bool RegExpOptimize::S( FormalRegExpElement * & node ) const
 	bool optimized = false;
 	FormalRegExpAlternation * alternation = dynamic_cast<FormalRegExpAlternation*>( node );
 	if( alternation ) {
-		auto tmp = alternation->left;
-		alternation->left = optimize(alternation->left);
-		if(tmp != alternation->left) optimized = true;
+		FormalRegExpElement * tmp = optimize ( alternation->left.get() );
+		if(tmp != alternation->left.get()) {
+			optimized = true;
+			alternation->left = std::smart_ptr < FormalRegExpElement > ( tmp );
+		}
 
-		tmp = alternation->right;
-		alternation->right = optimize(alternation->right);
-		if(tmp != alternation->right) optimized = true;
+		tmp = optimize ( alternation->right.get() );
+		if(tmp != alternation->right.get()) {
+			optimized = true;
+			alternation->right = std::smart_ptr < FormalRegExpElement > ( tmp );
+		}
 
 		return optimized;
 	}
 
 	FormalRegExpConcatenation * concatenation = dynamic_cast<FormalRegExpConcatenation*>( node );
 	if( concatenation ) {
-		auto tmp = concatenation->left;
-		concatenation->left = optimize(concatenation->left);
-		if(tmp != concatenation->left) optimized = true;
+		FormalRegExpElement* tmp = optimize ( concatenation->left.get() );
+		if(tmp != concatenation->left.get()) {
+			optimized = true;
+			concatenation->left = std::smart_ptr < FormalRegExpElement > ( tmp );
+		}
 
-		tmp = concatenation->right;
-		concatenation->right = optimize(concatenation->right);
-		if(tmp != concatenation->right) optimized = true;
+		tmp = optimize ( concatenation->right.get());
+		if(tmp != concatenation->right.get()) {
+			optimized = true;
+			concatenation->right = std::smart_ptr < FormalRegExpElement > ( tmp );
+		}
 
 		return optimized;
 	}
 
 	FormalRegExpIteration * iteration = dynamic_cast<FormalRegExpIteration*>( node );
 	if( iteration ) {
-		auto tmp = iteration->element;
-		iteration->element = optimize(iteration->element);
-		if(tmp != iteration->element) optimized = true;
+		FormalRegExpElement* tmp = optimize ( iteration->element.get() );
+
+		if(tmp != iteration->element.get()) {
+			optimized = true;
+			iteration->element = std::smart_ptr < FormalRegExpElement > ( tmp );
+		}
 		return iteration;
 	}
 
@@ -72,17 +83,18 @@ bool RegExpOptimize::A1( FormalRegExpElement * & n ) const
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpAlternation * leftAlt = dynamic_cast<FormalRegExpAlternation *>( node->left );
+	FormalRegExpAlternation * leftAlt = dynamic_cast<FormalRegExpAlternation *>( node->left.get() );
 
 	if( leftAlt ) {
-		FormalRegExpElement * x = leftAlt->left;
-		FormalRegExpElement * y = leftAlt->right;
-		FormalRegExpElement * z = node->right;
+		leftAlt = static_cast<FormalRegExpAlternation *>( node->left.release() );
+		std::smart_ptr < FormalRegExpElement > x = std::move ( leftAlt->left );
+		std::smart_ptr < FormalRegExpElement > y = std::move ( leftAlt->right );
+		std::smart_ptr < FormalRegExpElement > z = std::move ( node->right );
 
-		node->left = x;
-		node->right = leftAlt;
-		leftAlt->left = y;
-		leftAlt->right = z;
+		leftAlt->left = std::move ( y );
+		leftAlt->right = std::move ( z );
+		node->left = std::move ( x );
+		node->right = std::smart_ptr < FormalRegExpElement > ( leftAlt );
 
 		return true;
 	}
@@ -100,15 +112,14 @@ bool RegExpOptimize::A2( FormalRegExpElement * & n ) const
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpAlternation * rightAlt = dynamic_cast<FormalRegExpAlternation *>( node->right );
+	FormalRegExpAlternation * rightAlt = dynamic_cast<FormalRegExpAlternation *>( node->right.get() );
 
 	if( rightAlt ) {
-		FormalRegExpElement * x = node->left;
-		FormalRegExpElement * y = rightAlt->left;
+		FormalRegExpElement * x = node->left.get();
+		FormalRegExpElement * y = rightAlt->left.get();
 
 		if(*x > *y) {
-			node->left = y;
-			rightAlt->left = x;
+			std::swap ( node->left, rightAlt->left );
 		} else {
 			return false;
 		}
@@ -129,20 +140,18 @@ bool RegExpOptimize::A3( FormalRegExpElement * & n ) const
 
 	// input can be \0 + \0, so at least one element must be preserved
 
-	FormalRegExpEmpty * rightEmp = dynamic_cast<FormalRegExpEmpty *>( node->right );
+	FormalRegExpEmpty * rightEmp = dynamic_cast<FormalRegExpEmpty *>( node->right.get() );
 	if( rightEmp ) {
-		delete rightEmp;
-		n = node->left;
-		node->left = NULL;
+		rightEmp = nullptr;
+		n = node->left.release();
 		delete node;
 		return true;
 	}
 
-	FormalRegExpEmpty * leftEmp = dynamic_cast<FormalRegExpEmpty *>( node->left );
+	FormalRegExpEmpty * leftEmp = dynamic_cast<FormalRegExpEmpty *>( node->left.release() );
 	if( leftEmp ) {
-		delete leftEmp;
-		n = node->right;
-		node->right = NULL;
+		leftEmp = nullptr;
+		n = node->right.release();
 		delete node;
 		return true;
 	}
@@ -168,10 +177,9 @@ bool RegExpOptimize::A4( FormalRegExpElement * & n ) const
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
-	if( node->left == node->right ) {
-		delete node->left;
-		n = node->right;
-		node->right = NULL;
+	if( *node->left == *node->right ) {
+		delete node->left.release();
+		n = node->right.release();
 		delete node;
 		return true;
 	}
@@ -189,17 +197,18 @@ bool RegExpOptimize::A5( FormalRegExpElement * & n ) const
 	FormalRegExpConcatenation * node = dynamic_cast<FormalRegExpConcatenation *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpConcatenation * leftCon = dynamic_cast<FormalRegExpConcatenation *>( node->left );
+	FormalRegExpConcatenation * leftCon = dynamic_cast<FormalRegExpConcatenation *>( node->left.get() );
 
 	if( leftCon ) {
-		FormalRegExpElement * x = leftCon->left;
-		FormalRegExpElement * y = leftCon->right;
-		FormalRegExpElement * z = node->right;
+		leftCon = static_cast<FormalRegExpConcatenation *>( node->left.release() );
+		std::smart_ptr < FormalRegExpElement > x = std::move ( leftCon->left );
+		std::smart_ptr < FormalRegExpElement > y = std::move ( leftCon->right );
+		std::smart_ptr < FormalRegExpElement > z = std::move ( node->right );
 
-		node->left = x;
-		node->right = leftCon;
-		leftCon->left = y;
-		leftCon->right = z;
+		leftCon->left = std::move ( y );
+		leftCon->right = std::move ( z );
+		node->left = std::move ( x );
+		node->right = std::smart_ptr < FormalRegExpElement > ( leftCon );
 
 		return true;
 	}
@@ -219,20 +228,18 @@ bool RegExpOptimize::A6( FormalRegExpElement * & n ) const
 
 	// input can be \e + \e, so at least one element must be preserved
 
-	FormalRegExpEpsilon * rightEmp = dynamic_cast<FormalRegExpEpsilon *>( node->right );
+	FormalRegExpEpsilon * rightEmp = dynamic_cast<FormalRegExpEpsilon *>( node->right.get() );
 	if( rightEmp ) {
-		delete rightEmp;
-		n = node->left;
-		node->left = NULL;
+		rightEmp = nullptr;
+		n = node->left.release();
 		delete node;
 		return true;
 	}
 
-	FormalRegExpEpsilon * leftEmp = dynamic_cast<FormalRegExpEpsilon *>( node->left );
+	FormalRegExpEpsilon * leftEmp = dynamic_cast<FormalRegExpEpsilon *>( node->left.get() );
 	if( leftEmp ) {
-		delete leftEmp;
-		n = node->right;
-		node->right = NULL;
+		leftEmp = nullptr;
+		n = node->right.release();
 		delete node;
 		return true;
 	}
@@ -250,7 +257,7 @@ bool RegExpOptimize::A7( FormalRegExpElement * & n ) const
 	FormalRegExpConcatenation * node = dynamic_cast<FormalRegExpConcatenation *>( n );
 	if( ! node ) return false;
 
-	if( dynamic_cast<FormalRegExpEmpty *>( node->right ) || dynamic_cast<FormalRegExpEmpty *>( node->left ) ) {
+	if( dynamic_cast<FormalRegExpEmpty *>( node->right.get() ) || dynamic_cast<FormalRegExpEmpty *>( node->left.get() ) ) {
 		delete node;
 		n = new FormalRegExpEmpty { };
 		return true;
@@ -295,60 +302,48 @@ bool RegExpOptimize::A10( FormalRegExpElement * & n ) const
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpEpsilon * leftEps = dynamic_cast<FormalRegExpEpsilon *>( node->left );
+	FormalRegExpEpsilon * leftEps = dynamic_cast<FormalRegExpEpsilon *>( node->left.get() );
 	if( leftEps ) {
-		FormalRegExpConcatenation * rightCon = dynamic_cast<FormalRegExpConcatenation *>( node->right );
+		FormalRegExpConcatenation * rightCon = dynamic_cast<FormalRegExpConcatenation *>( node->right.get() );
 		if( ! rightCon ) return false;
 
-		FormalRegExpIteration * rightLeftIte = dynamic_cast<FormalRegExpIteration *>( rightCon->left );
+		FormalRegExpIteration * rightLeftIte = dynamic_cast<FormalRegExpIteration *>( rightCon->left.get() );
 		if( rightLeftIte ) {
-			if(rightLeftIte->element == rightCon->right) {
-				delete leftEps;
-				delete rightCon->right;
-				n = rightCon->left;
-				rightCon->left = NULL;
+			if(*rightLeftIte->element == *rightCon->right) {
+				n = rightCon->left.release();
 				delete node;
 				return true;
 			}
 		}
 
-		FormalRegExpIteration * rightRightIte = dynamic_cast<FormalRegExpIteration *>( rightCon->right );
+		FormalRegExpIteration * rightRightIte = dynamic_cast<FormalRegExpIteration *>( rightCon->right.get() );
 		if( rightRightIte ) {
-			if(rightLeftIte->element == rightCon->left) {
-				delete leftEps;
-				delete rightCon->left;
-				n = rightCon->right;
-				rightCon->right = NULL;
+			if(*rightLeftIte->element == *rightCon->left) {
+				n = rightCon->right.release();
 				delete node;
 				return true;
 			}
 		}
 	}
 
-	FormalRegExpEpsilon * rightEps = dynamic_cast<FormalRegExpEpsilon *>( node->right );
+	FormalRegExpEpsilon * rightEps = dynamic_cast<FormalRegExpEpsilon *>( node->right.get() );
 	if( rightEps ) {
-		FormalRegExpConcatenation * leftCon = dynamic_cast<FormalRegExpConcatenation *>( node->left );
+		FormalRegExpConcatenation * leftCon = dynamic_cast<FormalRegExpConcatenation *>( node->left.get() );
 		if( ! leftCon ) return false;
 
-		FormalRegExpIteration * leftLeftIte = dynamic_cast<FormalRegExpIteration *>( leftCon->left );
+		FormalRegExpIteration * leftLeftIte = dynamic_cast<FormalRegExpIteration *>( leftCon->left.get() );
 		if( leftLeftIte ) {
-			if(leftLeftIte->element == leftCon->right) {
-				delete rightEps;
-				delete leftCon->right;
-				n = leftCon->left;
-				leftCon->left = NULL;
+			if(*leftLeftIte->element == *leftCon->right) {
+				n = leftCon->left.release();
 				delete node;
 				return true;
 			}
 		}
 
-		FormalRegExpIteration * leftRightIte = dynamic_cast<FormalRegExpIteration *>( leftCon->right );
+		FormalRegExpIteration * leftRightIte = dynamic_cast<FormalRegExpIteration *>( leftCon->right.get() );
 		if( leftRightIte ) {
-			if(leftLeftIte->element == leftCon->left) {
-				delete rightEps;
-				delete leftCon->left;
-				n = leftCon->right;
-				leftCon->right = NULL;
+			if(*leftLeftIte->element == *leftCon->left) {
+				n = leftCon->right.release();
 				delete node;
 				return true;
 			}
@@ -368,19 +363,15 @@ bool RegExpOptimize::A11( FormalRegExpElement * & n ) const
 	FormalRegExpIteration * node = dynamic_cast<FormalRegExpIteration *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpAlternation * childAlt = dynamic_cast<FormalRegExpAlternation *>( node->element );
+	FormalRegExpAlternation * childAlt = dynamic_cast<FormalRegExpAlternation *>( node->element.get() );
 	if( childAlt )
 	{
-		if(dynamic_cast<FormalRegExpEpsilon*>(childAlt->left)) {
-			node->element = childAlt->right;
-			childAlt->right = NULL;
-			delete childAlt;
+		if(dynamic_cast<FormalRegExpEpsilon*>(childAlt->left.get())) {
+			node->element = std::move ( childAlt->right );
 			return true;
 		}
-		if(dynamic_cast<FormalRegExpEpsilon*>(childAlt->right)) {
-			node->element = childAlt->left;
-			childAlt->left = NULL;
-			delete childAlt;
+		if(dynamic_cast<FormalRegExpEpsilon*>(childAlt->right.get())) {
+			node->element = std::move ( childAlt->left );
 			return true;
 		}
 	}
@@ -398,7 +389,7 @@ bool RegExpOptimize::V1( FormalRegExpElement * & n ) const
 	FormalRegExpIteration * node = dynamic_cast<FormalRegExpIteration *>( n );
 	if( ! node ) return false;
 
-	if( dynamic_cast<FormalRegExpEmpty*>( node->element ) )
+	if( dynamic_cast<FormalRegExpEmpty*>( node->element.get() ) )
 	{
 		delete node;
 		n = new FormalRegExpEpsilon( );
@@ -417,21 +408,19 @@ bool RegExpOptimize::V2( FormalRegExpElement * & n ) const
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->left );
+	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->left.get() );
 	if( leftIte ) {
-		if(leftIte->element == node->right) {
-			n = node->left;
-			node->left = NULL;
+		if(*leftIte->element == *node->right) {
+			n = node->left.release();
 			delete node;
 			return true;
 		}
 	}
 
-	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->right );
+	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->right.get() );
 	if( rightIte ) {
-		if(rightIte->element == node->left) {
-			n = node->right;
-			node->right = NULL;
+		if(*rightIte->element == *node->left) {
+			n = node->right.release();
 			delete node;
 			return true;
 		}
@@ -450,13 +439,10 @@ bool RegExpOptimize::V3( FormalRegExpElement * & n ) const
 	FormalRegExpIteration * node = dynamic_cast<FormalRegExpIteration *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpIteration* childIter = dynamic_cast<FormalRegExpIteration*>( node->element );
+	FormalRegExpIteration* childIter = dynamic_cast<FormalRegExpIteration*>( node->element.get() );
 	if( childIter )
 	{
-		node->element = childIter->element;
-		childIter->element = NULL;
-		delete childIter;
-
+		node->element = std::move ( childIter->element );
 		return true;
 	}
 
@@ -473,16 +459,16 @@ bool RegExpOptimize::V4( FormalRegExpElement * & n ) const
 	FormalRegExpIteration * node = dynamic_cast<FormalRegExpIteration *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpConcatenation * child = dynamic_cast<FormalRegExpConcatenation *>( node->element );
+	FormalRegExpConcatenation * child = dynamic_cast<FormalRegExpConcatenation *>( node->element.get() );
 	if( ! child ) return false;
 
-	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( child->left );
+	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( child->left.get() );
 	if( ! leftIte ) return false;
 
-	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( child->right );
+	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( child->right.get() );
 	if( ! rightIte ) return false;
 
-	n = new FormalRegExpIteration(FormalRegExpAlternation(std::move( *leftIte->element ), std::move(*rightIte->element)));
+	n = new FormalRegExpIteration( FormalRegExpAlternation(std::move( * leftIte->element ), std::move( * rightIte->element)));
 
 	delete node;
 	return true;
@@ -538,13 +524,13 @@ bool RegExpOptimize::V10( FormalRegExpElement * & n ) const
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->left );
+	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->left.get() );
 	if( ! leftIte ) return false;
 
-	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->right );
+	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->right.get() );
 	if( ! rightIte ) return false;
 
-	n = new FormalRegExpConcatenation(std::move( *leftIte->element ), std::move(*rightIte->element));
+	n = new FormalRegExpConcatenation(std::move( * leftIte->element ), std::move( * rightIte->element ) );
 
 	delete node;
 	return true;
@@ -560,21 +546,19 @@ bool RegExpOptimize::X1( FormalRegExpElement * & n ) const
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->left );
+	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->left.get() );
 	if( leftIte ) {
-		if(dynamic_cast<FormalRegExpEpsilon*>(node->right)) {
-			n = node->left;
-			node->left = NULL;
+		if(dynamic_cast<FormalRegExpEpsilon*>(node->right.get())) {
+			n = node->left.release();
 			delete node;
 			return true;
 		}
 	}
 
-	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->right );
+	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->right.get() );
 	if( rightIte ) {
-		if(dynamic_cast<FormalRegExpEpsilon*>(node->left)) {
-			n = node->right;
-			node->right = NULL;
+		if(dynamic_cast<FormalRegExpEpsilon*>(node->left.get())) {
+			n = node->right.release();
 			delete node;
 			return true;
 		}
diff --git a/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx b/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx
index 61def6759a..fbc83ad918 100644
--- a/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx
+++ b/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx
@@ -44,14 +44,14 @@ UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpAlternation co
 	UnboundedRegExpAlternation* alt = new UnboundedRegExpAlternation( );
 
 	for( const auto & child : node->elements )
-		alt->elements.push_back( optimize( child ) );
+		alt->elements.push_back( std::smart_ptr < UnboundedRegExpElement > ( optimize( child.get() ) ) );
 
 	// optimize while you can
 	while( A1( alt ) || A2( alt ) || A3( alt ) || A4( alt ) || A10( alt ) || V2( alt ) || V5( alt ) || V6( alt ) || X1( alt ) );
 
 	if( alt->elements.size( ) == 1 )
 	{
-		UnboundedRegExpElement* ret = alt->elements.front( );
+		UnboundedRegExpElement* ret = alt->elements.front( ).release();
 		alt->elements.clear( );
 		delete alt;
 		return ret;
@@ -70,13 +70,13 @@ UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpConcatenation
 	UnboundedRegExpConcatenation* concat = new UnboundedRegExpConcatenation( );
 
 	for( const auto & child : node->elements )
-		concat->elements.push_back( optimize( child ) );
+		concat->elements.push_back( std::smart_ptr < UnboundedRegExpElement > ( optimize( child.get() ) ) );
 
 	while( A5( concat ) || A6( concat ) || A7( concat ) || A8( concat ) || A9( concat ) || V8( concat ) );//|| V9( concat ) );
 
 	if( concat->elements.size( ) == 1 )
 	{
-		UnboundedRegExpElement* ret = concat->elements.front( );
+		UnboundedRegExpElement* ret = concat->elements.front( ).release();
 		concat->elements.clear( );
 		delete concat;
 		return ret;
@@ -93,13 +93,12 @@ UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpConcatenation
 UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpIteration const * const & node ) const
 {
 	UnboundedRegExpIteration* iter = new UnboundedRegExpIteration( UnboundedRegExpEmpty {} );
-	delete iter->element;
-	iter->element = optimize( node->element );
+	iter->element = std::smart_ptr < UnboundedRegExpElement > ( optimize( node->element.get() ) );
 
 	do
 	{
 		// V1 is implemented right here
-		if( dynamic_cast<UnboundedRegExpEmpty*>( iter->element ) )
+		if( dynamic_cast<UnboundedRegExpEmpty*>( iter->element.get() ) )
 		{
 			delete iter;
 			return new UnboundedRegExpEpsilon( );
@@ -136,10 +135,11 @@ bool RegExpOptimize::A1( UnboundedRegExpAlternation * const & node ) const
 
 	for( auto it = node->elements.begin( ); it != node->elements.end( ); )
 	{
-		UnboundedRegExpAlternation * const & childUnboundedRegExpAlternation = dynamic_cast<UnboundedRegExpAlternation *>( * it );
+		UnboundedRegExpAlternation * childUnboundedRegExpAlternation = dynamic_cast<UnboundedRegExpAlternation *>( it->get() );
 
 		if( childUnboundedRegExpAlternation )
 		{
+			childUnboundedRegExpAlternation = static_cast<UnboundedRegExpAlternation *>( it->release() );
 			it = node->elements.erase( it );
 
 			size_t off = it - node->elements.begin();
@@ -169,7 +169,7 @@ bool RegExpOptimize::A1( UnboundedRegExpAlternation * const & node ) const
   */
 bool RegExpOptimize::A2( UnboundedRegExpAlternation * const & node ) const
 {
-	std::function<bool( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b )> cmp = [ ]( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool { return *a < *b; };
+	auto cmp = [ ]( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool { return *a < *b; };
 
 	if( std::is_sorted( node->elements.begin( ), node->elements.end( ), cmp ) )
 		return false;
@@ -191,12 +191,11 @@ bool RegExpOptimize::A3( UnboundedRegExpAlternation * const & node ) const
 
 	for( auto it = node->elements.begin( ); it != node->elements.end( ); )
 	{
-		UnboundedRegExpEmpty const * const & empty = dynamic_cast<UnboundedRegExpEmpty const *>( * it );
+		UnboundedRegExpEmpty const * const & empty = dynamic_cast<UnboundedRegExpEmpty const *>( it->get() );
 
 		if( empty && node->elements.size( ) > 1 )
 		{
 			it = node->elements.erase( it );
-			delete empty;
 
 			optimized = true;
 		}
@@ -229,7 +228,6 @@ bool RegExpOptimize::A4( UnboundedRegExpAlternation * const & node ) const
 	{
 		if ( ** it == ** std::prev( it ) )
 		{
-			delete * it;
 			it = node->elements.erase( it );
 			optimized = true;
 		}
@@ -253,10 +251,11 @@ bool RegExpOptimize::A5( UnboundedRegExpConcatenation * const & node ) const
 
 	for( auto it = node->elements.begin( ); it != node->elements.end( ); )
 	{
-		UnboundedRegExpConcatenation * const & childUnboundedRegExpConcatenation = dynamic_cast<UnboundedRegExpConcatenation *>( * it );
+		UnboundedRegExpConcatenation * childUnboundedRegExpConcatenation = dynamic_cast<UnboundedRegExpConcatenation *>( it->get() );
 
 		if( childUnboundedRegExpConcatenation )
 		{
+			childUnboundedRegExpConcatenation = static_cast<UnboundedRegExpConcatenation *>( it->release() );
 			it = node->elements.erase( it );
 
 			size_t off = it - node->elements.begin();
@@ -288,10 +287,9 @@ bool RegExpOptimize::A6( UnboundedRegExpConcatenation * const & node ) const
 
 	for( auto it = node->elements.begin( ); it != node->elements.end( ); )
 	{
-		UnboundedRegExpEpsilon* epsilon = dynamic_cast<UnboundedRegExpEpsilon*>( * it );
+		UnboundedRegExpEpsilon* epsilon = dynamic_cast<UnboundedRegExpEpsilon*>( it->get() );
 		if( epsilon && node->elements.size( ) > 1 )
 		{
-			delete * it;
 			it = node->elements.erase( it );
 
 			optimized = true;
@@ -312,15 +310,12 @@ bool RegExpOptimize::A7( UnboundedRegExpConcatenation * const & node ) const
 {
 	bool optimized = false;
 
-	if( std::any_of( node->elements.begin( ), node->elements.end( ), []( UnboundedRegExpElement const * const & a ) -> bool{ return dynamic_cast<UnboundedRegExpEmpty const *>( a ); } ) )
+	if( std::any_of( node->elements.begin( ), node->elements.end( ), []( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return dynamic_cast<UnboundedRegExpEmpty const *>( a.get() ); } ) )
 	{
 		if(node->elements.size() == 1) return false;
 
-		for( auto const& child : node->elements )
-			delete child;
-
 		node->elements.clear( );
-		node->elements.push_back( new UnboundedRegExpEmpty( ) );
+		node->elements.push_back( std::smart_ptr < UnboundedRegExpElement > ( new UnboundedRegExpEmpty( ) ) );
 
 		optimized = true;
 	}
@@ -447,23 +442,22 @@ bool RegExpOptimize::A10( UnboundedRegExpAlternation * const & node ) const
 		optimizedIter = false;
 
 		// check if we have some epsilon or iteration left, else nothing to do
-		auto eps = find_if( node->elements.begin( ), node->elements.end( ), [ ]( UnboundedRegExpElement const * const & a ) -> bool {
-			return dynamic_cast<UnboundedRegExpEpsilon const *>( a ) || dynamic_cast<UnboundedRegExpIteration const*>( a );
+		auto eps = find_if( node->elements.begin( ), node->elements.end( ), [ ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool {
+			return dynamic_cast<UnboundedRegExpEpsilon const *>( a.get() ) || dynamic_cast<UnboundedRegExpIteration const*>( a.get() );
 		});
 		if( eps == node->elements.end( ) )
 			break;
 
-		UnboundedRegExpConcatenation const * const & childConcat = dynamic_cast<UnboundedRegExpConcatenation const *>( *it );
+		UnboundedRegExpConcatenation const * const & childConcat = dynamic_cast<UnboundedRegExpConcatenation const *>( it->get() );
 		if( childConcat )
 		{
 			// if iteration is first element of concatenation
-			UnboundedRegExpIteration const * const & iter = dynamic_cast<UnboundedRegExpIteration const *>( childConcat->elements.front( ) );
+			UnboundedRegExpIteration const * const & iter = dynamic_cast<UnboundedRegExpIteration const *>( childConcat->elements.front( ).get() );
 
 			if( iter )
 			{
 				// concatenation without the iteration node
 				UnboundedRegExpConcatenation *tmpConcat = dynamic_cast<UnboundedRegExpConcatenation *>( childConcat->clone( ) );
-				delete tmpConcat->elements.front( );
 				tmpConcat->elements.erase( tmpConcat->elements.begin( ) );
 				UnboundedRegExpElement * tmpConcatOpt = optimize( tmpConcat );
 
@@ -473,21 +467,19 @@ bool RegExpOptimize::A10( UnboundedRegExpAlternation * const & node ) const
 					optimized = optimizedIter = true;
 
 					size_t off = it - node->elements.begin();
-					node->elements.push_back( iter->clone( ) );
+					node->elements.push_back( std::smart_ptr < UnboundedRegExpElement > ( iter->clone( ) ) );
 					it = node->elements.begin() + off;
 
-					delete childConcat;
 					it = node->elements.erase( it );
 
 					// find the eps again - invalidated after prev erase
-					eps = find_if( node->elements.begin( ), node->elements.end( ), [ ]( UnboundedRegExpElement const * const & a ) -> bool {
-						return dynamic_cast<UnboundedRegExpEpsilon const *>( a );
+					eps = find_if( node->elements.begin( ), node->elements.end( ), [ ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool {
+						return dynamic_cast<UnboundedRegExpEpsilon const *>( a.get() );
 					});
 					// if it was eps, delete it
 					// if it was not the eps but iteration, keep it
 					if( eps != node->elements.end( ) )
 					{
-						delete *eps;
 						it = node->elements.erase( eps );
 					}
 				}
@@ -512,13 +504,13 @@ bool RegExpOptimize::A11( UnboundedRegExpIteration * const & node ) const
 {
 	bool optimized = false;
 
-	UnboundedRegExpAlternation * const & childAlt = dynamic_cast<UnboundedRegExpAlternation *>( node->element );
+	UnboundedRegExpAlternation * const & childAlt = dynamic_cast<UnboundedRegExpAlternation *>( node->element.get() );
 
 	if( childAlt )
 	{
 		// check if eps inside iteration's alternation
-		auto eps = find_if( childAlt->elements.begin( ), childAlt->elements.end( ), [ ]( UnboundedRegExpElement const * const & a ) -> bool {
-			return dynamic_cast<UnboundedRegExpEpsilon const *>( a );
+		auto eps = find_if( childAlt->elements.begin( ), childAlt->elements.end( ), [ ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool {
+			return dynamic_cast<UnboundedRegExpEpsilon const *>( a.get() );
 		});
 
 		// if no eps
@@ -527,7 +519,6 @@ bool RegExpOptimize::A11( UnboundedRegExpIteration * const & node ) const
 
 		// remove eps from alternation
 		optimized = true;
-		delete * eps;
 		childAlt->elements.erase( eps );
 	}
 
@@ -564,9 +555,9 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node ) const
 	// cache  iter elements because of operator invalidation after erase
 	for( const auto & n : node->elements )
 	{
-		UnboundedRegExpIteration* iter = dynamic_cast<UnboundedRegExpIteration*>( n );
+		UnboundedRegExpIteration* iter = dynamic_cast<UnboundedRegExpIteration*>( n.get() );
 		if( iter )
-			iterElements.push_back( iter->element );
+			iterElements.push_back( iter->element.get() );
 	}
 
 	for( const auto & n : iterElements )
@@ -578,7 +569,7 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node ) const
 			bool every = true;
 			for( const auto & altElem : tmpAlt->elements )
 			{
-				auto it = find_if( node->elements.begin( ), node->elements.end( ), [ altElem ]( UnboundedRegExpElement const * const & a ) -> bool {
+				auto it = find_if( node->elements.begin( ), node->elements.end( ), [ &altElem ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool {
 					return *a == *altElem;
 				});
 
@@ -592,12 +583,11 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node ) const
 
 				for( const auto & altElem : tmpAlt->elements )
 				{
-					auto it = find_if( node->elements.begin( ), node->elements.end( ), [ altElem ]( UnboundedRegExpElement const * const & a ) -> bool {
+					auto it = find_if( node->elements.begin( ), node->elements.end( ), [ &altElem ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool {
 						return *a == *altElem;
 					});
 					assert( it != node->elements.end( ) );
 
-					delete *it;
 					node->elements.erase( it );
 				}
 			}
@@ -610,7 +600,6 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node ) const
 			{
 				optimized = true;
 
-				delete *it;
 				it = node->elements.erase( it );
 			}
 			else
@@ -630,12 +619,10 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node ) const
   */
 bool RegExpOptimize::V3( UnboundedRegExpIteration * const & node ) const
 {
-	UnboundedRegExpIteration* childIter = dynamic_cast<UnboundedRegExpIteration*>( node->element );
+	UnboundedRegExpIteration* childIter = dynamic_cast<UnboundedRegExpIteration*>( node->element.get() );
 	if( childIter )
 	{
-		node->element = childIter->element;
-		childIter->element = NULL;
-		delete childIter;
+		node->element = std::move ( childIter->element );
 
 		return true;
 	}
@@ -651,21 +638,18 @@ bool RegExpOptimize::V3( UnboundedRegExpIteration * const & node ) const
 bool RegExpOptimize::V4( UnboundedRegExpIteration * const & node ) const
 {
 	// interpretation: if iteration's element is concat and every concat's element is iteration
-	UnboundedRegExpConcatenation* alt = dynamic_cast<UnboundedRegExpConcatenation*>( node->element );
-	if( ! alt || ! all_of( alt->elements.begin( ), alt->elements.end( ), [] ( UnboundedRegExpElement const * const & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration const * const >( a ); } ) )
+	UnboundedRegExpConcatenation* cont = dynamic_cast<UnboundedRegExpConcatenation*>( node->element.get() );
+	if( ! cont || ! all_of( cont->elements.begin( ), cont->elements.end( ), [] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration const * const >( a.get() ); } ) )
 		return false;
 
 	UnboundedRegExpAlternation * newAlt = new UnboundedRegExpAlternation( );
 
-	for( const auto & n : alt->elements )
+	for( const auto & n : cont->elements )
 	{
-		UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( n );
-		newAlt->elements.push_back( iter->element );
-		iter->element = NULL;
+		newAlt->elements.push_back( std::move ( static_cast<UnboundedRegExpIteration*>(n.get())->element ) );
 	}
 
-	node->element = optimize( newAlt );
-	delete alt;
+	node->element = std::smart_ptr < UnboundedRegExpElement > ( optimize( newAlt ) );
 	delete newAlt;
 
 	return true;
@@ -689,7 +673,7 @@ bool RegExpOptimize::V5( UnboundedRegExpAlternation * const & node ) const
 
 	for( auto itA = node->elements.begin( ); itA != node->elements.end( ); )
 	{
-		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( * itA );
+		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( itA->get() );
 		if( ! concat )
 		{
 			itA ++;
@@ -698,7 +682,7 @@ bool RegExpOptimize::V5( UnboundedRegExpAlternation * const & node ) const
 
 		for( auto itC = concat->elements.begin( ); itC != std::prev( concat->elements.end( ) ); )
 		{
-			UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( *itC );
+			UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( itC->get() );
 			if( ! iter )
 			{
 				itC ++;
@@ -709,9 +693,9 @@ bool RegExpOptimize::V5( UnboundedRegExpAlternation * const & node ) const
 			auto itStartY = std::next( itC ); //itStartY points to y in expression x*xy
 
 			// if iter's element is concat
-			if( dynamic_cast<UnboundedRegExpConcatenation*>( iter->element ) )
+			if( dynamic_cast<UnboundedRegExpConcatenation*>( iter->element.get() ) )
 			{
-				UnboundedRegExpConcatenation * iterConcat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element );
+				UnboundedRegExpConcatenation * iterConcat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element.get() );
 
 				// std::cout << "....." << std::endl;
 				// std::cout << RegExp( concat ) << std::endl;
@@ -722,7 +706,7 @@ bool RegExpOptimize::V5( UnboundedRegExpAlternation * const & node ) const
 
 				if( distance( iterConcat->elements.begin( ), iterConcat->elements.end( ) ) != distance( std::next( itC ), concat->elements.end( ) )
 				 || ! equal( iterConcat->elements.begin( ), iterConcat->elements.end( ), std::next( itC ),
-					[ ]( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool{ return *a == *b; } ) )
+					[ ]( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool{ return *a == *b; } ) )
 				{
 					itC++;
 					continue;
@@ -773,13 +757,15 @@ bool RegExpOptimize::V5( UnboundedRegExpAlternation * const & node ) const
 
 			// concatenate "a" and "y" and see if they exist somewhere in parent alternation ( node->elements )
 			UnboundedRegExpConcatenation* tmpAY = new UnboundedRegExpConcatenation( );
-			tmpAY->elements.push_back( regexpA );
-			tmpAY->elements.push_back( regexpY );
+			tmpAY->elements.push_back( std::smart_ptr < UnboundedRegExpElement > ( regexpA ) );
+			tmpAY->elements.push_back( std::smart_ptr < UnboundedRegExpElement > ( regexpY ) );
 			UnboundedRegExpElement * regexpAY = optimize( tmpAY );
+			regexpA = tmpAY->elements[0].release();
+			regexpY = tmpAY->elements[1].release();
 			tmpAY->elements.clear( );
 			delete tmpAY;
 
-			auto iterAY = find_if( node->elements.begin( ), node->elements.end( ), [ regexpAY ] ( UnboundedRegExpElement const * const & a ) -> bool{ return *a == *regexpAY; } );
+			auto iterAY = find_if( node->elements.begin( ), node->elements.end( ), [ regexpAY ] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return *a == *regexpAY; } );
 			delete regexpAY;
 			if( iterAY == node->elements.end( ) )
 			{
@@ -792,30 +778,25 @@ bool RegExpOptimize::V5( UnboundedRegExpAlternation * const & node ) const
 
 			// if AY exists, then we can simply do this:
 				//iterator invalidated, need to backup concat node
-			UnboundedRegExpElement * tmpItA = *itA;
+			UnboundedRegExpElement * tmpItA = itA->get();
 
-			delete *iterAY;
 			node->elements.erase( iterAY );
 
 				// iterator invalidated, need to recall before erase
-			itA = find_if( node->elements.begin( ), node->elements.end( ), [ tmpItA ]( UnboundedRegExpElement const * const & a ) -> bool { return *a == *tmpItA; } );
+			itA = find_if( node->elements.begin( ), node->elements.end( ), [ tmpItA ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return *a == *tmpItA; } );
 
 			UnboundedRegExpConcatenation * tmpAltered = new UnboundedRegExpConcatenation( );
-			tmpAltered->elements.push_back( regexpA );
+			tmpAltered->elements.push_back( std::smart_ptr < UnboundedRegExpElement > ( regexpA ) );
 			tmpAltered->elements.push_back( * itC );
-			tmpAltered->elements.push_back( regexpY );
+			tmpAltered->elements.push_back( std::smart_ptr < UnboundedRegExpElement > ( regexpY ) );
 			UnboundedRegExpElement * regexpAltered = optimize( tmpAltered );
 
 			tmpAltered->elements.clear( );
 			delete tmpAltered;
 
-			delete regexpA;
-			delete regexpY;
-
-			delete *itA;
 			itA = node->elements.erase( itA );
 
-			node->elements.insert( itA, regexpAltered );
+			node->elements.insert( itA, std::smart_ptr < UnboundedRegExpElement > ( regexpAltered ) );
 
 			optimized = true;
 			break;
@@ -845,7 +826,7 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const
 
 	for( auto itA = node->elements.begin( ); itA != node->elements.end( ); )
 	{
-		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( * itA );
+		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( itA->get() );
 		if( ! concat )
 		{
 			itA ++;
@@ -854,7 +835,7 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const
 
 		for( auto itC = std::next( concat->elements.begin( ) ); itC != concat->elements.end( ); )
 		{
-			UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( * itC );
+			UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( itC->get() );
 			if( ! iter )
 			{
 				itC ++;
@@ -865,9 +846,9 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const
 			auto itStartX = itC; //itStartX points to first x in expression xx*, everything before is therefore prefix - regexp "a"
 
 			// if iter's element is concat
-			if( dynamic_cast<UnboundedRegExpConcatenation*>( iter->element ) )
+			if( dynamic_cast<UnboundedRegExpConcatenation*>( iter->element.get() ) )
 			{
-				UnboundedRegExpConcatenation * iterConcat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element );
+				UnboundedRegExpConcatenation * iterConcat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element.get() );
 
 				if( distance( concat->elements.begin( ), itC ) < (int)iterConcat->elements.size( ) )
 				{
@@ -879,7 +860,7 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const
 				if( distance( iterConcat->elements.begin( ), iterConcat->elements.end( ) ) != distance( itStartX, concat->elements.end( ) )
 					||
 					! equal( iterConcat->elements.begin( ), iterConcat->elements.end( ), itStartX,
-					[]( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool{ return *a == *b; } ) )
+					[]( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool{ return *a == *b; } ) )
 				{
 					itC++;
 					continue;
@@ -929,13 +910,15 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const
 
 			// concatenate "a" and "y" and see if they exist somewhere in parent alternation ( node->elements )
 			UnboundedRegExpConcatenation* tmpAY = new UnboundedRegExpConcatenation( );
-			tmpAY->elements.push_back( regexpA );
-			tmpAY->elements.push_back( regexpY );
+			tmpAY->elements.push_back( std::smart_ptr < UnboundedRegExpElement > ( regexpA ) );
+			tmpAY->elements.push_back( std::smart_ptr < UnboundedRegExpElement > ( regexpY ) );
 			UnboundedRegExpElement * regexpAY = optimize( tmpAY );
+			regexpA = tmpAY->elements[0].release();
+			regexpY = tmpAY->elements[1].release();
 			tmpAY->elements.clear( );
 			delete tmpAY;
 
-			auto iterAY = find_if( node->elements.begin( ), node->elements.end( ), [ regexpAY ] ( UnboundedRegExpElement const * const & a ) -> bool{ return *a == *regexpAY; } );
+			auto iterAY = find_if( node->elements.begin( ), node->elements.end( ), [ regexpAY ] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return *a == *regexpAY; } );
 			delete regexpAY;
 			if( iterAY == node->elements.end( ) )
 			{
@@ -948,29 +931,24 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const
 
 			// if AY exists, then we can simply do this:
 				//iterator invalidated, need to backup concat node
-			UnboundedRegExpElement * tmpItA = *itA;
-			delete *iterAY;
+			UnboundedRegExpElement * tmpItA = itA->get();
 			node->elements.erase( iterAY );
 
 				// iterator invalidated, need to recall before erase
-			itA = find_if( node->elements.begin( ), node->elements.end( ), [ tmpItA ]( UnboundedRegExpElement const * const & a ) -> bool { return *a == *tmpItA; } );
+			itA = find_if( node->elements.begin( ), node->elements.end( ), [ tmpItA ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return *a == *tmpItA; } );
 
 			UnboundedRegExpConcatenation * tmpAltered = new UnboundedRegExpConcatenation( );
-			tmpAltered->elements.push_back( regexpA );
+			tmpAltered->elements.push_back( std::smart_ptr < UnboundedRegExpElement > ( regexpA ) );
 			tmpAltered->elements.push_back( * itC );
-			tmpAltered->elements.push_back( regexpY );
+			tmpAltered->elements.push_back( std::smart_ptr < UnboundedRegExpElement > ( regexpY ) );
 			UnboundedRegExpElement * regexpAltered = optimize( tmpAltered );
 
 			tmpAltered->elements.clear( );
 			delete tmpAltered;
 
-			delete regexpA;
-			delete regexpY;
-
-			delete *itA;
 			itA = node->elements.erase( itA );
 
-			node->elements.insert( itA, regexpAltered );
+			node->elements.insert( itA, std::smart_ptr < UnboundedRegExpElement > ( regexpAltered ) );
 			optimized = true;
 			break;
 		}
@@ -994,7 +972,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const
 
 	for( auto it = next( node->elements.begin( ) ); it != node->elements.end( ); )
 	{
-		UnboundedRegExpIteration* iter = dynamic_cast<UnboundedRegExpIteration*>( * it );
+		UnboundedRegExpIteration* iter = dynamic_cast<UnboundedRegExpIteration*>( it->get() );
 
 		if( ! iter )
 		{
@@ -1003,7 +981,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const
 		}
 
 		// if element of iteration is concatenation, we need to check this specially
-		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element );
+		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element.get() );
 
 		if( concat )
 		{
@@ -1020,12 +998,10 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const
 
 			if( regexp::properties::RegExpEpsilon::languageContainsEpsilon(*concat) &&
 				distance( concat->elements.begin( ), concat->elements.end( )) == distance ( it2, node->elements.end( ) ) &&
-				equal( concat->elements.begin( ), concat->elements.end( ), it2, [] ( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool { return *a == *b; } ) )
+				equal( concat->elements.begin( ), concat->elements.end( ), it2, [] ( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool { return *a == *b; } ) )
 			{
 				optimized = true;
 
-				for( auto delIt = it2 ; delIt != it ; delIt ++ )
-					delete *delIt;
 				it = node->elements.erase( it2, it );
 			}
 			else
@@ -1046,7 +1022,6 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const
 
 			if( regexp::properties::RegExpEpsilon::languageContainsEpsilon(*(iter->element)) && *( iter->element ) == **prev )
 			{
-				delete * prev;
 				it = node->elements.erase( prev );
 				optimized = true;
 
@@ -1078,13 +1053,13 @@ bool RegExpOptimize::V9( UnboundedRegExpConcatenation * const & node ) const
 
 	for( auto it = node->elements.begin( ) ; it != node->elements.end( ) ; )
 	{
-		UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( * it );
+		UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( it->get() );
 		if ( ! iter )
 		{
 			it++;
 			continue;
 		}
-		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element );
+		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element.get() );
 		if( ! concat )
 		{
 			it++;
@@ -1111,7 +1086,7 @@ bool RegExpOptimize::V9( UnboundedRegExpConcatenation * const & node ) const
 		// std::cout << RegExp( tmp ) << std::endl;
 
 		// copy the range <it;sth>, delete it and go back to the iter node
-		std::vector<UnboundedRegExpElement*> copyRange;
+		std::vector<std::smart_ptr < UnboundedRegExpElement > > copyRange;
 		copyRange.insert( copyRange.end(), std::next( it ), c1Iter );
 		it = node->elements.erase( std::next( it ), c1Iter );
 		it = std::prev( it );
@@ -1137,21 +1112,18 @@ bool RegExpOptimize::V9( UnboundedRegExpConcatenation * const & node ) const
 bool RegExpOptimize::V10( UnboundedRegExpIteration * const & node ) const
 {
 	// interpretation: if iter's child is alternation where its every child is iteration, then they do not have to be iteration
-	UnboundedRegExpAlternation* alt = dynamic_cast<UnboundedRegExpAlternation*>( node->element );
-	if( ! alt || ! all_of( alt->elements.begin( ), alt->elements.end( ), [] ( UnboundedRegExpElement const * const & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration const * const >( a ); } ) )
+	UnboundedRegExpAlternation* alt = dynamic_cast<UnboundedRegExpAlternation*>( node->element.get() );
+	if( ! alt || ! all_of( alt->elements.begin( ), alt->elements.end( ), [] ( std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration const * const >( a.get() ); } ) )
 		return false;
 
 	UnboundedRegExpAlternation * newAlt = new UnboundedRegExpAlternation( );
 
 	for( const auto & n : alt->elements )
 	{
-		UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( n );
-		newAlt->elements.push_back( iter->element );
-		iter->element = NULL;
+		newAlt->elements.push_back( std::move ( static_cast<UnboundedRegExpIteration*>(n.get())->element ) );
 	}
 
-	node->element = optimize( newAlt );
-	delete alt;
+	node->element = std::smart_ptr < UnboundedRegExpElement > ( optimize( newAlt ) );
 	delete newAlt;
 
 	return true;
@@ -1167,12 +1139,11 @@ bool RegExpOptimize::X1( UnboundedRegExpAlternation * const & node ) const
 	// theorem: In regexp like a* + \e, \e is described twice, first in a*, second in \e.
 	//  therefore we can delete the \e as it is redundant
 
-	auto iter = find_if( node->elements.begin( ), node->elements.end( ), [] (UnboundedRegExpElement const * const & a ) -> bool { return dynamic_cast<UnboundedRegExpIteration const * const>( a );} );
-	auto eps = find_if( node->elements.begin( ), node->elements.end( ), [] (UnboundedRegExpElement const * const & a ) -> bool { return dynamic_cast<UnboundedRegExpEpsilon const * const>( a );} );
+	auto iter = find_if( node->elements.begin( ), node->elements.end( ), [] (const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return dynamic_cast<UnboundedRegExpIteration const * const>( a.get() );} );
+	auto eps = find_if( node->elements.begin( ), node->elements.end( ), [] (const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return dynamic_cast<UnboundedRegExpEpsilon const * const>( a.get() );} );
 
 	if( iter != node->elements.end( ) && eps != node->elements.end( ) )
 	{
-		delete *eps;
 		node->elements.erase( eps );
 		return true;
 	}
-- 
GitLab