From bbd90d39ba92f49271622e41b7dfd9aa52f51ced Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 19 Jul 2016 08:20:17 +0200
Subject: [PATCH] make optimisation functions static

---
 .../src/regexp/simplify/RegExpOptimize.h      |  47 +++--
 .../simplify/RegExpOptimizeUnboundedPart.cxx  | 180 +++++++++---------
 2 files changed, 109 insertions(+), 118 deletions(-)

diff --git a/alib2algo/src/regexp/simplify/RegExpOptimize.h b/alib2algo/src/regexp/simplify/RegExpOptimize.h
index e8d24797f9..81dab1c699 100644
--- a/alib2algo/src/regexp/simplify/RegExpOptimize.h
+++ b/alib2algo/src/regexp/simplify/RegExpOptimize.h
@@ -61,8 +61,7 @@ namespace simplify {
  *
  *  - X1 : -> : a* + \e = a*
  */
-class RegExpOptimize : public std::SingleDispatch<RegExpOptimize, regexp::RegExp, regexp::RegExpBase>
-{
+class RegExpOptimize : public std::SingleDispatch<RegExpOptimize, regexp::RegExp, regexp::RegExpBase> {
 public:
 	RegExpOptimize() {}
 
@@ -85,28 +84,28 @@ private:
 	regexp::UnboundedRegExpElement * optimize( regexp::UnboundedRegExpEmpty const * const & node ) const;
 
 private:
-	bool A1( regexp::UnboundedRegExpAlternation * const & node ) const;
-	bool A2( regexp::UnboundedRegExpAlternation * const & node ) const;
-	bool A3( regexp::UnboundedRegExpAlternation * const & node ) const;
-	bool A4( regexp::UnboundedRegExpAlternation * const & node ) const;
-	bool A5( regexp::UnboundedRegExpConcatenation * const & node ) const;
-	bool A6( regexp::UnboundedRegExpConcatenation * const & node ) const;
-	bool A7( regexp::UnboundedRegExpConcatenation * const & node ) const;
-	bool A8( regexp::UnboundedRegExpConcatenation * const & node ) const;
-	bool A9( regexp::UnboundedRegExpConcatenation * const & node ) const;
-	bool A10( regexp::UnboundedRegExpAlternation * const & node ) const;
-	bool A11( regexp::UnboundedRegExpIteration * const & node ) const;
-	bool V1( regexp::UnboundedRegExpIteration * const & node ) const;
-	bool V2( regexp::UnboundedRegExpAlternation * const & node ) const;
-	bool V3( regexp::UnboundedRegExpIteration * const & node ) const;
-	bool V4( regexp::UnboundedRegExpIteration * const & node ) const;
-	bool V5( regexp::UnboundedRegExpAlternation * const & node ) const;
-	bool V6( regexp::UnboundedRegExpAlternation * const & node ) const;
-	bool V8( regexp::UnboundedRegExpConcatenation * const & node ) const;
-	bool V9( regexp::UnboundedRegExpConcatenation * const & node ) const;
-	bool V10( regexp::UnboundedRegExpIteration * const & node ) const;
-
-	bool X1( regexp::UnboundedRegExpAlternation * const & node ) const;
+	static bool A1( regexp::UnboundedRegExpAlternation & node );
+	static bool A2( regexp::UnboundedRegExpAlternation & node );
+	static bool A3( regexp::UnboundedRegExpAlternation & node );
+	static bool A4( regexp::UnboundedRegExpAlternation & node );
+	static bool A5( regexp::UnboundedRegExpConcatenation & node );
+	static bool A6( regexp::UnboundedRegExpConcatenation & node );
+	static bool A7( regexp::UnboundedRegExpConcatenation & node );
+	static bool A8( regexp::UnboundedRegExpConcatenation & node );
+	static bool A9( regexp::UnboundedRegExpConcatenation & node );
+	static bool A10( regexp::UnboundedRegExpAlternation & node );
+	static bool A11( regexp::UnboundedRegExpIteration & node );
+	static bool V1( regexp::UnboundedRegExpIteration & node );
+	static bool V2( regexp::UnboundedRegExpAlternation & node );
+	static bool V3( regexp::UnboundedRegExpIteration & node );
+	static bool V4( regexp::UnboundedRegExpIteration & node );
+	static bool V5( regexp::UnboundedRegExpAlternation & node );
+	static bool V6( regexp::UnboundedRegExpAlternation & node );
+	static bool V8( regexp::UnboundedRegExpConcatenation & node );
+	static bool V9( regexp::UnboundedRegExpConcatenation & node );
+	static bool V10( regexp::UnboundedRegExpIteration & node );
+
+	static bool X1( regexp::UnboundedRegExpAlternation & node );
 
 	bool S( regexp::FormalRegExpElement * & node ) const;
 	bool A1( regexp::FormalRegExpElement * & node ) const;
diff --git a/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx b/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx
index 7a073174a4..1fb2421e80 100644
--- a/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx
+++ b/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx
@@ -89,7 +89,7 @@ UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpAlternation co
 		alt->pushBackChild( 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 ) );
+	while( A1( * alt ) || A2( * alt ) || A3( * alt ) || A4( * alt ) || A10( * alt ) || V2( * alt ) || V5( * alt ) || V6( * alt ) || X1( * alt ) );
 
 	if( alt->getElements ( ).size( ) == 1 ) {
 		UnboundedRegExpElement* ret = alt->getChildren ( ).front ( ).release ( );
@@ -111,7 +111,7 @@ UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpConcatenation
 	for( const auto & child : node->getElements ( ) )
 		concat->pushBackChild ( std::smart_ptr < UnboundedRegExpElement > ( optimize( child.get() ) ) );
 
-	while( A5( concat ) || A6( concat ) || A7( concat ) || A8( concat ) || A9( concat ) || V8( concat ) );//|| V9( concat ) );
+	while( A5( * concat ) || A6( * concat ) || A7( * concat ) || A8( * concat ) || A9( * concat ) || V8( * concat ) );//|| V9( * concat ) );
 
 	if( concat->getElements ( ).size( ) == 1 ) {
 		UnboundedRegExpElement* ret = concat->getChildren ( ).front( ).release();
@@ -142,7 +142,7 @@ UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpIteration cons
 			delete iter;
 			return new UnboundedRegExpEpsilon( );
 		}
-	} while( A11( iter ) || V1( iter ) || V3( iter ) || V4( iter ) || V10( iter ) );
+	} while( A11( * iter ) || V1( * iter ) || V3( * iter ) || V4( * iter ) || V10( * iter ) );
 
 	return iter;
 }
