From ef5bd30ea65320424d243267c84915b9b538b8d1 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Mon, 10 Aug 2015 19:22:09 +0200
Subject: [PATCH] continue refactoring

---
 .../src/arbology/exact/ExactSubtreeMatch.cpp  | 50 ++++---------------
 .../src/arbology/exact/ExactSubtreeMatch.h    | 20 +++-----
 .../exact/ExactSubtreeMatchingAutomaton.cpp   | 44 ++--------------
 .../exact/ExactSubtreeMatchingAutomaton.h     | 19 +++----
 4 files changed, 27 insertions(+), 106 deletions(-)

diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp b/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp
index fc2fe8b0e2..08b61e361d 100644
--- a/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp
+++ b/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp
@@ -20,9 +20,7 @@ namespace arbology {
 namespace exact {
 
 std::set<unsigned> ExactSubtreeMatch::match(const tree::Tree& subject, const tree::Tree& pattern) {
-	std::set<unsigned> data;
-	Accept((void*) &data, subject.getData(), pattern.getData(), ExactSubtreeMatch::EXACT_SUBTREE_MATCH);
-	return data;
+	return getInstance().dispatch(subject.getData(), pattern.getData());
 }
 
 bool ExactSubtreeMatch::matchHelper(const tree::UnrankedNode& subject, const tree::UnrankedNode& pattern) {
@@ -36,7 +34,7 @@ bool ExactSubtreeMatch::matchHelper(const tree::UnrankedNode& subject, const tre
 
 bool ExactSubtreeMatch::matchHelper(const tree::RankedNode& subject, const tree::RankedNode& pattern) {
 	if(subject.getSymbol() != pattern.getSymbol()) return false;
-	// ranked symbols are the same test for number of children is not needed
+	// ranked symbols are the same; test for number of children is not needed
 	for(const std::tuple<const tree::RankedNode*, const tree::RankedNode*>& childs : std::make_pair_foreach(subject.getChildren(), pattern.getChildren())) {
 		if(!matchHelper(*std::get<0>(childs), *std::get<1>(childs))) return false;
 	}
@@ -66,6 +64,8 @@ std::set<unsigned> ExactSubtreeMatch::match(const tree::UnrankedTree& subject, c
 	return occ;
 }
 
+auto ExactSubtreeMatchUnrankedTreeUnrankedTree = ExactSubtreeMatch::RegistratorWrapper<std::set<unsigned>, tree::UnrankedTree, tree::UnrankedTree>(ExactSubtreeMatch::getInstance(), ExactSubtreeMatch::match);
+
 std::set<unsigned> ExactSubtreeMatch::match(const tree::RankedTree& subject, const tree::RankedTree& pattern) {
 	unsigned i = 0;
 	std::set<unsigned> occ;
@@ -73,6 +73,8 @@ std::set<unsigned> ExactSubtreeMatch::match(const tree::RankedTree& subject, con
 	return occ;
 }
 
+auto ExactSubtreeMatchRankedTreeRankedTree = ExactSubtreeMatch::RegistratorWrapper<std::set<unsigned>, tree::RankedTree, tree::RankedTree>(ExactSubtreeMatch::getInstance(), ExactSubtreeMatch::match);
+
 std::set<unsigned> ExactSubtreeMatch::match(const tree::PrefixRankedTree& subject, const tree::PrefixRankedTree& pattern) {
 	std::set<unsigned> occ;
 	for(unsigned i = 0; i <= subject.getContent().size() - pattern.getContent().size(); i++) {
@@ -87,6 +89,8 @@ std::set<unsigned> ExactSubtreeMatch::match(const tree::PrefixRankedTree& subjec
 	return occ;
 }
 
+auto ExactSubtreeMatchPrefixRankedTreePrefixRankedTree = ExactSubtreeMatch::RegistratorWrapper<std::set<unsigned>, tree::PrefixRankedTree, tree::PrefixRankedTree>(ExactSubtreeMatch::getInstance(), ExactSubtreeMatch::match);
+
 std::set<unsigned> ExactSubtreeMatch::match(const tree::PrefixRankedBarTree& subject, const tree::PrefixRankedBarTree& pattern) {
 	std::set<unsigned> occ;
 	for(unsigned i = 0; i <= subject.getContent().size() - pattern.getContent().size(); i++) {
@@ -101,43 +105,7 @@ std::set<unsigned> ExactSubtreeMatch::match(const tree::PrefixRankedBarTree& sub
 	return occ;
 }
 
-void ExactSubtreeMatch::Visit(void* data, const tree::UnrankedTree& subject, const tree::UnrankedTree& pattern) const {
-	std::set<unsigned> & res = *((std::set<unsigned>*) data);
-	res = this->match(subject, pattern);
-}
-
-void ExactSubtreeMatch::Visit(void* data, const tree::RankedTree& subject, const tree::RankedTree& pattern) const {
-	std::set<unsigned> & res = *((std::set<unsigned>*) data);
-	res = this->match(subject, pattern);
-}
-
-void ExactSubtreeMatch::Visit(void*, const tree::RankedPattern&, const tree::RankedPattern&) const {
-	throw exception::AlibException("Unsupported tree type RankedPattern");
-}
-
-void ExactSubtreeMatch::Visit(void* data, const tree::PrefixRankedTree& subject, const tree::PrefixRankedTree& pattern) const {
-	std::set<unsigned> & res = *((std::set<unsigned>*) data);
-	res = this->match(subject, pattern);
-}
-
-void ExactSubtreeMatch::Visit(void* data, const tree::PrefixRankedBarTree& subject, const tree::PrefixRankedBarTree& pattern) const {
-	std::set<unsigned> & res = *((std::set<unsigned>*) data);
-	res = this->match(subject, pattern);
-}
-
-void ExactSubtreeMatch::Visit(void*, const tree::PrefixRankedPattern&, const tree::PrefixRankedPattern&) const {
-	throw exception::AlibException("Unsupported tree type PrefixRankedPattern");
-}
-
-void ExactSubtreeMatch::Visit(void*, const tree::PrefixRankedBarPattern&, const tree::PrefixRankedBarPattern&) const {
-	throw exception::AlibException("Unsupported tree type PrefixRankedBarPattern");
-}
-
-void ExactSubtreeMatch::Visit(void*, const tree::UnrankedPattern&, const tree::UnrankedPattern&) const {
-	throw exception::AlibException("Unsupported tree type UnrankedPattern");
-}
-
-const ExactSubtreeMatch ExactSubtreeMatch::EXACT_SUBTREE_MATCH;
+auto ExactSubtreeMatchPrefixRankedBarTreePrefixRankedBarTree = ExactSubtreeMatch::RegistratorWrapper<std::set<unsigned>, tree::PrefixRankedBarTree, tree::PrefixRankedBarTree>(ExactSubtreeMatch::getInstance(), ExactSubtreeMatch::match);
 
 } /* namespace exact */
 
diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatch.h b/alib2algo/src/arbology/exact/ExactSubtreeMatch.h
index fbb22e056c..ee63da8750 100644
--- a/alib2algo/src/arbology/exact/ExactSubtreeMatch.h
+++ b/alib2algo/src/arbology/exact/ExactSubtreeMatch.h
@@ -12,15 +12,14 @@
 #include <tree/ranked/RankedNode.h>
 #include <tree/unranked/UnrankedNode.h>
 #include <set>
+#include <common/multipleDispatch.hpp>
 
 namespace arbology {
 
 namespace exact {
 
-class ExactSubtreeMatch : public tree::VisitableTreeBase::const_promoting_visitor_type {
+class ExactSubtreeMatch : public std::DoubleDispatch<std::set<unsigned>, tree::TreeBase, tree::TreeBase> {
 public:
-	ExactSubtreeMatch() {}
-
 	/**
 	 * Performs conversion.
 	 * @return left regular grammar equivalent to source automaton.
@@ -38,16 +37,11 @@ private:
 	static void matchInternal(unsigned& index, std::set<unsigned>& occ, const tree::UnrankedNode& subject, const tree::UnrankedNode& pattern);
 	static void matchInternal(unsigned& index, std::set<unsigned>& occ, const tree::RankedNode& subject, const tree::RankedNode& pattern);
 
-	void Visit(void*, const tree::UnrankedTree& subject, const tree::UnrankedTree& pattern) const;
-	void Visit(void*, const tree::RankedTree& subject, const tree::RankedTree& pattern) const;
-	void Visit(void*, const tree::RankedPattern& subject, const tree::RankedPattern& pattern) const;
-	void Visit(void*, const tree::PrefixRankedTree& subject, const tree::PrefixRankedTree& pattern) const;
-	void Visit(void*, const tree::PrefixRankedBarTree& subject, const tree::PrefixRankedBarTree& pattern) const;
-	void Visit(void*, const tree::PrefixRankedPattern& subject, const tree::PrefixRankedPattern& pattern) const;
-	void Visit(void*, const tree::PrefixRankedBarPattern& subject, const tree::PrefixRankedBarPattern& pattern) const;
-	void Visit(void*, const tree::UnrankedPattern& subject, const tree::UnrankedPattern& pattern) const;
-
-	static const ExactSubtreeMatch EXACT_SUBTREE_MATCH;
+public:
+	static ExactSubtreeMatch& getInstance() {
+		static ExactSubtreeMatch res;
+		return res;
+	}
 };
 
 } /* namespace exact */
diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp
index 71190dd719..1636071f74 100644
--- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp
+++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp
@@ -17,11 +17,7 @@ namespace arbology {
 namespace exact {
 
 automaton::Automaton ExactSubtreeMatchingAutomaton::construct(const tree::Tree& pattern) {
-	automaton::Automaton* out = NULL;
-	pattern.getData().Accept((void*) &out, ExactSubtreeMatchingAutomaton::EXACT_SUBTREE_MATCHING_AUTOMATON);
-	automaton::Automaton res = std::move(*out);
-	delete out;
-	return res;
+	return getInstance().dispatch(pattern.getData());
 }
 
 automaton::InputDrivenNPDA ExactSubtreeMatchingAutomaton::construct(const tree::PrefixRankedTree& pattern) {
@@ -45,6 +41,8 @@ automaton::InputDrivenNPDA ExactSubtreeMatchingAutomaton::construct(const tree::
 	return res;
 }
 
+auto ExactSubtreeMatchingAutomatonPrefixRankedTree = ExactSubtreeMatchingAutomaton::RegistratorWrapper<automaton::InputDrivenNPDA, tree::PrefixRankedTree>(ExactSubtreeMatchingAutomaton::getInstance(), ExactSubtreeMatchingAutomaton::construct);
+
 automaton::State constructRecursive(const tree::RankedNode & node, automaton::NFTA & res, int & nextState) {
 	std::vector<automaton::State> states;
 	states.reserve(node.getSymbol().getRank().getData());
@@ -65,41 +63,7 @@ automaton::NFTA ExactSubtreeMatchingAutomaton::construct(const tree::RankedTree
 	return res;
 }
 
-void ExactSubtreeMatchingAutomaton::Visit(void* data, const tree::RankedTree& pattern) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(this->construct(pattern));
-}
-
-void ExactSubtreeMatchingAutomaton::Visit(void* data, const tree::PrefixRankedTree& pattern) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(this->construct(pattern));
-}
-
-void ExactSubtreeMatchingAutomaton::Visit(void*, const tree::PrefixRankedBarTree&) const {
-	throw exception::AlibException("Unsupported tree type PrefixRankedBarTree");
-}
-
-void ExactSubtreeMatchingAutomaton::Visit(void*, const tree::RankedPattern&) const {
-	throw exception::AlibException("Unsupported tree type RankedPattern");
-}
-
-void ExactSubtreeMatchingAutomaton::Visit(void*, const tree::PrefixRankedPattern&) const {
-	throw exception::AlibException("Unsupported tree type PrefixRankedPattern");
-}
-
-void ExactSubtreeMatchingAutomaton::Visit(void*, const tree::PrefixRankedBarPattern&) const {
-	throw exception::AlibException("Unsupported tree type PrefixRankedBarPattern");
-}
-
-void ExactSubtreeMatchingAutomaton::Visit(void*, const tree::UnrankedTree&) const {
-	throw exception::AlibException("Unsupported tree type UnrankedTree");
-}
-
-void ExactSubtreeMatchingAutomaton::Visit(void*, const tree::UnrankedPattern&) const {
-	throw exception::AlibException("Unsupported tree type UnrankedPattern");
-}
-
-const ExactSubtreeMatchingAutomaton ExactSubtreeMatchingAutomaton::EXACT_SUBTREE_MATCHING_AUTOMATON;
+auto ExactSubtreeMatchingAutomatonRankedTree = ExactSubtreeMatchingAutomaton::RegistratorWrapper<automaton::NFTA, tree::RankedTree>(ExactSubtreeMatchingAutomaton::getInstance(), ExactSubtreeMatchingAutomaton::construct);
 
 } /* namespace exact */
 
diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h
index dbe3b1471e..436eb92390 100644
--- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h
+++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h
@@ -12,12 +12,13 @@
 #include <automaton/PDA/InputDrivenNPDA.h>
 #include <automaton/TA/NFTA.h>
 #include <tree/Tree.h>
+#include <common/multipleDispatch.hpp>
 
 namespace arbology {
 
 namespace exact {
 
-class ExactSubtreeMatchingAutomaton : public tree::VisitableTreeBase::const_visitor_type {
+class ExactSubtreeMatchingAutomaton : public std::SingleDispatch<automaton::Automaton, tree::TreeBase> {
 public:
 	ExactSubtreeMatchingAutomaton() {}
 
@@ -29,17 +30,11 @@ public:
 
 	static automaton::InputDrivenNPDA construct(const tree::PrefixRankedTree& pattern);
 	static automaton::NFTA construct(const tree::RankedTree& pattern);
-private:
-	void Visit(void*, const tree::RankedTree& pattern) const;
-	void Visit(void*, const tree::RankedPattern& subject) const;
-	void Visit(void*, const tree::PrefixRankedTree& pattern) const;
-	void Visit(void*, const tree::PrefixRankedBarTree& pattern) const;
-	void Visit(void*, const tree::PrefixRankedPattern& pattern) const;
-	void Visit(void*, const tree::PrefixRankedBarPattern& pattern) const;
-	void Visit(void*, const tree::UnrankedTree& pattern) const;
-	void Visit(void*, const tree::UnrankedPattern& subject) const;
-
-	static const ExactSubtreeMatchingAutomaton EXACT_SUBTREE_MATCHING_AUTOMATON;
+
+	static ExactSubtreeMatchingAutomaton& getInstance() {
+		static ExactSubtreeMatchingAutomaton res;
+		return res;
+	}
 };
 
 } /* namespace exact */
-- 
GitLab