From 5df5e174f22b6a7c34f663fa8ba6e434a6e58578 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sun, 18 Dec 2016 20:43:36 +0100
Subject: [PATCH] template automaton reverse algorithm

---
 alib2algo/src/automaton/transform/Reverse.cpp | 51 ----------------
 alib2algo/src/automaton/transform/Reverse.h   | 61 ++++++++++++++++++-
 2 files changed, 58 insertions(+), 54 deletions(-)

diff --git a/alib2algo/src/automaton/transform/Reverse.cpp b/alib2algo/src/automaton/transform/Reverse.cpp
index 289b453377..ed567ffa4b 100644
--- a/alib2algo/src/automaton/transform/Reverse.cpp
+++ b/alib2algo/src/automaton/transform/Reverse.cpp
@@ -7,11 +7,6 @@
 
 #include "Reverse.h"
 
-#include <automaton/FSM/MultiInitialStateNFA.h>
-
-#include <vector>
-#include <algorithm>
-
 namespace automaton {
 
 namespace transform {
@@ -20,54 +15,8 @@ automaton::Automaton Reverse::convert(const Automaton& automaton) {
 	return dispatch(automaton.getData());
 }
 
-automaton::MultiInitialStateNFA < > Reverse::convert(const automaton::DFA<>& automaton) {
-	automaton::MultiInitialStateNFA < > res;
-
-	res.setStates(automaton.getStates());
-	res.addFinalState(automaton.getInitialState());
-	res.setInitialStates( automaton.getFinalStates() );
-	res.setInputAlphabet(automaton.getInputAlphabet());
-
-	for(const auto& t : automaton.getTransitions())
-		res.addTransition(t.second, t.first.second, t.first.first);
-
-	return res;
-}
-
 auto ReverseDFA = Reverse::RegistratorWrapper<automaton::MultiInitialStateNFA < > , automaton::DFA<>>(Reverse::convert);
-
-automaton::MultiInitialStateNFA < > Reverse::convert(const automaton::NFA < > & automaton) {
-	automaton::MultiInitialStateNFA < > res;
-
-	res.setStates(automaton.getStates());
-	res.addFinalState(automaton.getInitialState());
-	res.setInitialStates( automaton.getFinalStates() );
-	res.setInputAlphabet(automaton.getInputAlphabet());
-
-	for(const auto& t : automaton.getTransitions())
-		for(const auto& q : t.second)
-			res.addTransition(q, t.first.second, t.first.first);
-
-	return res;
-}
-
 auto ReverseNFA = Reverse::RegistratorWrapper<automaton::MultiInitialStateNFA < > , automaton::NFA < > >(Reverse::convert);
-
-automaton::MultiInitialStateNFA < > Reverse::convert(const automaton::MultiInitialStateNFA < > & automaton) {
-	automaton::MultiInitialStateNFA < > res;
-
-	res.setStates(automaton.getStates());
-	res.setFinalStates(automaton.getInitialStates());
-	res.setInitialStates( automaton.getFinalStates() );
-	res.setInputAlphabet(automaton.getInputAlphabet());
-
-	for(const auto& t : automaton.getTransitions())
-		for(const auto& q : t.second)
-			res.addTransition(q, t.first.second, t.first.first);
-
-	return res;
-}
-
 auto ReverseMultiInitialStateNFA = Reverse::RegistratorWrapper<automaton::MultiInitialStateNFA < > , automaton::MultiInitialStateNFA < > >(Reverse::convert);
 
 } /* namespace transform */
diff --git a/alib2algo/src/automaton/transform/Reverse.h b/alib2algo/src/automaton/transform/Reverse.h
index f0e412e7ac..de97ad6d7a 100644
--- a/alib2algo/src/automaton/transform/Reverse.h
+++ b/alib2algo/src/automaton/transform/Reverse.h
@@ -8,9 +8,14 @@
 #ifndef REVERSE_H_
 #define REVERSE_H_
 
+#include <vector>
+#include <algorithm>
+
 #include <core/multipleDispatch.hpp>
+
 #include <automaton/Automaton.h>
 #include <automaton/AutomatonFeatures.h>
+#include <automaton/FSM/MultiInitialStateNFA.h>
 
 namespace automaton {
 
@@ -18,9 +23,12 @@ namespace transform {
 
 class Reverse : public std::SingleDispatch<Reverse, automaton::Automaton, const automaton::AutomatonBase &> {
 public:
-	static automaton::MultiInitialStateNFA < > convert(const automaton::DFA<>& automaton);
-	static automaton::MultiInitialStateNFA < > convert(const automaton::NFA < > & automaton);
-	static automaton::MultiInitialStateNFA < > convert(const automaton::MultiInitialStateNFA < > & automaton);
+	template < class SymbolType, class StateType >
+	static automaton::MultiInitialStateNFA < SymbolType, StateType > convert(const automaton::DFA < SymbolType, StateType > & automaton);
+	template < class SymbolType, class StateType >
+	static automaton::MultiInitialStateNFA < SymbolType, StateType > convert(const automaton::NFA < SymbolType, StateType > & automaton);
+	template < class SymbolType, class StateType >
+	static automaton::MultiInitialStateNFA < SymbolType, StateType > convert(const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton);
 
 	/**
 	 * Creates finite automaton accepting reverse language of given automaton
@@ -30,6 +38,53 @@ public:
 	static automaton::Automaton convert( const automaton::Automaton & automaton );
 };
 
+template < class SymbolType, class StateType >
+automaton::MultiInitialStateNFA < SymbolType, StateType > Reverse::convert(const automaton::DFA < SymbolType, StateType > & automaton) {
+	automaton::MultiInitialStateNFA < SymbolType, StateType > res;
+
+	res.setStates(automaton.getStates());
+	res.addFinalState(automaton.getInitialState());
+	res.setInitialStates( automaton.getFinalStates() );
+	res.setInputAlphabet(automaton.getInputAlphabet());
+
+	for(const auto& t : automaton.getTransitions())
+		res.addTransition(t.second, t.first.second, t.first.first);
+
+	return res;
+}
+
+template < class SymbolType, class StateType >
+automaton::MultiInitialStateNFA < SymbolType, StateType > Reverse::convert(const automaton::NFA < SymbolType, StateType > & automaton) {
+	automaton::MultiInitialStateNFA < SymbolType, StateType > res;
+
+	res.setStates(automaton.getStates());
+	res.addFinalState(automaton.getInitialState());
+	res.setInitialStates( automaton.getFinalStates() );
+	res.setInputAlphabet(automaton.getInputAlphabet());
+
+	for(const auto& t : automaton.getTransitions())
+		for(const auto& q : t.second)
+			res.addTransition(q, t.first.second, t.first.first);
+
+	return res;
+}
+
+template < class SymbolType, class StateType >
+automaton::MultiInitialStateNFA < SymbolType, StateType > Reverse::convert(const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton) {
+	automaton::MultiInitialStateNFA < SymbolType, StateType > res;
+
+	res.setStates(automaton.getStates());
+	res.setFinalStates(automaton.getInitialStates());
+	res.setInitialStates( automaton.getFinalStates() );
+	res.setInputAlphabet(automaton.getInputAlphabet());
+
+	for(const auto& t : automaton.getTransitions())
+		for(const auto& q : t.second)
+			res.addTransition(q, t.first.second, t.first.first);
+
+	return res;
+}
+
 } /* namespace transform */
 
 } /* namespace automaton */
-- 
GitLab