From c3860b989396b64f91bf8dc3e548df6ce779ea90 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Mon, 21 Nov 2016 09:57:15 +0100
Subject: [PATCH] template RegExpEpsilon algorithm

---
 .../src/regexp/properties/RegExpEpsilon.cpp   |  84 ----------
 .../src/regexp/properties/RegExpEpsilon.h     | 150 +++++++++++++++---
 2 files changed, 132 insertions(+), 102 deletions(-)

diff --git a/alib2algo/src/regexp/properties/RegExpEpsilon.cpp b/alib2algo/src/regexp/properties/RegExpEpsilon.cpp
index d94bb17c7c..87d8b489e5 100644
--- a/alib2algo/src/regexp/properties/RegExpEpsilon.cpp
+++ b/alib2algo/src/regexp/properties/RegExpEpsilon.cpp
@@ -17,94 +17,10 @@ bool RegExpEpsilon::languageContainsEpsilon(const regexp::RegExp& regexp) {
 	return dispatch(regexp.getData());
 }
 
-bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExpElement < alphabet::Symbol > & regexp) {
-	return regexp.accept<bool, RegExpEpsilon::Formal>();
-}
-
-bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExpStructure < alphabet::Symbol > & regexp) {
-	return languageContainsEpsilon(regexp.getStructure());
-}
-
-bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExp < > & regexp) {
-	return languageContainsEpsilon(regexp.getRegExp());
-}
-
 auto RegExpEpsilonFormalRegExp = RegExpEpsilon::RegistratorWrapper<bool, regexp::FormalRegExp < > >( RegExpEpsilon::languageContainsEpsilon);
 
-bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExpElement < alphabet::Symbol > & regexp) {
-	return regexp.accept<bool, RegExpEpsilon::Unbounded>();
-}
-
-bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExpStructure < alphabet::Symbol > & regexp) {
-	return languageContainsEpsilon(regexp.getStructure());
-}
-
-bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExp < > & regexp) {
-	return languageContainsEpsilon(regexp.getRegExp());
-}
-
 auto RegExpEpsilonUnboundedRegExp = RegExpEpsilon::RegistratorWrapper<bool, regexp::UnboundedRegExp < > >( RegExpEpsilon::languageContainsEpsilon);
 
-// ---------------------------------------------------------------------------
-
-bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alternation) {
-	for ( const auto & element : alternation.getElements ( ) )
-		if ( element->accept < bool, RegExpEpsilon::Unbounded > ( ) )
-			return true;
-
-	return false;
-}
-
-bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & concatenation) {
-	for ( const auto & element : concatenation.getElements ( ) )
-		if ( ! element->accept < bool, RegExpEpsilon::Unbounded > ( ) )
-			return false;
-
-	return true;
-}
-
-bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpIteration < alphabet::Symbol > &) {
-	return true;
-}
-
-bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpSymbol < alphabet::Symbol > &) {
-	return false;
-}
-
-bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > &) {
-	return true;
-}
-
-bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpEmpty < alphabet::Symbol > &) {
-	return false;
-}
-
-// ----------------------------------------------------------------------------
-
-bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpAlternation < alphabet::Symbol > & alternation) {
-	return alternation.getLeftElement().accept<bool, RegExpEpsilon::Formal>() || alternation.getRightElement().accept<bool, RegExpEpsilon::Formal>();
-}
-
-bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpConcatenation < alphabet::Symbol > & concatenation) {
-	return concatenation.getLeftElement().accept<bool, RegExpEpsilon::Formal>() && concatenation.getRightElement().accept<bool, RegExpEpsilon::Formal>();
-}
-
-bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpIteration < alphabet::Symbol > &) {
-	return true;
-}
-
-bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpSymbol < alphabet::Symbol > &) {
-	return false;
-}
-
-bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpEmpty < alphabet::Symbol > &) {
-	return false;
-}
-
-bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpEpsilon < alphabet::Symbol > &) {
-	return true;
-}
-
 } /* namespace properties */
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/properties/RegExpEpsilon.h b/alib2algo/src/regexp/properties/RegExpEpsilon.h
index 1253ec033b..8d41a193e4 100644
--- a/alib2algo/src/regexp/properties/RegExpEpsilon.h
+++ b/alib2algo/src/regexp/properties/RegExpEpsilon.h
@@ -28,35 +28,149 @@ class RegExpEpsilon : public std::SingleDispatch<RegExpEpsilon, bool, const rege
 public:
 	static bool languageContainsEpsilon(const regexp::RegExp& regexp);
 