@@ -164,14 +164,15 @@ UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpEpsilon const
   * @param node UnboundedRegExpAlternation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A1( UnboundedRegExpAlternation * const & node ) const {
+bool RegExpOptimize::A1( UnboundedRegExpAlternation & node ) {
 	bool optimized = false;
-	for( auto it = node->getChildren ( ).begin( ); it != node->getChildren ( ).end( ); ) {
+
+	for( auto it = node.getChildren ( ).begin( ); it != node.getChildren ( ).end( ); ) {
 		if( dynamic_cast < UnboundedRegExpAlternation * > ( it->get ( ) ) ) {
 			std::smart_ptr < UnboundedRegExpAlternation > childAlt ( static_cast < UnboundedRegExpAlternation * >( it->release() ) );
-			it = node->getChildren ( ).erase( it );
+			it = node.getChildren ( ).erase( it );
 
-			it = node->insert( it, std::make_move_iterator(childAlt->getChildren ( ).begin ( ) ), std::make_move_iterator(childAlt->getChildren ( ).end ( ) ) );
+			it = node.insert( it, std::make_move_iterator(childAlt->getChildren ( ).begin ( ) ), std::make_move_iterator(childAlt->getChildren ( ).end ( ) ) );
 
  			optimized = true;
 		} else
@@ -186,13 +187,13 @@ bool RegExpOptimize::A1( UnboundedRegExpAlternation * const & node ) const {
   * @param node UnboundedRegExpAlternation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A2( UnboundedRegExpAlternation * const & node ) const {
+bool RegExpOptimize::A2( UnboundedRegExpAlternation & node ) {
 	auto cmp = [ ]( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool { return *a < *b; };
 
-	if( std::is_sorted( node->getChildren ( ).begin( ), node->getChildren ( ).end( ), cmp ) )
+	if( std::is_sorted( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), cmp ) )
 		return false;
 
-	std::sort( node->getChildren ( ).begin(), node->getChildren ( ).end(), cmp );
+	std::sort( node.getChildren ( ).begin(), node.getChildren ( ).end(), cmp );
 	return true;
 }
 
@@ -201,14 +202,14 @@ bool RegExpOptimize::A2( UnboundedRegExpAlternation * const & node ) const {
   * @param node UnboundedRegExpAlternation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A3( UnboundedRegExpAlternation * const & node ) const {
+bool RegExpOptimize::A3( UnboundedRegExpAlternation & node ) {
 	bool optimized = false;
 
 	// alternation with no children is efectively \0
 
-	for( auto it = node->getChildren ( ).begin( ); it != node->getChildren ( ).end( ); ) {
+	for( auto it = node.getChildren ( ).begin( ); it != node.getChildren ( ).end( ); ) {
 		if( dynamic_cast < UnboundedRegExpEmpty * >( it->get ( ) ) ) {
-			it = node->getChildren ( ).erase( it );
+			it = node.getChildren ( ).erase( it );
 
 			optimized = true;
 		} else
@@ -223,7 +224,7 @@ bool RegExpOptimize::A3( UnboundedRegExpAlternation * const & node ) const {
   * @param node UnboundedRegExpAlternation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A4( UnboundedRegExpAlternation * const & node ) const {
+bool RegExpOptimize::A4( UnboundedRegExpAlternation & node ) {
 	/*
 	 * two ways of implementing this opitimization:
 	 * - sort and call std::unique ( O(n lg n) + O(n) ), but it also sorts...
@@ -233,10 +234,10 @@ bool RegExpOptimize::A4( UnboundedRegExpAlternation * const & node ) const {
 	 */
 	auto cmp = [ ]( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool { return *a == *b; };
 
-	size_t size = node->getChildren ( ).size ( );
-	std::unique ( node->getChildren ( ).begin ( ), node->getChildren ( ).end ( ), cmp);
+	size_t size = node.getChildren ( ).size ( );
+	std::unique ( node.getChildren ( ).begin ( ), node.getChildren ( ).end ( ), cmp);
 
-	return size != node->getChildren ( ).size ( );
+	return size != node.getChildren ( ).size ( );
 }
 
 /**
@@ -244,15 +245,15 @@ bool RegExpOptimize::A4( UnboundedRegExpAlternation * const & node ) const {
   * @param node UnboundedRegExpConcatenation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A5( UnboundedRegExpConcatenation * const & node ) const {
+bool RegExpOptimize::A5( UnboundedRegExpConcatenation & node ) {
 	bool optimized = false;
 
-	for( auto it = node->getChildren ( ).begin( ); it != node->getChildren ( ).end( ); ) {
+	for( auto it = node.getChildren ( ).begin( ); it != node.getChildren ( ).end( ); ) {
 		if( dynamic_cast<UnboundedRegExpConcatenation *>( it->get() ) ) {
 			std::smart_ptr < UnboundedRegExpConcatenation > childConcat ( static_cast<UnboundedRegExpConcatenation *>( it->release() ) );
-			it = node->getChildren ( ).erase( it );
+			it = node.getChildren ( ).erase( it );
 
-			it = node->insert( it, std::make_move_iterator(childConcat->getChildren ( ).begin( )), std::make_move_iterator(childConcat->getChildren ( ).end( ) ));
+			it = node.insert( it, std::make_move_iterator(childConcat->getChildren ( ).begin( )), std::make_move_iterator(childConcat->getChildren ( ).end( ) ));
 
 			optimized = true;
 		} else
@@ -267,14 +268,14 @@ bool RegExpOptimize::A5( UnboundedRegExpConcatenation * const & node ) const {
   * @param node UnboundedRegExpConcatenation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A6( UnboundedRegExpConcatenation * const & node ) const {
+bool RegExpOptimize::A6( UnboundedRegExpConcatenation & node ) {
 	bool optimized = false;
 
 	// concatenation with no children is efectively \e
 
-	for( auto it = node->getChildren ( ).begin( ); it != node->getChildren ( ).end( ); ) {
+	for( auto it = node.getChildren ( ).begin( ); it != node.getChildren ( ).end( ); ) {
 		if( dynamic_cast < UnboundedRegExpEpsilon * >( it->get ( ) ) ) {
-			it = node->getChildren ( ).erase( it );
+			it = node.getChildren ( ).erase( it );
 
 			optimized = true;
 		} else
@@ -289,12 +290,12 @@ bool RegExpOptimize::A6( UnboundedRegExpConcatenation * const & node ) const {
   * @param node UnboundedRegExpConcatenation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A7( UnboundedRegExpConcatenation * const & node ) const {
-	if( std::any_of( node->getChildren ( ).begin( ), node->getChildren ( ).end( ), []( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return dynamic_cast < UnboundedRegExpEmpty * >( a.get() ); } ) ) {
-		if(node->getChildren ( ).size() == 1) return false;
+bool RegExpOptimize::A7( UnboundedRegExpConcatenation & node ) {
+	if(node.getChildren ( ).size() == 1) return false;
 
-		node->getChildren ( ).clear( );
-		node->pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( new UnboundedRegExpEmpty( ) ) );
+	if( std::any_of( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), []( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return dynamic_cast < UnboundedRegExpEmpty * >( a.get() ); } ) ) {
+		node.getChildren ( ).clear( );
+		node.pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( new UnboundedRegExpEmpty( ) ) );
 
 		return true;
 	}
@@ -307,8 +308,7 @@ bool RegExpOptimize::A7( UnboundedRegExpConcatenation * const & node ) const {
   * @param node UnboundedRegExpConcatenation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A8( UnboundedRegExpConcatenation * const & /* node */) const
-{
+bool RegExpOptimize::A8( UnboundedRegExpConcatenation & /* node */) {
 /*
 	bool optimized = false;
 
@@ -355,8 +355,7 @@ bool RegExpOptimize::A8( UnboundedRegExpConcatenation * const & /* node */) cons
   * @param node UnboundedRegExpConcatenation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A9( UnboundedRegExpConcatenation * const & /* node */) const
-{
+bool RegExpOptimize::A9( UnboundedRegExpConcatenation & /* node */) {
 /*
 	bool optimized = false;
 
@@ -406,7 +405,7 @@ bool RegExpOptimize::A9( UnboundedRegExpConcatenation * const & /* node */) cons
   * @param node UnboundedRegExpAlternation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A10( UnboundedRegExpAlternation * const & node ) const {
+bool RegExpOptimize::A10( UnboundedRegExpAlternation & node ) {
 	bool optimized = false;
 
 	/*
@@ -416,15 +415,15 @@ bool RegExpOptimize::A10( UnboundedRegExpAlternation * const & node ) const {
 	 */
 
 	// check if we have some epsilon or iteration left, else nothing to do
-	auto eps = find_if( node->getElements().begin( ), node->getElements().end( ), [ ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool {
+	auto eps = find_if( node.getElements().begin( ), node.getElements().end( ), [ ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool {
 		return dynamic_cast<UnboundedRegExpEpsilon const *>( a.get() ) || dynamic_cast<UnboundedRegExpIteration const*>( a.get() );
 	});
 
-	if( eps == node->getElements().end( ) )
+	if( eps == node.getElements().end( ) )
 		return false;
 
-	for( unsigned i = 0; i < node->getChildren ( ).size ( ); i++ ) {
-		UnboundedRegExpConcatenation * childConcat = dynamic_cast<UnboundedRegExpConcatenation *>( node->getChildren ( ) [ i ].get ( ) );
+	for( unsigned i = 0; i < node.getChildren ( ).size ( ); i++ ) {
+		UnboundedRegExpConcatenation * childConcat = dynamic_cast<UnboundedRegExpConcatenation *>( node.getChildren ( ) [ i ].get ( ) );
 		if( ! childConcat )
 			continue;
 
@@ -436,13 +435,13 @@ bool RegExpOptimize::A10( UnboundedRegExpAlternation * const & node ) const {
 		// concatenation without the iteration node
 		UnboundedRegExpConcatenation tmpConcat ( * childConcat );
 		tmpConcat.getChildren ( ).erase( tmpConcat.getChildren ( ).begin( ) );
+		UnboundedRegExpElement * tmpConcatOpt = RegExpOptimize::REG_EXP_OPTIMIZE.optimize ( & tmpConcat );
 
-		UnboundedRegExpElement * tmpConcatOpt = optimize( & tmpConcat );
 		// check if the iteration element is the same as the rest of the concatenation
 		if( iter->getElement() == * tmpConcatOpt ) {
 			optimized = true;
 
-			node->setChild ( std::move ( childConcat->getElements().front() ), i );
+			node.setChild ( std::move ( childConcat->getElements().front() ), i );
 		}
 
 		delete tmpConcatOpt;
@@ -456,10 +455,8 @@ bool RegExpOptimize::A10( UnboundedRegExpAlternation * const & node ) const {
   * @param node UnboundedRegExpIteration node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A11( UnboundedRegExpIteration * const & node ) const {
-	bool optimized = false;
-
-	UnboundedRegExpAlternation * const & childAlt = dynamic_cast<UnboundedRegExpAlternation *>( node->getChild ( ).get() );
+bool RegExpOptimize::A11( UnboundedRegExpIteration & node ) {
+	UnboundedRegExpAlternation * childAlt = dynamic_cast<UnboundedRegExpAlternation *>( node.getChild ( ).get() );
 
 	if( childAlt ) {
 		// check if eps inside iteration's alternation
@@ -472,11 +469,11 @@ bool RegExpOptimize::A11( UnboundedRegExpIteration * const & node ) const {
 			return false;
 
 		// remove eps from alternation
-		optimized = true;
 		childAlt->getChildren ( ).erase( eps );
+		return true;
 	}
 
-	return optimized;
+	return false;
 }
 
 /**
@@ -484,8 +481,7 @@ bool RegExpOptimize::A11( UnboundedRegExpIteration * const & node ) const {
   * @param node UnboundedRegExpIteration node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V1( UnboundedRegExpIteration * const &) const
-{
+bool RegExpOptimize::V1( UnboundedRegExpIteration &) {
 	// implemented in optimize( UnboundedRegExpIteration )
 
 	return false;
@@ -496,7 +492,7 @@ bool RegExpOptimize::V1( UnboundedRegExpIteration * const &) const
   * @param node UnboundedRegExpAlternation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node ) const {
+bool RegExpOptimize::V2( UnboundedRegExpAlternation & node ) {
 	bool optimized = false;
 
 	/*
@@ -506,7 +502,7 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node ) const {
 
 	std::vector < UnboundedRegExpElement * > iterElements;
 	// cache  iter elements because of operator invalidation after erase
-	for( const std::smart_ptr < UnboundedRegExpElement > & n : node->getElements ( ) ) {
+	for( const std::smart_ptr < UnboundedRegExpElement > & n : node.getElements ( ) ) {
 		UnboundedRegExpIteration * iter = dynamic_cast < UnboundedRegExpIteration * > ( n.get ( ) );
 		if( iter ) {
 			UnboundedRegExpAlternation * inner = dynamic_cast < UnboundedRegExpAlternation * > ( iter->getChild ( ).get ( ) );
@@ -520,16 +516,16 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node ) const {
 	}
 
 	for( UnboundedRegExpElement * n : iterElements ) {
-		auto it = find_if( node->getChildren().begin( ), node->getChildren().end( ), [ n ] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool {
+		auto it = find_if( node.getChildren().begin( ), node.getChildren().end( ), [ n ] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool {
 			return *a == *n;
 		});
 
-		if( it == node->getChildren().end() ) {
+		if( it == node.getChildren().end() ) {
 			continue;
 		}
 
 		optimized = true;
-		node->getChildren().erase( it );
+		node.getChildren().erase( it );
 	}
 
 	return optimized;
@@ -540,10 +536,10 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node ) const {
   * @param node UnboundedRegExpIteration node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V3( UnboundedRegExpIteration * const & node ) const {
-	UnboundedRegExpIteration* childIter = dynamic_cast<UnboundedRegExpIteration*>( node->getChild ( ).get() );
+bool RegExpOptimize::V3( UnboundedRegExpIteration & node ) {
+	UnboundedRegExpIteration* childIter = dynamic_cast<UnboundedRegExpIteration*>( node.getChild ( ).get() );
 	if( childIter ) {
-		node->setChild ( std::move ( childIter->getChild ( ) ) );
+		node.setChild ( std::move ( childIter->getChild ( ) ) );
 
 		return true;
 	}
@@ -556,20 +552,18 @@ bool RegExpOptimize::V3( UnboundedRegExpIteration * const & node ) const {
   * @param node UnboundedRegExpIteration node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V4( UnboundedRegExpIteration * const & node ) const {
+bool RegExpOptimize::V4( UnboundedRegExpIteration & node ) {
 	// interpretation: if iteration's element is concat and every concat's element is iteration
-	UnboundedRegExpConcatenation* cont = dynamic_cast<UnboundedRegExpConcatenation*>( node->getChild ( ).get() );
+	UnboundedRegExpConcatenation* cont = dynamic_cast<UnboundedRegExpConcatenation*>( node.getChild ( ).get() );
 	if( ! cont || ! all_of( cont->getChildren ( ).begin( ), cont->getChildren ( ).end( ), [] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration * >( a.get() ); } ) )
 		return false;
 
-	UnboundedRegExpAlternation * newAlt = new UnboundedRegExpAlternation( );
+	UnboundedRegExpAlternation newAlt;
 
-	for( const auto & n : cont->getChildren ( ) ) {
-		newAlt->pushBackChild ( std::move ( static_cast < UnboundedRegExpIteration * > ( n.get ( ) )->getChild ( ) ) );
-	}
+	for( const auto & n : cont->getChildren ( ) )
+		newAlt.pushBackChild ( std::move ( static_cast < UnboundedRegExpIteration * > ( n.get ( ) )->getChild ( ) ) );
 
-	node->setChild ( std::smart_ptr < UnboundedRegExpElement > ( optimize ( newAlt ) ) );
-	delete newAlt;
+	node.setChild ( std::smart_ptr < UnboundedRegExpElement > ( RegExpOptimize::REG_EXP_OPTIMIZE.optimize ( & newAlt ) ) );
 
 	return true;
 }
@@ -579,8 +573,7 @@ bool RegExpOptimize::V4( UnboundedRegExpIteration * const & node ) const {
   * @param node UnboundedRegExpAlternation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V5( UnboundedRegExpAlternation * const & /* node */ ) const
-{
+bool RegExpOptimize::V5( UnboundedRegExpAlternation & /* node */ ) {
 /*	bool optimized = false; */
 
 	// reinterpretation: ax*y = ay+ax*xy
@@ -733,7 +726,7 @@ bool RegExpOptimize::V5( UnboundedRegExpAlternation * const & /* node */ ) const
   * @param node UnboundedRegExpAlternation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const {
+bool RegExpOptimize::V6( UnboundedRegExpAlternation & node ) {
 	bool optimized = false;
 
 	// reinterpretation: ax*y = ay+axx*y
@@ -743,7 +736,7 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const {
 	//	y = rest (suffix)
 	// prefix.xx*.suffix + prefix.suffix = prefix.x*.suffix
 
-	for( auto itA = node->getChildren ( ).begin( ); itA != node->getChildren ( ).end( ); ) {
+	for( auto itA = node.getChildren ( ).begin( ); itA != node.getChildren ( ).end( ); ) {
 		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( itA->get() );
 		if( ! concat ) {
 			++ itA;
@@ -792,7 +785,7 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const {
 			} else {
 				UnboundedRegExpConcatenation* tmpA = new UnboundedRegExpConcatenation( );
 				tmpA->insert( tmpA->getChildren().end( ), concat->getChildren().begin( ), itStartX );
-				regexpA = optimize( tmpA );
+				regexpA = RegExpOptimize::REG_EXP_OPTIMIZE.optimize( tmpA );
 				delete tmpA;
 			}
 
@@ -803,7 +796,7 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const {
 			} else {
 				UnboundedRegExpConcatenation* tmpY = new UnboundedRegExpConcatenation( );
 				tmpY->insert( tmpY->getChildren().end( ), std::next( itC ), concat->getChildren ( ).end( ) );
-				regexpY = optimize( tmpY );
+				regexpY = RegExpOptimize::REG_EXP_OPTIMIZE.optimize( tmpY );
 				delete tmpY;
 			}
 
@@ -811,14 +804,14 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const {
 			UnboundedRegExpConcatenation* tmpAY = new UnboundedRegExpConcatenation( );
 			tmpAY->pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( regexpA ) );
 			tmpAY->pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( regexpY ) );
-			UnboundedRegExpElement * regexpAY = optimize( tmpAY );
+			UnboundedRegExpElement * regexpAY = RegExpOptimize::REG_EXP_OPTIMIZE.optimize( tmpAY );
 			regexpA = tmpAY->getChildren()[0].release();
 			regexpY = tmpAY->getChildren()[1].release();
 			delete tmpAY;
 
-			auto iterAY = find_if( node->getChildren().begin( ), node->getChildren().end( ), [ regexpAY ] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return *a == *regexpAY; } );
+			auto iterAY = find_if( node.getChildren().begin( ), node.getChildren().end( ), [ regexpAY ] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return *a == *regexpAY; } );
 			delete regexpAY;
-			if( iterAY == node->getChildren().end( ) ) {
+			if( iterAY == node.getChildren().end( ) ) {
 				++ itC;
 
 				delete regexpA;
@@ -829,20 +822,20 @@ 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->get();
-			node->getChildren().erase( iterAY );
+			node.getChildren().erase( iterAY );
 
 			// iterator invalidated, need to recall before erase
-			itA = find_if( node->getChildren().begin( ), node->getChildren().end( ), [ tmpItA ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return *a == *tmpItA; } );
+			itA = find_if( node.getChildren().begin( ), node.getChildren().end( ), [ tmpItA ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return *a == *tmpItA; } );
 
 			UnboundedRegExpConcatenation * tmpAltered = new UnboundedRegExpConcatenation( );
 			tmpAltered->pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( regexpA ) );
 			tmpAltered->pushBackChild( * itC );
 			tmpAltered->pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( regexpY ) );
-			UnboundedRegExpElement * regexpAltered = optimize( tmpAltered );
+			UnboundedRegExpElement * regexpAltered = RegExpOptimize::REG_EXP_OPTIMIZE.optimize( tmpAltered );
 
 			delete tmpAltered;
 
-			node->setChild( std::smart_ptr < UnboundedRegExpElement > ( regexpAltered ), itA );
+			node.setChild( std::smart_ptr < UnboundedRegExpElement > ( regexpAltered ), itA );
 			optimized = true;
 			break;
 		}
@@ -858,15 +851,15 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const {
   * @param node UnboundedRegExpConcatenation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const {
+bool RegExpOptimize::V8( UnboundedRegExpConcatenation & node ) {
 	bool optimized = false;
 
 	// interpretation: if there is iteration in concatenation node, and element of iteration contains eps and is straight before this iteration, then this element can be omitted
 
-	if ( node->getChildren ( ).size ( ) == 0 )
+	if ( node.getChildren ( ).size ( ) == 0 )
 		return false;
 
-	for( auto it = next ( node->getChildren ( ).begin( ) ); it != node->getChildren ( ).end( ); ) {
+	for( auto it = next ( node.getChildren ( ).begin( ) ); it != node.getChildren ( ).end( ); ) {
 		UnboundedRegExpIteration* iter = dynamic_cast<UnboundedRegExpIteration*>( it->get() );
 
 		if( ! iter ) {
@@ -879,7 +872,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const {
 
 		if( concat ) {
 			// check if not out of bounds
-			if( ( unsigned ) distance( node->getChildren ( ).begin( ), it ) < concat->getChildren ( ).size ( ) ) {
+			if( ( unsigned ) distance( node.getChildren ( ).begin( ), it ) < concat->getChildren ( ).size ( ) ) {
 				it ++;
 				continue;
 			}
@@ -889,22 +882,22 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const {
 			advance( it2, - (int) concat->getChildren().size( ) );
 
 			if( regexp::properties::RegExpEpsilon::languageContainsEpsilon(*concat) &&
-				concat->getChildren().size ( ) == ( unsigned ) distance ( it2, node->getChildren ( ).end( ) ) &&
+				concat->getChildren().size ( ) == ( unsigned ) distance ( it2, node.getChildren ( ).end( ) ) &&
 				equal( concat->getChildren ( ).begin( ), concat->getChildren ( ).end( ), it2, [] ( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool { return *a == *b; } ) ) {
 				optimized = true;
 
-				it = node->getChildren().erase( it2, it );
+				it = node.getChildren().erase( it2, it );
 			} else
 				++ it;
 		} else {
 			auto prev = std::prev ( it );
 
 			if( regexp::properties::RegExpEpsilon::languageContainsEpsilon(iter->getElement()) && iter->getElement ( ) == **prev ) {
-				it = node->getChildren().erase( prev );
+				it = node.getChildren().erase( prev );
 				optimized = true;
 
 				// in case xxx*, we need to stay on the iter element, not to go behind it
-				if( it != node->getChildren().begin( ) )
+				if( it != node.getChildren().begin( ) )
 					it = std::prev( it );
 			} else
 				++ it;
@@ -919,8 +912,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const {
   * @param node UnboundedRegExpConcatenation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V9( UnboundedRegExpConcatenation * const & /* node */ ) const
-{
+bool RegExpOptimize::V9( UnboundedRegExpConcatenation & /* node */ ) {
 /*	bool optimized = false; */
 
 	// interpretation: if concat (C1) with iter && iteration's element is concat (C2), then:
@@ -986,9 +978,9 @@ bool RegExpOptimize::V9( UnboundedRegExpConcatenation * const & /* node */ ) con
   * @param node UnboundedRegExpIteration node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V10( UnboundedRegExpIteration * const & node ) const {
+bool RegExpOptimize::V10( UnboundedRegExpIteration & node ) {
 	// interpretation: if iter's child is alternation where some of its children are iteration, then they do not have to be iterations
-	UnboundedRegExpAlternation* alt = dynamic_cast<UnboundedRegExpAlternation*>( node->getChild ( ).get() );
+	UnboundedRegExpAlternation* alt = dynamic_cast<UnboundedRegExpAlternation*>( node.getChild ( ).get() );
 	if( ! alt || ! any_of( alt->getChildren ( ).begin( ), alt->getChildren ( ).end( ), [] ( std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration * >( a.get() ); } ) )
 		return false;
 
@@ -1005,15 +997,15 @@ bool RegExpOptimize::V10( UnboundedRegExpIteration * const & node ) const {
   * @param node UnboundedRegExpAlternation node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::X1( UnboundedRegExpAlternation * const & node ) const {
+bool RegExpOptimize::X1( UnboundedRegExpAlternation & node ) {
 	// 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->getChildren ( ).begin( ), node->getChildren ( ).end( ), [] (const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return dynamic_cast<UnboundedRegExpIteration * >( a.get() );} );
-	auto eps = find_if( node->getChildren ( ).begin( ), node->getChildren ( ).end( ), [] (const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return dynamic_cast<UnboundedRegExpEpsilon * >( a.get() );} );
+	auto iter = find_if( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), [] (const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return dynamic_cast<UnboundedRegExpIteration * >( a.get() );} );
+	auto eps = find_if( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), [] (const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return dynamic_cast<UnboundedRegExpEpsilon * >( a.get() );} );
 
-	if( iter != node->getChildren ( ).end( ) && eps != node->getChildren ( ).end( ) ) {
-		node->getChildren ( ).erase( eps );
+	if( iter != node.getChildren ( ).end( ) && eps != node.getChildren ( ).end( ) ) {
+		node.getChildren ( ).erase( eps );
 		return true;
 	}
 
-- 
GitLab