From 76a324006ae3367efae9aa8b50fb0cb24f27b494 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Mon, 30 May 2016 11:35:41 +0200
Subject: [PATCH] iteration improvements

---
 alib2algo/src/automaton/run/Run.cpp           | 40 +++++++--------
 .../src/automaton/transform/PDAToRHPDA.cpp    | 49 ++++++++++---------
 .../equations/LeftRegularEquationSolver.cpp   |  8 +--
 .../equations/RightRegularEquationSolver.cpp  |  8 +--
 .../src/regexp/glushkov/GlushkovTraversal.cpp |  9 ++--
 .../src/regexp/transform/RegExpDerivation.cpp |  2 +-
 alib2std/src/extensions/iterator.hpp          | 38 ++++++++++++++
 alib2std/src/iterator                         |  7 +++
 8 files changed, 103 insertions(+), 58 deletions(-)
 create mode 100644 alib2std/src/extensions/iterator.hpp
 create mode 100644 alib2std/src/iterator

diff --git a/alib2algo/src/automaton/run/Run.cpp b/alib2algo/src/automaton/run/Run.cpp
index 3580d1bc9f..6c025718f2 100644
--- a/alib2algo/src/automaton/run/Run.cpp
+++ b/alib2algo/src/automaton/run/Run.cpp
@@ -19,6 +19,7 @@
 
 #include <deque>
 #include <algorithm>
+#include <iterator>
 
 namespace automaton {
 
@@ -246,7 +247,7 @@ std::tuple < bool, State, std::set < unsigned >, std::deque < alphabet::Symbol >
 
 		for ( unsigned j = 0; j < operation.first.size ( ); j++ ) pushdownStore.pop_back ( );
 
-		for ( auto iter = operation.second.rbegin ( ); iter != operation.second.rend ( ); ++iter ) pushdownStore.push_back ( * iter );
+		for ( const auto & symbol : std::make_reverse ( operation.second ) ) pushdownStore.push_back ( symbol );
 
 		state = transition->second;
 		i++;
@@ -447,7 +448,7 @@ std::tuple < bool, State, std::set < unsigned >, std::deque < alphabet::Symbol >
 
 		for ( unsigned j = 0; j < std::get < 2 > ( transition->first ).size ( ); j++ ) pushdownStore.pop_back ( );
 
-		for ( auto iter = transition->second.second.rbegin ( ); iter != transition->second.second.rend ( ); ++iter ) pushdownStore.push_back ( * iter );
+		for ( const auto & symbol : std::make_reverse ( transition->second.second ) ) pushdownStore.push_back ( symbol );
 
 		state = transition->second.first;
 
@@ -519,12 +520,11 @@ std::tuple < bool, std::set < State >, std::set < std::vector < alphabet::Symbol
 			continue;
 		}
 