-	static bool languageContainsEpsilon(const regexp::FormalRegExpElement < alphabet::Symbol > & regexp);
-	static bool languageContainsEpsilon(const regexp::FormalRegExpStructure < alphabet::Symbol > & regexp);
-	static bool languageContainsEpsilon(const regexp::FormalRegExp < > & regexp);
+	template < class SymbolType >
+	static bool languageContainsEpsilon(const regexp::FormalRegExpElement < SymbolType > & regexp);
+	template < class SymbolType >
+	static bool languageContainsEpsilon(const regexp::FormalRegExpStructure < SymbolType > & regexp);
+	template < class SymbolType >
+	static bool languageContainsEpsilon(const regexp::FormalRegExp < SymbolType > & regexp);
 
-	static bool languageContainsEpsilon(const regexp::UnboundedRegExpElement < alphabet::Symbol > & regexp);
-	static bool languageContainsEpsilon(const regexp::UnboundedRegExpStructure < alphabet::Symbol > & regexp);
-	static bool languageContainsEpsilon(const regexp::UnboundedRegExp < > & regexp);
+	template < class SymbolType >
+	static bool languageContainsEpsilon(const regexp::UnboundedRegExpElement < SymbolType > & regexp);
+	template < class SymbolType >
+	static bool languageContainsEpsilon(const regexp::UnboundedRegExpStructure < SymbolType > & regexp);
+	template < class SymbolType >
+	static bool languageContainsEpsilon(const regexp::UnboundedRegExp < SymbolType > & regexp);
 
+	template < class SymbolType >
 	class Unbounded {
 	public:
-		static bool visit(const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alternation);
-		static bool visit(const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & concatenation);
-		static bool visit(const regexp::UnboundedRegExpIteration < alphabet::Symbol > & iteration);
-		static bool visit(const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol);
-		static bool visit(const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & empty);
-		static bool visit(const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & epsilon);
+		static bool visit(const regexp::UnboundedRegExpAlternation < SymbolType > & alternation);
+		static bool visit(const regexp::UnboundedRegExpConcatenation < SymbolType > & concatenation);
+		static bool visit(const regexp::UnboundedRegExpIteration < SymbolType > & iteration);
+		static bool visit(const regexp::UnboundedRegExpSymbol < SymbolType > & symbol);
+		static bool visit(const regexp::UnboundedRegExpEmpty < SymbolType > & empty);
+		static bool visit(const regexp::UnboundedRegExpEpsilon < SymbolType > & epsilon);
 	};
 
+	template < class SymbolType >
 	class Formal {
 	public:
-		static bool visit(const regexp::FormalRegExpAlternation < alphabet::Symbol > & alternation);
-		static bool visit(const regexp::FormalRegExpConcatenation < alphabet::Symbol > & concatenation);
-		static bool visit(const regexp::FormalRegExpIteration < alphabet::Symbol > & iteration);
-		static bool visit(const regexp::FormalRegExpSymbol < alphabet::Symbol > & symbol);
-		static bool visit(const regexp::FormalRegExpEmpty < alphabet::Symbol > & empty);
-		static bool visit(const regexp::FormalRegExpEpsilon < alphabet::Symbol > & epsilon);
+		static bool visit(const regexp::FormalRegExpAlternation < SymbolType > & alternation);
+		static bool visit(const regexp::FormalRegExpConcatenation < SymbolType > & concatenation);
+		static bool visit(const regexp::FormalRegExpIteration < SymbolType > & iteration);
+		static bool visit(const regexp::FormalRegExpSymbol < SymbolType > & symbol);
+		static bool visit(const regexp::FormalRegExpEmpty < SymbolType > & empty);
+		static bool visit(const regexp::FormalRegExpEpsilon < SymbolType > & epsilon);
 	};
 };
 