-		auto transitions = automaton . getTransitionsFromState ( state );
-		for ( auto transition = transitions . begin (); transition != transitions . end (); transition ++ ) {
-			if ( std::get<1>(transition -> first) != (* symbolIter) && ! std::get<1>(transition -> first) . is<string::Epsilon>() ) {
+		for ( const auto & transition : automaton . getTransitionsFromState ( state ) ) {
+			if ( std::get<1>(transition . first) != (* symbolIter) && ! std::get<1>(transition . first) . is<string::Epsilon>() )
 				continue;
-			}
-			auto pop = std::get<2>(transition -> first);
+
+			const auto & pop = std::get<2>(transition . first);
 			graphStructuredStack * stackNodeCopy = stackNode;
 			graphStructuredStack * outputNodeCopy = outputNode;
 
@@ -534,33 +534,31 @@ std::tuple < bool, std::set < State >, std::set < std::vector < alphabet::Symbol
 					break;
 				}
 				stackNodeCopy = stackNodeCopy -> parent;
-			}			
+			}
 			if ( j == pop . size () ) {
-				for ( auto iter = (std::get<1>(transition -> second)).rbegin(); iter != (std::get<1>(transition -> second)).rend(); iter ++ ) {
-					stackNodeCopy = new graphStructuredStack ( stackNodeCopy, (* iter) );
+				for ( const auto & elem : std::make_reverse ( std::get<1>(transition . second ) ) ) {
+					stackNodeCopy = new graphStructuredStack ( stackNodeCopy, elem );
 					allNodes . insert ( stackNodeCopy );
 				}
-				for ( auto iter = (std::get<2>(transition -> second)).begin(); iter != (std::get<2>(transition -> second)).end(); iter ++ ) {
-					outputNodeCopy = new graphStructuredStack ( outputNodeCopy, (* iter) );
+				for ( const auto & elem : std::get<2>(transition . second) ) {
+					outputNodeCopy = new graphStructuredStack ( outputNodeCopy, elem );
 					allNodes . insert ( outputNodeCopy );
 				}
 
-				if ( ! std::get<1>(transition -> first) . is<string::Epsilon>() ) {
-					configuration = std::make_tuple ( std::get<0>(transition -> second), symbolIter + 1, stackNodeCopy, outputNodeCopy );
-				}
-				else {
-					configuration = std::make_tuple ( std::get<0>(transition -> second), symbolIter, stackNodeCopy, outputNodeCopy );					
+				if ( ! std::get<1>(transition . first) . is<string::Epsilon>() ) {
+					configuration = std::make_tuple ( std::get<0>(transition . second), symbolIter + 1, stackNodeCopy, outputNodeCopy );
+				} else {
+					configuration = std::make_tuple ( std::get<0>(transition . second), symbolIter, stackNodeCopy, outputNodeCopy );
 				}
 				bftQueue . push_back ( configuration );
-			}
-			else {
+			} else {
 				states . insert ( state );
 			}
 		}
 	}
 
-	for ( auto iter = allNodes . begin (); iter != allNodes . end (); iter ++ ) {
-		delete (* iter);
+	for ( const auto & elem : allNodes ) {
+		delete elem;
 	}
 
 	return std::make_tuple ( res, states, allOutputs );
diff --git a/alib2algo/src/automaton/transform/PDAToRHPDA.cpp b/alib2algo/src/automaton/transform/PDAToRHPDA.cpp
index 37ee089dba..6c428137a7 100644
--- a/alib2algo/src/automaton/transform/PDAToRHPDA.cpp
+++ b/alib2algo/src/automaton/transform/PDAToRHPDA.cpp
@@ -17,6 +17,7 @@
 #include <set>
 #include <map>
 #include <queue>
+#include <iterator>
 
 namespace automaton {
 
@@ -66,40 +67,40 @@ automaton::RealTimeHeightDeterministicDPDA PDAToRHPDA::convert ( const automaton
 			int popPushSymbols = std::get < 2 > ( transition.first ).size ( ) + to.second.size ( );
 
 			automaton::State lastUS = automaton::createUniqueState ( automaton::State ( us + std::to_string ( i ) ), res.getStates ( ) );
-			std::for_each ( std::get < 2 > ( transition.first ).begin ( ), std::get < 2 > ( transition.first ).end ( ), [&] ( const alphabet::Symbol & pop ) {
-					automaton::State fromState = ( popPushIndex == 0 ) ? std::get < 0 > ( transition.first ) : lastUS;
+			for ( const alphabet::Symbol & pop :std::get < 2 > ( transition.first ) ) {
+				automaton::State fromState = ( popPushIndex == 0 ) ? std::get < 0 > ( transition.first ) : lastUS;
 
-					if ( popPushIndex != 0 ) lastUS = automaton::createUniqueState ( automaton::State ( us + std::to_string ( ++i ) ), res.getStates ( ) );
+				if ( popPushIndex != 0 ) lastUS = automaton::createUniqueState ( automaton::State ( us + std::to_string ( ++i ) ), res.getStates ( ) );
 
-					automaton::State toState = ( popPushIndex == popPushSymbols - 1 ) ? to.first : lastUS;
+				automaton::State toState = ( popPushIndex == popPushSymbols - 1 ) ? to.first : lastUS;
 
-					res.addState ( fromState );
-					res.addState ( toState );
+				res.addState ( fromState );
+				res.addState ( toState );
 
-					if ( popPushIndex == 0 )
-						res.addReturnTransition ( fromState, std::get < 1 > ( transition.first ), pop, toState );
-					else
-						res.addReturnTransition ( fromState, pop, toState );
+				if ( popPushIndex == 0 )
+					res.addReturnTransition ( fromState, std::get < 1 > ( transition.first ), pop, toState );
+				else
+					res.addReturnTransition ( fromState, pop, toState );
 
-					popPushIndex++;
-				} );
-			std::for_each ( to.second.rbegin ( ), to.second.rend ( ), [&] ( const alphabet::Symbol & push ) {
-					automaton::State fromState = ( popPushIndex == 0 ) ? std::get < 0 > ( transition.first ) : lastUS;
+				popPushIndex++;
+			}
+			for ( const alphabet::Symbol & push : std::make_reverse ( to.second ) ) {
+				automaton::State fromState = ( popPushIndex == 0 ) ? std::get < 0 > ( transition.first ) : lastUS;
 
-					if ( popPushIndex != 0 ) lastUS = automaton::createUniqueState ( automaton::State ( us + std::to_string ( ++i ) ), res.getStates ( ) );
+				if ( popPushIndex != 0 ) lastUS = automaton::createUniqueState ( automaton::State ( us + std::to_string ( ++i ) ), res.getStates ( ) );
 
-					automaton::State toState = ( popPushIndex == popPushSymbols - 1 ) ? to.first : lastUS;
+				automaton::State toState = ( popPushIndex == popPushSymbols - 1 ) ? to.first : lastUS;
 
-					res.addState ( fromState );
-					res.addState ( toState );
+				res.addState ( fromState );
+				res.addState ( toState );
 
-					if ( popPushIndex == 0 )
-						res.addCallTransition ( fromState, std::get < 1 > ( transition.first ), toState, push );
-					else
-						res.addCallTransition ( fromState, toState, push );
+				if ( popPushIndex == 0 )
+					res.addCallTransition ( fromState, std::get < 1 > ( transition.first ), toState, push );
+				else
+					res.addCallTransition ( fromState, toState, push );
 
-					popPushIndex++;
-				} );
+				popPushIndex++;
+			}
 		}
 	}
 
diff --git a/alib2algo/src/equations/LeftRegularEquationSolver.cpp b/alib2algo/src/equations/LeftRegularEquationSolver.cpp
index 59f2d51ab2..19bb0e99e2 100644
--- a/alib2algo/src/equations/LeftRegularEquationSolver.cpp
+++ b/alib2algo/src/equations/LeftRegularEquationSolver.cpp
@@ -13,7 +13,7 @@
 namespace equations {
 
 regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) {
-	for(auto itA = nonterminalSymbolsByDepth.rbegin(); itA != nonterminalSymbolsByDepth.rend(); itA ++) {
+	for(auto itA = nonterminalSymbolsByDepth.rbegin(); itA != nonterminalSymbolsByDepth.rend(); ++ itA) {
 		const alphabet::Symbol& a = * itA;
 
 		/*
@@ -25,7 +25,7 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) {
 		regexp::simplify::RegExpOptimize::optimize(loop);
 
 		// for all transitions from A apply Arden's Lemma
-		for(auto itB = std::next(itA) ; itB != nonterminalSymbolsByDepth.rend(); itB ++) {
+		for(auto itB = std::next(itA) ; itB != nonterminalSymbolsByDepth.rend(); ++ itB) {
 			const alphabet::Symbol& b = * itB;
 			regexp::UnboundedRegExpConcatenation concat;
 			concat.appendElement(std::move(equationTransition.find(std::make_pair(a, b))->second));
@@ -47,10 +47,10 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) {
 		 * eliminate A from rest of the equations using this pattern:
 		 * B->C = B->C + concatenate(B->A, A->C)
 		 */
-		for(auto itB = std::next(itA); itB != nonterminalSymbolsByDepth.rend(); itB ++) {
+		for(auto itB = std::next(itA); itB != nonterminalSymbolsByDepth.rend(); ++ itB) {
 			const alphabet::Symbol& b = * itB;
 
-			for(auto itC = std::next(itA); itC != nonterminalSymbolsByDepth.rend(); itC ++) {
+			for(auto itC = std::next(itA); itC != nonterminalSymbolsByDepth.rend(); ++ itC) {
 				const alphabet::Symbol& c = * itC;
 
 				regexp::UnboundedRegExpConcatenation concat;
diff --git a/alib2algo/src/equations/RightRegularEquationSolver.cpp b/alib2algo/src/equations/RightRegularEquationSolver.cpp
index 8403237f90..71c515d5f2 100644
--- a/alib2algo/src/equations/RightRegularEquationSolver.cpp
+++ b/alib2algo/src/equations/RightRegularEquationSolver.cpp
@@ -13,7 +13,7 @@
 namespace equations {
 
 regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) {
-	for(auto itA = nonterminalSymbolsByDepth.rbegin(); itA != nonterminalSymbolsByDepth.rend(); itA ++) {
+	for(auto itA = nonterminalSymbolsByDepth.rbegin(); itA != nonterminalSymbolsByDepth.rend(); ++ itA) {
 		const alphabet::Symbol& a = * itA;
 
 		/*
@@ -25,7 +25,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) {
 		regexp::simplify::RegExpOptimize::optimize(loop);
 
 		// for all transitions from A apply Arden's Lemma
-		for(auto itB = std::next(itA) ; itB != nonterminalSymbolsByDepth.rend(); itB ++) {
+		for(auto itB = std::next(itA) ; itB != nonterminalSymbolsByDepth.rend(); ++ itB) {
 			const alphabet::Symbol& b = * itB;
 			regexp::UnboundedRegExpConcatenation concat;
 			concat.appendElement(loop);
@@ -47,10 +47,10 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) {
 		 * eliminate A from rest of the equations using this pattern:
 		 * B->C = B->C + concatenate(B->A, A->C)
 		 */
-		for(auto itB = std::next(itA); itB != nonterminalSymbolsByDepth.rend(); itB ++) {
+		for(auto itB = std::next(itA); itB != nonterminalSymbolsByDepth.rend(); ++ itB) {
 			const alphabet::Symbol& b = * itB;
 
-			for(auto itC = std::next(itA); itC != nonterminalSymbolsByDepth.rend(); itC ++) {
+			for(auto itC = std::next(itA); itC != nonterminalSymbolsByDepth.rend(); ++ itC) {
 				const alphabet::Symbol& c = * itC;
 
 				regexp::UnboundedRegExpConcatenation concat;
diff --git a/alib2algo/src/regexp/glushkov/GlushkovTraversal.cpp b/alib2algo/src/regexp/glushkov/GlushkovTraversal.cpp
index a757df8d3d..ca79e7f813 100644
--- a/alib2algo/src/regexp/glushkov/GlushkovTraversal.cpp
+++ b/alib2algo/src/regexp/glushkov/GlushkovTraversal.cpp
@@ -11,6 +11,7 @@
 #include <alphabet/SymbolPairSymbol.h>
 
 #include <exception/CommonException.h>
+#include <iterator>
 
 namespace regexp {
 
@@ -132,7 +133,7 @@ std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::last ( const regex
 std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::last ( const regexp::UnboundedRegExpAlternation & node ) {
 	std::set < regexp::UnboundedRegExpSymbol > ret;
 
-	for ( auto const & element : node.getElements ( ) ) {
+	for ( const auto & element : node.getElements ( ) ) {
 		std::set < regexp::UnboundedRegExpSymbol > tmp = last ( * element );
 		ret.insert ( tmp.begin ( ), tmp.end ( ) );
 	}
@@ -143,11 +144,11 @@ std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::last ( const regex
 std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::last ( const regexp::UnboundedRegExpConcatenation & node ) {
 	std::set < regexp::UnboundedRegExpSymbol > ret;
 
-	for ( auto it = node.getElements ( ).rbegin ( ); it != node.getElements ( ).rend ( ); it++ ) {
-		std::set < regexp::UnboundedRegExpSymbol > tmp = last ( * * it );
+	for ( const auto & element : std::make_reverse ( node.getElements ( ) ) ) {
+		std::set < regexp::UnboundedRegExpSymbol > tmp = last ( * element );
 		ret.insert ( tmp.begin ( ), tmp.end ( ) );
 
-		if ( !regexp::properties::RegExpEpsilon::languageContainsEpsilon ( * * it ) )
+		if ( !regexp::properties::RegExpEpsilon::languageContainsEpsilon ( * element ) )
 			break;
 	}
 
diff --git a/alib2algo/src/regexp/transform/RegExpDerivation.cpp b/alib2algo/src/regexp/transform/RegExpDerivation.cpp
index 735b8bba8a..1c132c81bc 100644
--- a/alib2algo/src/regexp/transform/RegExpDerivation.cpp
+++ b/alib2algo/src/regexp/transform/RegExpDerivation.cpp
@@ -121,7 +121,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpConcat
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>>*) userData);
 	std::unique_ptr < regexp::UnboundedRegExpAlternation > ret ( new regexp::UnboundedRegExpAlternation() );
 
-	for(auto child = concatenation.getElements().begin(); child != concatenation.getElements().end(); child ++) {
+	for(auto child = concatenation.getElements().begin(); child != concatenation.getElements().end(); ++ child) {
 		std::unique_ptr < regexp::UnboundedRegExpConcatenation > concat ( new regexp::UnboundedRegExpConcatenation() );
 		(*child)->Accept(userData, *this);
 		concat->appendElement( std::move ( * out.second ) );
diff --git a/alib2std/src/extensions/iterator.hpp b/alib2std/src/extensions/iterator.hpp
new file mode 100644
index 0000000000..9c0e1d2592
--- /dev/null
+++ b/alib2std/src/extensions/iterator.hpp
@@ -0,0 +1,38 @@
+/*
+ * iterator.hpp
+ *
+ * Created on: Apr 1, 2013
+ * Author: Jan Travnicek
+ */
+
+#ifndef __ITERATOR_HPP_
+#define __ITERATOR_HPP_
+
+namespace std {
+
+template<class T>
+class reverser {
+	T& m_Container;
+
+public:
+	reverser(T& container) : m_Container ( container ) {
+	}
+
+	std::reverse_iterator<typename std::conditional<std::is_const<T>::value,typename T::const_iterator,typename T::iterator>::type> begin() const {
+		return m_Container.rbegin();
+	}
+
+	std::reverse_iterator<typename std::conditional<std::is_const<T>::value,typename T::const_iterator,typename T::iterator>::type> end() const {
+		return m_Container.rend();
+	}
+};
+
+template<class T>
+reverser<T> make_reverse(T& container) {
+	return reverser<T>(container);
+}
+
+} /* namespace std */
+
+#endif /* __ITERATOR_HPP_ */
+
diff --git a/alib2std/src/iterator b/alib2std/src/iterator
new file mode 100644
index 0000000000..a843ead466
--- /dev/null
+++ b/alib2std/src/iterator
@@ -0,0 +1,7 @@
+#ifndef __ITERATOR_HEADER_WRAPPER_
+#define __ITERATOR_HEADER_WRAPPER_
+
+#include <bits/../iterator>
+#include "extensions/iterator.hpp"
+
+#endif /* __ITERATOR_HEADER_WRAPPER_ */
-- 
GitLab