+// ----------------------------------------------------------------------------
+
+template < class SymbolType >
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExpElement < SymbolType > & regexp) {
+	return regexp.template accept<bool, RegExpEpsilon::Formal < SymbolType >>();
+}
+
+template < class SymbolType >
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExpStructure < SymbolType > & regexp) {
+	return languageContainsEpsilon(regexp.getStructure());
+}
+
+template < class SymbolType >
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExp < SymbolType > & regexp) {
+	return languageContainsEpsilon(regexp.getRegExp());
+}
+
+// ----------------------------------------------------------------------------
+
+template < class SymbolType >
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExpElement < SymbolType > & regexp) {
+	return regexp.template accept<bool, RegExpEpsilon::Unbounded < SymbolType >>();
+}
+
+template < class SymbolType >
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExpStructure < SymbolType > & regexp) {
+	return languageContainsEpsilon(regexp.getStructure());
+}
+
+template < class SymbolType >
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExp < SymbolType > & regexp) {
+	return languageContainsEpsilon(regexp.getRegExp());
+}
+
+// ---------------------------------------------------------------------------
+
+template < class SymbolType >
+bool RegExpEpsilon::Unbounded < SymbolType >::visit(const regexp::UnboundedRegExpAlternation < SymbolType > & alternation) {
+	for ( const auto & element : alternation.getElements ( ) )
+		if ( element->template accept < bool, RegExpEpsilon::Unbounded < SymbolType > > ( ) )
+			return true;
+
+	return false;
+}
+
+template < class SymbolType >
+bool RegExpEpsilon::Unbounded < SymbolType >::visit(const regexp::UnboundedRegExpConcatenation < SymbolType > & concatenation) {
+	for ( const auto & element : concatenation.getElements ( ) )
+		if ( ! element->template accept < bool, RegExpEpsilon::Unbounded < SymbolType > > ( ) )
+			return false;
+
+	return true;
+}
+
+template < class SymbolType >
+bool RegExpEpsilon::Unbounded < SymbolType >::visit(const regexp::UnboundedRegExpIteration < SymbolType > &) {
+	return true;
+}
+
+template < class SymbolType >
+bool RegExpEpsilon::Unbounded < SymbolType >::visit(const regexp::UnboundedRegExpSymbol < SymbolType > &) {
+	return false;
+}
+
+template < class SymbolType >
+bool RegExpEpsilon::Unbounded < SymbolType >::visit(const regexp::UnboundedRegExpEpsilon < SymbolType > &) {
+	return true;
+}
+
+template < class SymbolType >
+bool RegExpEpsilon::Unbounded < SymbolType >::visit(const regexp::UnboundedRegExpEmpty < SymbolType > &) {
+	return false;
+}
+
+// ----------------------------------------------------------------------------
+
+template < class SymbolType >
+bool RegExpEpsilon::Formal < SymbolType >::visit(const regexp::FormalRegExpAlternation < SymbolType > & alternation) {
+	return alternation.getLeftElement().template accept<bool, RegExpEpsilon::Formal < SymbolType >>() || alternation.getRightElement().template accept<bool, RegExpEpsilon::Formal < SymbolType >>();
+}
+
+template < class SymbolType >
+bool RegExpEpsilon::Formal < SymbolType >::visit(const regexp::FormalRegExpConcatenation < SymbolType > & concatenation) {
+	return concatenation.getLeftElement().template accept<bool, RegExpEpsilon::Formal < SymbolType >>() && concatenation.getRightElement().template accept<bool, RegExpEpsilon::Formal < SymbolType >>();
+}
+
+template < class SymbolType >
+bool RegExpEpsilon::Formal < SymbolType >::visit(const regexp::FormalRegExpIteration < SymbolType > &) {
+	return true;
+}
+
+template < class SymbolType >
+bool RegExpEpsilon::Formal < SymbolType >::visit(const regexp::FormalRegExpSymbol < SymbolType > &) {
+	return false;
+}
+
+template < class SymbolType >
+bool RegExpEpsilon::Formal < SymbolType >::visit(const regexp::FormalRegExpEmpty < SymbolType > &) {
+	return false;
+}
+
+template < class SymbolType >
+bool RegExpEpsilon::Formal < SymbolType >::visit(const regexp::FormalRegExpEpsilon < SymbolType > &) {
+	return true;
+}
+
 } /* namespace properties */
 
 } /* namespace regexp */
-- 
GitLab