From f41829107a758c6e4a7c49ef5bdae74d8ff9dde4 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Thu, 16 Oct 2014 17:44:06 +0200
Subject: [PATCH] typeId reimplementation

---
 alib2data/src/alphabet/BlankSymbol.h          |  2 +-
 .../src/alphabet/BottomOfTheStackSymbol.h     |  2 +-
 alib2data/src/alphabet/EndSymbol.h            |  2 +-
 alib2data/src/alphabet/LabeledSymbol.h        |  2 +-
 alib2data/src/alphabet/Symbol.cpp             |  5 +-
 alib2data/src/automaton/FSM/CompactNFA.h      |  2 +-
 alib2data/src/automaton/FSM/DFA.h             |  2 +-
 alib2data/src/automaton/FSM/EpsilonNFA.h      |  2 +-
 alib2data/src/automaton/FSM/ExtendedNFA.h     |  2 +-
 .../src/automaton/FSM/MultiInitialStateNFA.h  |  2 +-
 alib2data/src/automaton/FSM/NFA.h             |  2 +-
 alib2data/src/automaton/PDA/DPDA.h            |  2 +-
 alib2data/src/automaton/PDA/InputDrivenNPDA.h |  2 +-
 alib2data/src/automaton/PDA/NPDA.h            |  2 +-
 .../PDA/RealTimeHeightDeterministicDPDA.h     |  2 +-
 .../PDA/RealTimeHeightDeterministicNPDA.h     |  2 +-
 alib2data/src/automaton/PDA/SinglePopDPDA.h   |  2 +-
 alib2data/src/automaton/PDA/SinglePopNPDA.h   |  2 +-
 .../src/automaton/PDA/VisiblyPushdownDPDA.h   |  2 +-
 .../src/automaton/PDA/VisiblyPushdownNPDA.h   |  2 +-
 alib2data/src/automaton/TM/OneTapeDTM.h       |  2 +-
 alib2data/src/common/base.hpp                 | 20 +++---
 alib2data/src/container/ObjectsMap.h          |  2 +-
 alib2data/src/container/ObjectsPair.h         |  2 +-
 alib2data/src/container/ObjectsSet.h          |  2 +-
 alib2data/src/container/ObjectsVector.h       |  2 +-
 alib2data/src/exception/AlibException.h       |  2 +-
 alib2data/src/grammar/ContextFree/CFG.h       |  2 +-
 alib2data/src/grammar/ContextFree/CNF.h       |  2 +-
 .../src/grammar/ContextFree/EpsilonFreeCFG.h  |  2 +-
 alib2data/src/grammar/ContextFree/GNF.h       |  2 +-
 alib2data/src/grammar/ContextFree/LG.h        |  2 +-
 alib2data/src/grammar/ContextSensitive/CSG.h  |  2 +-
 .../ContextSensitive/NonContractingGrammar.h  |  2 +-
 alib2data/src/grammar/Regular/LeftLG.h        |  2 +-
 alib2data/src/grammar/Regular/LeftRG.h        |  2 +-
 alib2data/src/grammar/Regular/RightLG.h       |  2 +-
 alib2data/src/grammar/Regular/RightRG.h       |  2 +-
 .../ContextPreservingUnrestrictedGrammar.h    |  2 +-
 .../Unrestricted/UnrestrictedGrammar.h        |  2 +-
 alib2data/src/label/HexavigesimalLabel.h      |  2 +-
 alib2data/src/label/LabelPairLabel.h          |  2 +-
 alib2data/src/label/LabelSetLabel.h           |  2 +-
 alib2data/src/label/ObjectLabel.h             |  2 +-
 alib2data/src/label/PrimitiveLabel.h          |  2 +-
 alib2data/src/object/Void.h                   |  2 +-
 alib2data/src/primitive/Character.h           |  2 +-
 alib2data/src/primitive/Integer.h             |  2 +-
 alib2data/src/primitive/String.h              |  2 +-
 alib2data/src/regexp/formal/FormalRegExp.h    |  2 +-
 .../regexp/formal/FormalRegExpAlternation.cpp |  7 ++
 .../regexp/formal/FormalRegExpAlternation.h   |  5 ++
 .../formal/FormalRegExpConcatenation.cpp      |  6 ++
 .../regexp/formal/FormalRegExpConcatenation.h |  7 ++
 .../src/regexp/formal/FormalRegExpElement.cpp | 71 -------------------
 .../src/regexp/formal/FormalRegExpElement.h   | 56 +++------------
 .../src/regexp/formal/FormalRegExpEmpty.cpp   |  6 ++
 .../src/regexp/formal/FormalRegExpEmpty.h     |  7 ++
 .../src/regexp/formal/FormalRegExpEpsilon.cpp |  7 ++
 .../src/regexp/formal/FormalRegExpEpsilon.h   |  7 ++
 .../regexp/formal/FormalRegExpIteration.cpp   |  7 ++
 .../src/regexp/formal/FormalRegExpIteration.h |  6 ++
 .../src/regexp/formal/FormalRegExpSymbol.cpp  |  7 ++
 .../src/regexp/formal/FormalRegExpSymbol.h    |  6 ++
 .../src/regexp/unbounded/UnboundedRegExp.h    |  2 +-
 .../unbounded/UnboundedRegExpAlternation.cpp  |  7 ++
 .../unbounded/UnboundedRegExpAlternation.h    |  6 ++
 .../UnboundedRegExpConcatenation.cpp          |  7 ++
 .../unbounded/UnboundedRegExpConcatenation.h  |  6 ++
 .../unbounded/UnboundedRegExpElement.cpp      | 71 -------------------
 .../regexp/unbounded/UnboundedRegExpElement.h | 56 +++------------
 .../regexp/unbounded/UnboundedRegExpEmpty.cpp |  7 ++
 .../regexp/unbounded/UnboundedRegExpEmpty.h   |  7 +-
 .../unbounded/UnboundedRegExpEpsilon.cpp      |  7 ++
 .../regexp/unbounded/UnboundedRegExpEpsilon.h |  5 ++
 .../unbounded/UnboundedRegExpIteration.cpp    |  7 ++
 .../unbounded/UnboundedRegExpIteration.h      |  6 ++
 .../unbounded/UnboundedRegExpSymbol.cpp       |  7 ++
 .../regexp/unbounded/UnboundedRegExpSymbol.h  |  6 ++
 alib2data/src/std/visitor.hpp                 |  3 +
 alib2data/src/string/CyclicString.h           |  2 +-
 alib2data/src/string/Epsilon.h                |  2 +-
 alib2data/src/string/LinearString.h           |  2 +-
 alib2data/test-src/std/StdVisitorTest.cpp     |  6 +-
 84 files changed, 244 insertions(+), 304 deletions(-)

diff --git a/alib2data/src/alphabet/BlankSymbol.h b/alib2data/src/alphabet/BlankSymbol.h
index f67dc359e6..422432b38f 100644
--- a/alib2data/src/alphabet/BlankSymbol.h
+++ b/alib2data/src/alphabet/BlankSymbol.h
@@ -38,7 +38,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<BlankSymbol>();
 	}
 
 	static BlankSymbol BLANK;
diff --git a/alib2data/src/alphabet/BottomOfTheStackSymbol.h b/alib2data/src/alphabet/BottomOfTheStackSymbol.h
index f18851e480..91c73bef28 100644
--- a/alib2data/src/alphabet/BottomOfTheStackSymbol.h
+++ b/alib2data/src/alphabet/BottomOfTheStackSymbol.h
@@ -38,7 +38,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<BottomOfTheStackSymbol>();
 	}
 
 	static BottomOfTheStackSymbol BOTTOM_OF_THE_STACK;
diff --git a/alib2data/src/alphabet/EndSymbol.h b/alib2data/src/alphabet/EndSymbol.h
index 8a69354bd6..dd1f88c29c 100644
--- a/alib2data/src/alphabet/EndSymbol.h
+++ b/alib2data/src/alphabet/EndSymbol.h
@@ -38,7 +38,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<EndSymbol>();
 	}
 
 	static EndSymbol END;
diff --git a/alib2data/src/alphabet/LabeledSymbol.h b/alib2data/src/alphabet/LabeledSymbol.h
index 19463b1a3d..720834b9bd 100644
--- a/alib2data/src/alphabet/LabeledSymbol.h
+++ b/alib2data/src/alphabet/LabeledSymbol.h
@@ -53,7 +53,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<LabeledSymbol>();
 	}
 };
 
diff --git a/alib2data/src/alphabet/Symbol.cpp b/alib2data/src/alphabet/Symbol.cpp
index 258e0fbeea..5ef6949175 100644
--- a/alib2data/src/alphabet/Symbol.cpp
+++ b/alib2data/src/alphabet/Symbol.cpp
@@ -16,11 +16,10 @@ namespace alphabet {
 alphabet::Symbol createUniqueSymbol(const alphabet::Symbol& base, const std::set<alphabet::Symbol>& terminalAlphabet, const std::set<alphabet::Symbol>& nonterminalAlphabet) {
 	label::NextLabel nextLabelCreator;
 
-	const alphabet::LabeledSymbol* baseSymbol = dynamic_cast<const alphabet::LabeledSymbol*>(&(base.getData()));
-	if(baseSymbol == NULL)
+	if(alib::ObjectBase::typeId<LabeledSymbol>() != base.getData().selfTypeId())
 		throw exception::AlibException("Could not create unique symbol with nonlabeled base symbol " + (std::string) base + "." );
 
-	label::Label nextLabel = baseSymbol->getLabel();
+	label::Label nextLabel = static_cast<const alphabet::LabeledSymbol&>(base.getData()).getLabel();
 
 	int i = 0;
 	do {
diff --git a/alib2data/src/automaton/FSM/CompactNFA.h b/alib2data/src/automaton/FSM/CompactNFA.h
index 5a8a23a227..9993c60998 100644
--- a/alib2data/src/automaton/FSM/CompactNFA.h
+++ b/alib2data/src/automaton/FSM/CompactNFA.h
@@ -91,7 +91,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<CompactNFA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/FSM/DFA.h b/alib2data/src/automaton/FSM/DFA.h
index 6aae39ba68..cd5344e6f3 100644
--- a/alib2data/src/automaton/FSM/DFA.h
+++ b/alib2data/src/automaton/FSM/DFA.h
@@ -92,7 +92,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<DFA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/FSM/EpsilonNFA.h b/alib2data/src/automaton/FSM/EpsilonNFA.h
index 348dead1da..317e3cb8b4 100644
--- a/alib2data/src/automaton/FSM/EpsilonNFA.h
+++ b/alib2data/src/automaton/FSM/EpsilonNFA.h
@@ -170,7 +170,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<EpsilonNFA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.h b/alib2data/src/automaton/FSM/ExtendedNFA.h
index 6703e34da1..d13f02c02f 100644
--- a/alib2data/src/automaton/FSM/ExtendedNFA.h
+++ b/alib2data/src/automaton/FSM/ExtendedNFA.h
@@ -93,7 +93,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<ExtendedNFA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h
index e104ce8a51..d026d17e22 100644
--- a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h
+++ b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h
@@ -109,7 +109,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<MultiInitialStateNFA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/FSM/NFA.h b/alib2data/src/automaton/FSM/NFA.h
index 880ac3d3fd..0221b9d36a 100644
--- a/alib2data/src/automaton/FSM/NFA.h
+++ b/alib2data/src/automaton/FSM/NFA.h
@@ -107,7 +107,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<NFA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/PDA/DPDA.h b/alib2data/src/automaton/PDA/DPDA.h
index 0605585360..195f2d44ed 100644
--- a/alib2data/src/automaton/PDA/DPDA.h
+++ b/alib2data/src/automaton/PDA/DPDA.h
@@ -94,7 +94,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<DPDA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/PDA/InputDrivenNPDA.h b/alib2data/src/automaton/PDA/InputDrivenNPDA.h
index ce9ad393b9..40e4c13b11 100644
--- a/alib2data/src/automaton/PDA/InputDrivenNPDA.h
+++ b/alib2data/src/automaton/PDA/InputDrivenNPDA.h
@@ -100,7 +100,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<InputDrivenNPDA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/PDA/NPDA.h b/alib2data/src/automaton/PDA/NPDA.h
index a5efe560ee..cf066b4f4b 100644
--- a/alib2data/src/automaton/PDA/NPDA.h
+++ b/alib2data/src/automaton/PDA/NPDA.h
@@ -88,7 +88,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<NPDA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.h b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.h
index d6eda02718..505fec37f0 100644
--- a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.h
+++ b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.h
@@ -130,7 +130,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<RealTimeHeightDeterministicDPDA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h
index 4db20c948d..335111cd88 100644
--- a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h
+++ b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h
@@ -130,7 +130,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<RealTimeHeightDeterministicNPDA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/PDA/SinglePopDPDA.h b/alib2data/src/automaton/PDA/SinglePopDPDA.h
index 48ec8b9e89..7bb5678904 100644
--- a/alib2data/src/automaton/PDA/SinglePopDPDA.h
+++ b/alib2data/src/automaton/PDA/SinglePopDPDA.h
@@ -93,7 +93,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<SinglePopDPDA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/PDA/SinglePopNPDA.h b/alib2data/src/automaton/PDA/SinglePopNPDA.h
index faf23c975e..158f829819 100644
--- a/alib2data/src/automaton/PDA/SinglePopNPDA.h
+++ b/alib2data/src/automaton/PDA/SinglePopNPDA.h
@@ -87,7 +87,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<SinglePopNPDA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/PDA/VisiblyPushdownDPDA.h b/alib2data/src/automaton/PDA/VisiblyPushdownDPDA.h
index b4d21594df..a4560a4c6a 100644
--- a/alib2data/src/automaton/PDA/VisiblyPushdownDPDA.h
+++ b/alib2data/src/automaton/PDA/VisiblyPushdownDPDA.h
@@ -116,7 +116,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<VisiblyPushdownDPDA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h
index f63db90f38..cb4d663312 100644
--- a/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h
+++ b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h
@@ -116,7 +116,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<VisiblyPushdownNPDA>();
 	}
 };
 
diff --git a/alib2data/src/automaton/TM/OneTapeDTM.h b/alib2data/src/automaton/TM/OneTapeDTM.h
index 5cd77dbbcc..40a366862a 100644
--- a/alib2data/src/automaton/TM/OneTapeDTM.h
+++ b/alib2data/src/automaton/TM/OneTapeDTM.h
@@ -86,7 +86,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<OneTapeDTM>();
 	}
 };
 
diff --git a/alib2data/src/common/base.hpp b/alib2data/src/common/base.hpp
index 044fa857f2..54c1a5df1b 100644
--- a/alib2data/src/common/base.hpp
+++ b/alib2data/src/common/base.hpp
@@ -16,10 +16,10 @@ namespace alib {
 template<int ID>
 class base_base {
 public:
-	template<typename T>
-	int typeId(const T&) const {
+/*	template<typename T>
+	static int typeId() {
 		return ID;
-	}
+	}*/
 
 	virtual int selfTypeId() const = 0;
 
@@ -34,7 +34,8 @@ class base_helper;
 template<int ID, typename T>
 class base_helper<ID, T> : public base_base<ID + 1> {
 public:
-	virtual int typeId(const T &) const {
+	template<typename R, typename std::enable_if < std::is_same< R, T >::value >::type* = nullptr >
+	static int typeId() {
 		return ID;
 	}
 
@@ -42,8 +43,8 @@ public:
 		return false;
 	}
 
-	virtual bool operator<(const T & other) const {
-		return this->selfTypeId() < typeId(other);
+	virtual bool operator<(const T &) const {
+		return this->selfTypeId() < typeId<T>();
 	}
 };
 
@@ -54,7 +55,8 @@ public:
 	using base_helper<ID + 1, Types...>::operator<;
 	using base_helper<ID + 1, Types...>::typeId;
 
-	virtual int typeId(const T &) const {
+	template<typename R, typename std::enable_if < std::is_same< R, T >::value >::type* = nullptr >
+	static int typeId() {
 		return ID;
 	}
 
@@ -62,8 +64,8 @@ public:
 		return false;
 	}
 
-	virtual bool operator<(const T & other) const {
-		return this->selfTypeId() < typeId(other);
+	virtual bool operator<(const T &) const {
+		return this->selfTypeId() < typeId<T>();
 	}
 };
 
diff --git a/alib2data/src/container/ObjectsMap.h b/alib2data/src/container/ObjectsMap.h
index 71503f3a2f..a2b989e869 100644
--- a/alib2data/src/container/ObjectsMap.h
+++ b/alib2data/src/container/ObjectsMap.h
@@ -38,7 +38,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<ObjectsMap>();
 	}
 };
 
diff --git a/alib2data/src/container/ObjectsPair.h b/alib2data/src/container/ObjectsPair.h
index fe8691ab17..270dcdea62 100644
--- a/alib2data/src/container/ObjectsPair.h
+++ b/alib2data/src/container/ObjectsPair.h
@@ -40,7 +40,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<ObjectsPair>();
 	}
 };
 
diff --git a/alib2data/src/container/ObjectsSet.h b/alib2data/src/container/ObjectsSet.h
index 7aadcb917a..0a5fec7f9f 100644
--- a/alib2data/src/container/ObjectsSet.h
+++ b/alib2data/src/container/ObjectsSet.h
@@ -38,7 +38,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<ObjectsSet>();
 	}
 };
 
diff --git a/alib2data/src/container/ObjectsVector.h b/alib2data/src/container/ObjectsVector.h
index 4396d458e6..03e89ebad7 100644
--- a/alib2data/src/container/ObjectsVector.h
+++ b/alib2data/src/container/ObjectsVector.h
@@ -38,7 +38,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<ObjectsVector>();
 	}
 };
 
diff --git a/alib2data/src/exception/AlibException.h b/alib2data/src/exception/AlibException.h
index 4b90853c48..bcdb502fd8 100644
--- a/alib2data/src/exception/AlibException.h
+++ b/alib2data/src/exception/AlibException.h
@@ -63,7 +63,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<AlibException>();
 	}
 };
 
diff --git a/alib2data/src/grammar/ContextFree/CFG.h b/alib2data/src/grammar/ContextFree/CFG.h
index 9e014389de..bb36acd063 100644
--- a/alib2data/src/grammar/ContextFree/CFG.h
+++ b/alib2data/src/grammar/ContextFree/CFG.h
@@ -60,7 +60,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<CFG>();
 	}
 };
 
diff --git a/alib2data/src/grammar/ContextFree/CNF.h b/alib2data/src/grammar/ContextFree/CNF.h
index 833b85e80c..af5c56a409 100644
--- a/alib2data/src/grammar/ContextFree/CNF.h
+++ b/alib2data/src/grammar/ContextFree/CNF.h
@@ -69,7 +69,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<CNF>();
 	}
 };
 
diff --git a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h
index e2751e1e8d..629b8cfaf3 100644
--- a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h
+++ b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h
@@ -64,7 +64,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<EpsilonFreeCFG>();
 	}
 };
 
diff --git a/alib2data/src/grammar/ContextFree/GNF.h b/alib2data/src/grammar/ContextFree/GNF.h
index 43134473fc..2a9caa5336 100644
--- a/alib2data/src/grammar/ContextFree/GNF.h
+++ b/alib2data/src/grammar/ContextFree/GNF.h
@@ -63,7 +63,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<GNF>();
 	}
 };
 
diff --git a/alib2data/src/grammar/ContextFree/LG.h b/alib2data/src/grammar/ContextFree/LG.h
index 56b5d34442..7c56b5e9dc 100644
--- a/alib2data/src/grammar/ContextFree/LG.h
+++ b/alib2data/src/grammar/ContextFree/LG.h
@@ -65,7 +65,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<LG>();
 	}
 };
 
diff --git a/alib2data/src/grammar/ContextSensitive/CSG.h b/alib2data/src/grammar/ContextSensitive/CSG.h
index 760a9319eb..f75ac10870 100644
--- a/alib2data/src/grammar/ContextSensitive/CSG.h
+++ b/alib2data/src/grammar/ContextSensitive/CSG.h
@@ -57,7 +57,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<CSG>();
 	}
 };
 
diff --git a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h
index 4b69b41aba..fc5cf10cd0 100644
--- a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h
+++ b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h
@@ -57,7 +57,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<NonContractingGrammar>();
 	}
 };
 
diff --git a/alib2data/src/grammar/Regular/LeftLG.h b/alib2data/src/grammar/Regular/LeftLG.h
index a972d9aa55..068b835035 100644
--- a/alib2data/src/grammar/Regular/LeftLG.h
+++ b/alib2data/src/grammar/Regular/LeftLG.h
@@ -64,7 +64,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<LeftLG>();
 	}
 };
 
diff --git a/alib2data/src/grammar/Regular/LeftRG.h b/alib2data/src/grammar/Regular/LeftRG.h
index aee1e8c96f..6800315605 100644
--- a/alib2data/src/grammar/Regular/LeftRG.h
+++ b/alib2data/src/grammar/Regular/LeftRG.h
@@ -163,7 +163,7 @@ public:
 	 * @copydoc alib::base_base::selfTypeId
 	 */
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<LeftRG>();
 	}
 };
 
diff --git a/alib2data/src/grammar/Regular/RightLG.h b/alib2data/src/grammar/Regular/RightLG.h
index b31d5476cc..fc0d2cf7d3 100644
--- a/alib2data/src/grammar/Regular/RightLG.h
+++ b/alib2data/src/grammar/Regular/RightLG.h
@@ -64,7 +64,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<RightLG>();
 	}
 };
 
diff --git a/alib2data/src/grammar/Regular/RightRG.h b/alib2data/src/grammar/Regular/RightRG.h
index eb173e4cb9..b21e848b73 100644
--- a/alib2data/src/grammar/Regular/RightRG.h
+++ b/alib2data/src/grammar/Regular/RightRG.h
@@ -84,7 +84,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<RightRG>();
 	}
 };
 
diff --git a/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.h b/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.h
index c5c425f843..bb23181be0 100644
--- a/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.h
+++ b/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.h
@@ -53,7 +53,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<ContextPreservingUnrestrictedGrammar>();
 	}
 };
 
diff --git a/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.h b/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.h
index 9639bd92b5..46ec38d06f 100644
--- a/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.h
+++ b/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.h
@@ -53,7 +53,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<UnrestrictedGrammar>();
 	}
 };
 
diff --git a/alib2data/src/label/HexavigesimalLabel.h b/alib2data/src/label/HexavigesimalLabel.h
index 206cce8c39..ce844d5ab8 100644
--- a/alib2data/src/label/HexavigesimalLabel.h
+++ b/alib2data/src/label/HexavigesimalLabel.h
@@ -52,7 +52,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<HexavigesimalLabel>();
 	}
 };
 
diff --git a/alib2data/src/label/LabelPairLabel.h b/alib2data/src/label/LabelPairLabel.h
index 1bfa1c5a27..9241485690 100644
--- a/alib2data/src/label/LabelPairLabel.h
+++ b/alib2data/src/label/LabelPairLabel.h
@@ -56,7 +56,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<LabelPairLabel>();
 	}
 };
 
diff --git a/alib2data/src/label/LabelSetLabel.h b/alib2data/src/label/LabelSetLabel.h
index 5d1bd413c9..9bdf8266c3 100644
--- a/alib2data/src/label/LabelSetLabel.h
+++ b/alib2data/src/label/LabelSetLabel.h
@@ -56,7 +56,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<LabelSetLabel>();
 	}
 };
 
diff --git a/alib2data/src/label/ObjectLabel.h b/alib2data/src/label/ObjectLabel.h
index e5bdc9ae0e..a4bc6ff70f 100644
--- a/alib2data/src/label/ObjectLabel.h
+++ b/alib2data/src/label/ObjectLabel.h
@@ -55,7 +55,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<ObjectLabel>();
 	}
 };
 
diff --git a/alib2data/src/label/PrimitiveLabel.h b/alib2data/src/label/PrimitiveLabel.h
index 9449841224..784f9fb44e 100644
--- a/alib2data/src/label/PrimitiveLabel.h
+++ b/alib2data/src/label/PrimitiveLabel.h
@@ -54,7 +54,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<PrimitiveLabel>();
 	}
 };
 
diff --git a/alib2data/src/object/Void.h b/alib2data/src/object/Void.h
index bfbea1238f..fa35b2295d 100644
--- a/alib2data/src/object/Void.h
+++ b/alib2data/src/object/Void.h
@@ -40,7 +40,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<Void>();
 	}
 
 	static Void VOID;
diff --git a/alib2data/src/primitive/Character.h b/alib2data/src/primitive/Character.h
index bfeae825b6..ad358b7bba 100644
--- a/alib2data/src/primitive/Character.h
+++ b/alib2data/src/primitive/Character.h
@@ -53,7 +53,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<Character>();
 	}
 };
 
diff --git a/alib2data/src/primitive/Integer.h b/alib2data/src/primitive/Integer.h
index 0020f69424..e70ca141c7 100644
--- a/alib2data/src/primitive/Integer.h
+++ b/alib2data/src/primitive/Integer.h
@@ -52,7 +52,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<Integer>();
 	}
 };
 
diff --git a/alib2data/src/primitive/String.h b/alib2data/src/primitive/String.h
index 297df0369c..5007dfd8fd 100644
--- a/alib2data/src/primitive/String.h
+++ b/alib2data/src/primitive/String.h
@@ -55,7 +55,7 @@ public:
 	virtual operator std::string () const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<String>();
 	}
 };
 
diff --git a/alib2data/src/regexp/formal/FormalRegExp.h b/alib2data/src/regexp/formal/FormalRegExp.h
index c1df2695db..2322d43694 100644
--- a/alib2data/src/regexp/formal/FormalRegExp.h
+++ b/alib2data/src/regexp/formal/FormalRegExp.h
@@ -123,7 +123,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<FormalRegExp>();
 	}
 };
 
diff --git a/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp b/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp
index 81b85de9aa..a7dbf0cfb7 100644
--- a/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp
@@ -8,6 +8,7 @@
 #include "FormalRegExpAlternation.h"
 #include "../../exception/AlibException.h"
 #include "../unbounded/UnboundedRegExpAlternation.h"
+#include <sstream>
 
 namespace regexp {
 
@@ -176,4 +177,10 @@ void FormalRegExpAlternation::computeMinimalAlphabet( std::set<alphabet::Symbol>
 	right->computeMinimalAlphabet(alphabet);
 }
 
+FormalRegExpAlternation::operator std::string() const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/formal/FormalRegExpAlternation.h b/alib2data/src/regexp/formal/FormalRegExpAlternation.h
index de9886b04a..cdc61ee511 100644
--- a/alib2data/src/regexp/formal/FormalRegExpAlternation.h
+++ b/alib2data/src/regexp/formal/FormalRegExpAlternation.h
@@ -98,6 +98,11 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 
+	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId<FormalRegExpAlternation>();
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp b/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp
index c65187ec1f..41154f6e3c 100644
--- a/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp
@@ -176,4 +176,10 @@ void FormalRegExpConcatenation::computeMinimalAlphabet( std::set<alphabet::Symbo
 	right->computeMinimalAlphabet(alphabet);
 }
 
+FormalRegExpConcatenation::operator std::string() const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
index 91405bdc4f..ecc788c3df 100644
--- a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
+++ b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
@@ -10,6 +10,7 @@
 
 #include <vector>
 #include "FormalRegExpElement.h"
+#include <sstream>
 
 namespace regexp {
 
@@ -94,6 +95,12 @@ public:
 	 * @copydoc FormalRegExpElement::operator>>() const
 	 */
 	virtual void operator>>(std::ostream& out) const;
+
+	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId<FormalRegExpConcatenation>();
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/formal/FormalRegExpElement.cpp b/alib2data/src/regexp/formal/FormalRegExpElement.cpp
index 612bfc591c..404c2d5a1a 100644
--- a/alib2data/src/regexp/formal/FormalRegExpElement.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpElement.cpp
@@ -16,75 +16,4 @@ FormalRegExpElement::FormalRegExpElement() : parentRegExp(NULL) {
 
 }
 
-FormalRegExpElement::~FormalRegExpElement() noexcept {
-
-}
-
-bool FormalRegExpElement::operator>=(const FormalRegExpElement& other) const {
-	return !(*this < other);
-}
-
-bool FormalRegExpElement::operator<=(const FormalRegExpElement& other) const {
-	return !(*this > other);
-}
-
-bool FormalRegExpElement::operator!=(const FormalRegExpElement& other) const {
-	return !(*this == other);
-}
-
-
-bool FormalRegExpElement::operator<(const FormalRegExpConcatenation& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-bool FormalRegExpElement::operator<(const FormalRegExpAlternation& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-bool FormalRegExpElement::operator<(const FormalRegExpIteration& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-bool FormalRegExpElement::operator<(const FormalRegExpSymbol& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-bool FormalRegExpElement::operator<(const FormalRegExpEpsilon& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-bool FormalRegExpElement::operator<(const FormalRegExpEmpty& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-
-bool FormalRegExpElement::operator==(const FormalRegExpConcatenation&) const {
-	return false;
-}
-
-bool FormalRegExpElement::operator==(const FormalRegExpAlternation&) const {
-	return false;
-}
-
-bool FormalRegExpElement::operator==(const FormalRegExpIteration&) const {
-	return false;
-}
-
-bool FormalRegExpElement::operator==(const FormalRegExpSymbol&) const {
-	return false;
-}
-
-bool FormalRegExpElement::operator==(const FormalRegExpEpsilon&) const {
-	return false;
-}
-
-bool FormalRegExpElement::operator==(const FormalRegExpEmpty&) const {
-	return false;
-}
-
-std::ostream& operator<<(std::ostream& out, const FormalRegExpElement& regexp) {
-	regexp >> out;
-	return out;
-}
-
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/formal/FormalRegExpElement.h b/alib2data/src/regexp/formal/FormalRegExpElement.h
index e02d2d5382..30ff34d1c4 100644
--- a/alib2data/src/regexp/formal/FormalRegExpElement.h
+++ b/alib2data/src/regexp/formal/FormalRegExpElement.h
@@ -30,7 +30,15 @@ class FormalRegExpElement;
 /**
  * Abstract class representing element in the regular expression. Can be operator or symbol.
  */
-class FormalRegExpElement : public std::acceptor_base<FormalRegExpElement, FormalRegExpAlternation, FormalRegExpConcatenation, FormalRegExpIteration, FormalRegExpSymbol, FormalRegExpEmpty, FormalRegExpEpsilon> {
+typedef std::acceptor_base<FormalRegExpElement,
+			FormalRegExpAlternation, FormalRegExpConcatenation, FormalRegExpIteration, FormalRegExpSymbol, FormalRegExpEmpty, FormalRegExpEpsilon
+	> VisitableFormalRegExpElement;
+
+class FormalRegExpElement :
+	public alib::base<
+			FormalRegExpElement,
+			FormalRegExpAlternation, FormalRegExpConcatenation, FormalRegExpIteration, FormalRegExpSymbol, FormalRegExpEmpty, FormalRegExpEpsilon
+	>, public VisitableFormalRegExpElement {
 protected:
 	/* 
 	 * Parent regexp contanining this instance of RegExpElement
@@ -62,14 +70,6 @@ protected:
 	
 public:
 	explicit FormalRegExpElement();
-	
-	/**
-	 * Creates copy of the element.
-	 * @return copy of the element
-	 */
-	virtual FormalRegExpElement* clone() const = 0;
-	
-	virtual FormalRegExpElement* plunder() && = 0;
 
 	/**
 	 * Creates copy of the element.
@@ -77,44 +77,6 @@ public:
 	 */
 	virtual UnboundedRegExpElement* cloneAsUnbounded() const = 0;
 
-	virtual ~FormalRegExpElement() noexcept;
-
-	// RegExpEmpty < RegExpEpsilon < RegExpSymbol < RegExpIteration < RegExpAlternation < RegExpConcatenation
-	virtual bool operator<(const FormalRegExpElement&) const = 0;
-	virtual bool operator==(const FormalRegExpElement&) const = 0;
-	virtual bool operator>(const FormalRegExpElement&) const = 0;
-
-	virtual bool operator>=(const FormalRegExpElement&) const;
-	virtual bool operator<=(const FormalRegExpElement&) const;
-	virtual bool operator!=(const FormalRegExpElement&) const;
-
-	virtual bool operator<(const FormalRegExpConcatenation&) const;
-	virtual bool operator<(const FormalRegExpAlternation&) const;
-	virtual bool operator<(const FormalRegExpIteration&) const;
-	virtual bool operator<(const FormalRegExpSymbol&) const;
-	virtual bool operator<(const FormalRegExpEpsilon&) const;
-	virtual bool operator<(const FormalRegExpEmpty&) const;
-
-	virtual bool operator==(const FormalRegExpConcatenation&) const;
-	virtual bool operator==(const FormalRegExpAlternation&) const;
-	virtual bool operator==(const FormalRegExpIteration&) const;
-	virtual bool operator==(const FormalRegExpSymbol&) const;
-	virtual bool operator==(const FormalRegExpEpsilon&) const;
-	virtual bool operator==(const FormalRegExpEmpty&) const;
-	
-	/**
-	 * Prints XML representation of the RegExp to the output stream.
-	 * @param out output stream to which print the RegExp
-	 */
-	virtual void operator>>(std::ostream& out) const = 0;
-	
-	/**
-	 * Prints XML representation of the RegExp to the output stream.
-	 * @param out output stream to which print the RegExp
-	 * @param regexp RegExp to print
-	 */
-	friend std::ostream& operator<<(std::ostream& out, const FormalRegExpElement& regexp);
-
 	friend class FormalRegExp;
 	
 	friend class FormalRegExpAlternation;
diff --git a/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp b/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp
index fb070961aa..a55e9a92bd 100644
--- a/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp
@@ -83,4 +83,10 @@ void FormalRegExpEmpty::computeMinimalAlphabet( std::set<alphabet::Symbol>&) con
 
 }
 
+FormalRegExpEmpty::operator std::string() const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/formal/FormalRegExpEmpty.h b/alib2data/src/regexp/formal/FormalRegExpEmpty.h
index e3417bb381..300cd803fa 100644
--- a/alib2data/src/regexp/formal/FormalRegExpEmpty.h
+++ b/alib2data/src/regexp/formal/FormalRegExpEmpty.h
@@ -9,6 +9,7 @@
 #define FORMAL_REG_EXP_EMPTY_H_
 
 #include "FormalRegExpElement.h"
+#include <sstream>
 
 namespace regexp {
 
@@ -65,6 +66,12 @@ public:
 	 * @copydoc FormalRegExpElement::operator>>() const
 	 */
 	virtual void operator>>(std::ostream& out) const;
+
+	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId<FormalRegExpEmpty>();
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp b/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp
index 1629e334e0..8d3d8563a2 100644
--- a/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp
@@ -7,6 +7,7 @@
 
 #include "FormalRegExpEpsilon.h"
 #include "../unbounded/UnboundedRegExpEpsilon.h"
+#include <sstream>
 
 namespace regexp {
 
@@ -83,4 +84,10 @@ void FormalRegExpEpsilon::computeMinimalAlphabet( std::set<alphabet::Symbol>&) c
 
 }
 
+FormalRegExpEpsilon::operator std::string() const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/formal/FormalRegExpEpsilon.h b/alib2data/src/regexp/formal/FormalRegExpEpsilon.h
index 1666c23c50..e146862bca 100644
--- a/alib2data/src/regexp/formal/FormalRegExpEpsilon.h
+++ b/alib2data/src/regexp/formal/FormalRegExpEpsilon.h
@@ -9,6 +9,7 @@
 #define FORMAL_REG_EXP_EPSILON_H_
 
 #include "FormalRegExpElement.h"
+#include <sstream>
 
 namespace regexp {
 
@@ -66,6 +67,12 @@ public:
 	 * @copydoc FormalRegExpElement::operator>>() const
 	 */
 	virtual void operator>>(std::ostream& out) const;
+
+	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId<FormalRegExpEpsilon>();
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/formal/FormalRegExpIteration.cpp b/alib2data/src/regexp/formal/FormalRegExpIteration.cpp
index f255ee33da..6ee36586d2 100644
--- a/alib2data/src/regexp/formal/FormalRegExpIteration.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpIteration.cpp
@@ -9,6 +9,7 @@
 #include "../../exception/AlibException.h"
 
 #include "../unbounded/UnboundedRegExpIteration.h"
+#include <sstream>
 
 namespace regexp {
 
@@ -130,5 +131,11 @@ void FormalRegExpIteration::computeMinimalAlphabet( std::set<alphabet::Symbol>&
 	element->computeMinimalAlphabet(alphabet);
 }
 
+FormalRegExpIteration::operator std::string() const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
 } /* namespace regexp */
 
diff --git a/alib2data/src/regexp/formal/FormalRegExpIteration.h b/alib2data/src/regexp/formal/FormalRegExpIteration.h
index e777b0e433..ad71fca8bc 100644
--- a/alib2data/src/regexp/formal/FormalRegExpIteration.h
+++ b/alib2data/src/regexp/formal/FormalRegExpIteration.h
@@ -90,6 +90,12 @@ public:
 	 * @copydoc FormalRegExpElement::operator>>() const
 	 */
 	virtual void operator>>(std::ostream& out) const;
+
+	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId<FormalRegExpIteration>();
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp b/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp
index 52d255b51e..6849734da8 100644
--- a/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp
@@ -7,6 +7,7 @@
 
 #include "FormalRegExpSymbol.h"
 #include "../unbounded/UnboundedRegExpSymbol.h"
+#include <sstream>
 
 namespace regexp {
 
@@ -121,5 +122,11 @@ const alphabet::Symbol& FormalRegExpSymbol::getSymbol() const {
 	return this->symbol;
 }
 
+FormalRegExpSymbol::operator std::string() const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
 } /* namespace regexp */
 
diff --git a/alib2data/src/regexp/formal/FormalRegExpSymbol.h b/alib2data/src/regexp/formal/FormalRegExpSymbol.h
index 85e438df57..05cbbb1219 100644
--- a/alib2data/src/regexp/formal/FormalRegExpSymbol.h
+++ b/alib2data/src/regexp/formal/FormalRegExpSymbol.h
@@ -83,6 +83,12 @@ public:
 	 * Returns the string representation of RegExp Symbol.
 	 */
 	const alphabet::Symbol& getSymbol() const;
+
+	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId<FormalRegExpSymbol>();
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExp.h b/alib2data/src/regexp/unbounded/UnboundedRegExp.h
index 28964b5f73..81a0f29af3 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExp.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExp.h
@@ -123,7 +123,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<UnboundedRegExp>();
 	}
 };
 
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp
index 66656f173c..52f17c3fcc 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp
@@ -9,6 +9,7 @@
 #include "../../exception/AlibException.h"
 #include "../formal/FormalRegExpAlternation.h"
 #include "../formal/FormalRegExpEmpty.h"
+#include <sstream>
 
 namespace regexp {
 
@@ -176,4 +177,10 @@ void UnboundedRegExpAlternation::computeMinimalAlphabet( std::set<alphabet::Symb
 		child->computeMinimalAlphabet(alphabet);
 }
 
+UnboundedRegExpAlternation::operator std::string() const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
index 94d5ee5e47..18b9dec3a7 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
@@ -95,6 +95,12 @@ public:
 	virtual void operator>>(std::ostream& out) const;
 
 	friend class RegExpOptimize;
+
+	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId<UnboundedRegExpAlternation>();
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp
index f932c21a73..96a9f65834 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp
@@ -9,6 +9,7 @@
 #include "../../exception/AlibException.h"
 #include "../formal/FormalRegExpConcatenation.h"
 #include "../formal/FormalRegExpEpsilon.h"
+#include <sstream>
 
 namespace regexp {
 
@@ -175,4 +176,10 @@ void UnboundedRegExpConcatenation::computeMinimalAlphabet( std::set<alphabet::Sy
 		child->computeMinimalAlphabet(alphabet);
 }
 
+UnboundedRegExpConcatenation::operator std::string() const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
index 7b47cb9533..feb155a2eb 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
@@ -94,6 +94,12 @@ public:
 	virtual void operator>>(std::ostream& out) const;
 	
 	friend class RegExpOptimize;
+
+	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId<UnboundedRegExpConcatenation>();
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.cpp
index 499e4cb734..4c631bc7bb 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.cpp
@@ -16,75 +16,4 @@ UnboundedRegExpElement::UnboundedRegExpElement() : parentRegExp(NULL) {
 
 }
 
-UnboundedRegExpElement::~UnboundedRegExpElement() noexcept {
-
-}
-
-bool UnboundedRegExpElement::operator>=(const UnboundedRegExpElement& other) const {
-	return !(*this < other);
-}
-
-bool UnboundedRegExpElement::operator<=(const UnboundedRegExpElement& other) const {
-	return !(*this > other);
-}
-
-bool UnboundedRegExpElement::operator!=(const UnboundedRegExpElement& other) const {
-	return !(*this == other);
-}
-
-
-bool UnboundedRegExpElement::operator<(const UnboundedRegExpConcatenation& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-bool UnboundedRegExpElement::operator<(const UnboundedRegExpAlternation& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-bool UnboundedRegExpElement::operator<(const UnboundedRegExpIteration& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-bool UnboundedRegExpElement::operator<(const UnboundedRegExpSymbol& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-bool UnboundedRegExpElement::operator<(const UnboundedRegExpEpsilon& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-bool UnboundedRegExpElement::operator<(const UnboundedRegExpEmpty& other) const {
-	return typeid(*this).before(typeid(other));
-}
-
-
-bool UnboundedRegExpElement::operator==(const UnboundedRegExpConcatenation&) const {
-	return false;
-}
-
-bool UnboundedRegExpElement::operator==(const UnboundedRegExpAlternation&) const {
-	return false;
-}
-
-bool UnboundedRegExpElement::operator==(const UnboundedRegExpIteration&) const {
-	return false;
-}
-
-bool UnboundedRegExpElement::operator==(const UnboundedRegExpSymbol&) const {
-	return false;
-}
-
-bool UnboundedRegExpElement::operator==(const UnboundedRegExpEpsilon&) const {
-	return false;
-}
-
-bool UnboundedRegExpElement::operator==(const UnboundedRegExpEmpty&) const {
-	return false;
-}
-
-std::ostream& operator<<(std::ostream& out, const UnboundedRegExpElement& regexp) {
-	regexp >> out;
-	return out;
-}
-
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h
index 9d6ee37cec..b057c8d0a2 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h
@@ -30,7 +30,15 @@ class UnboundedRegExpElement;
 /**
  * Abstract class representing element in the regular expression. Can be operator or symbol.
  */
-class UnboundedRegExpElement : public std::acceptor_base<UnboundedRegExpElement, UnboundedRegExpAlternation, UnboundedRegExpConcatenation, UnboundedRegExpIteration, UnboundedRegExpSymbol, UnboundedRegExpEmpty, UnboundedRegExpEpsilon> {
+typedef std::acceptor_base<UnboundedRegExpElement,
+			UnboundedRegExpAlternation, UnboundedRegExpConcatenation, UnboundedRegExpIteration, UnboundedRegExpSymbol, UnboundedRegExpEmpty, UnboundedRegExpEpsilon
+	> VisitableUnboundedRegExpElement;
+
+class UnboundedRegExpElement :
+	public alib::base<
+			UnboundedRegExpElement,
+			UnboundedRegExpAlternation, UnboundedRegExpConcatenation, UnboundedRegExpIteration, UnboundedRegExpSymbol, UnboundedRegExpEmpty, UnboundedRegExpEpsilon
+	>, public VisitableUnboundedRegExpElement {
 protected:
 	/**
 	 * Parent regexp contanining this instance of RegExpElement
@@ -63,58 +71,12 @@ protected:
 public:
 	explicit UnboundedRegExpElement();
 	
-	/**
-	 * Creates copy of the element.
-	 * @return copy of the element
-	 */
-	virtual UnboundedRegExpElement* clone() const = 0;
-	
-	virtual UnboundedRegExpElement* plunder() && = 0;
-
 	/**
 	 * Creates copy of the element.
 	 * @return copy of the element
 	 */
 	virtual FormalRegExpElement* cloneAsFormal() const = 0;
 
-	virtual ~UnboundedRegExpElement() noexcept;
-
-	// RegExpEmpty < RegExpEpsilon < RegExpSymbol < RegExpIteration < RegExpAlternation < RegExpConcatenation
-	virtual bool operator<(const UnboundedRegExpElement&) const = 0;
-	virtual bool operator==(const UnboundedRegExpElement&) const = 0;
-	virtual bool operator>(const UnboundedRegExpElement&) const = 0;
-
-	virtual bool operator>=(const UnboundedRegExpElement&) const;
-	virtual bool operator<=(const UnboundedRegExpElement&) const;
-	virtual bool operator!=(const UnboundedRegExpElement&) const;
-
-	virtual bool operator<(const UnboundedRegExpConcatenation&) const;
-	virtual bool operator<(const UnboundedRegExpAlternation&) const;
-	virtual bool operator<(const UnboundedRegExpIteration&) const;
-	virtual bool operator<(const UnboundedRegExpSymbol&) const;
-	virtual bool operator<(const UnboundedRegExpEpsilon&) const;
-	virtual bool operator<(const UnboundedRegExpEmpty&) const;
-
-	virtual bool operator==(const UnboundedRegExpConcatenation&) const;
-	virtual bool operator==(const UnboundedRegExpAlternation&) const;
-	virtual bool operator==(const UnboundedRegExpIteration&) const;
-	virtual bool operator==(const UnboundedRegExpSymbol&) const;
-	virtual bool operator==(const UnboundedRegExpEpsilon&) const;
-	virtual bool operator==(const UnboundedRegExpEmpty&) const;
-	
-	/**
-	 * Prints XML representation of the RegExp to the output stream.
-	 * @param out output stream to which print the RegExp
-	 */
-	virtual void operator>>(std::ostream& out) const = 0;
-	
-	/**
-	 * Prints XML representation of the RegExp to the output stream.
-	 * @param out output stream to which print the RegExp
-	 * @param regexp RegExp to print
-	 */
-	friend std::ostream& operator<<(std::ostream& out, const UnboundedRegExpElement& regexp);
-
 	friend class UnboundedRegExp;
 	
 	friend class UnboundedRegExpAlternation;
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp
index 11226123f3..06d15fa34e 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp
@@ -7,6 +7,7 @@
 
 #include "UnboundedRegExpEmpty.h"
 #include "../formal/FormalRegExpEmpty.h"
+#include <sstream>
 
 namespace regexp {
 
@@ -83,4 +84,10 @@ void UnboundedRegExpEmpty::computeMinimalAlphabet( std::set<alphabet::Symbol>&)
 
 }
 
+UnboundedRegExpEmpty::operator std::string() const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h
index cdae30504c..97fd1c08fe 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h
@@ -65,7 +65,12 @@ public:
 	 * @copydoc UnboundedRegExpElement::operator>>() const
 	 */
 	virtual void operator>>(std::ostream& out) const;
-	
+
+	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId<UnboundedRegExpEmpty>();
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp
index 565211a136..f190a6055f 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp
@@ -7,6 +7,7 @@
 
 #include "UnboundedRegExpEpsilon.h"
 #include "../formal/FormalRegExpEpsilon.h"
+#include <sstream>
 
 namespace regexp {
 
@@ -83,4 +84,10 @@ void UnboundedRegExpEpsilon::computeMinimalAlphabet( std::set<alphabet::Symbol>&
 
 }
 
+UnboundedRegExpEpsilon::operator std::string() const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h
index 50c45e8167..df1c9205c4 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h
@@ -68,6 +68,11 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 
+	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId<UnboundedRegExpEpsilon>();
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp
index 78e07bdc10..e2f9d5cf20 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp
@@ -9,6 +9,7 @@
 #include "../../exception/AlibException.h"
 
 #include "../formal/FormalRegExpIteration.h"
+#include <sstream>
 
 namespace regexp {
 
@@ -130,5 +131,11 @@ void UnboundedRegExpIteration::computeMinimalAlphabet( std::set<alphabet::Symbol
 	element->computeMinimalAlphabet(alphabet);
 }
 
+UnboundedRegExpIteration::operator std::string() const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
 } /* namespace regexp */
 
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
index afa05a7415..55b53447b3 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
@@ -93,6 +93,12 @@ public:
 	virtual void operator>>(std::ostream& out) const;
 
 	friend class RegExpOptimize;
+
+	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId<UnboundedRegExpIteration>();
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp
index 9cfafbf4f1..77f399bead 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp
@@ -7,6 +7,7 @@
 
 #include "UnboundedRegExpSymbol.h"
 #include "../formal/FormalRegExpSymbol.h"
+#include <sstream>
 
 namespace regexp {
 
@@ -121,5 +122,11 @@ const alphabet::Symbol& UnboundedRegExpSymbol::getSymbol() const {
 	return this->symbol;
 }
 
+UnboundedRegExpSymbol::operator std::string() const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
 } /* namespace regexp */
 
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h
index 858b8b4f61..d0c08c69e4 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h
@@ -82,6 +82,12 @@ public:
 	 * Returns the string representation of RegExp Symbol.
 	 */
 	const alphabet::Symbol& getSymbol() const;
+
+	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId<UnboundedRegExpSymbol>();
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/std/visitor.hpp b/alib2data/src/std/visitor.hpp
index 4a471db892..cf6119f0b1 100644
--- a/alib2data/src/std/visitor.hpp
+++ b/alib2data/src/std/visitor.hpp
@@ -65,6 +65,7 @@ struct const_promoting_helper<Tested, Other...> {
 			typename std::enable_if< std::is_constructible<Desired, Tested>::value >::type* = nullptr >
 	inline static bool tryPromote(void* userData, const Desired& first, const Base& second, const TargetVisitor& visitor) {
 		if(dynamic_cast<const Tested*>(&second)) {
+		//if(Tested::template typeId<Tested>() == second.selfTypeId()) { //TODO on g++-4.9 uncomment
 			visitor.Visit(userData, first, Desired(static_cast<const Tested&>(second)));
 			return true;
 		} else {
@@ -133,6 +134,7 @@ public:
 	template<typename R>
 	void Visit1(void* userData, const T& first, const R& second) const {
 		if(dynamic_cast<const T*>(&second)) {
+		//if(T::template typeId<T>() == second.selfTypeId()) { //TODO on g++-4.9 uncomment
 			this->Visit(userData, first, static_cast<const T&>(second));
 		} else {
 			throw std::logic_error("Same visitor: Visited types are different.");
@@ -153,6 +155,7 @@ public:
 	template<typename R>
 	void Visit1(void* userData, const T& first, const R& second) const {
 		if(dynamic_cast<const T*>(&second)) {
+		//if(T::template typeId<T>() == second.selfTypeId()) { //TODO on g++-4.9 uncomment
 			this->Visit(userData, first, static_cast<const T&>(second));
 		} else {
 			throw std::logic_error("Same visitor: Visited types are different.");
diff --git a/alib2data/src/string/CyclicString.h b/alib2data/src/string/CyclicString.h
index 8c641dc4da..61e5b8851b 100644
--- a/alib2data/src/string/CyclicString.h
+++ b/alib2data/src/string/CyclicString.h
@@ -67,7 +67,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<CyclicString>();
 	}
 };
 
diff --git a/alib2data/src/string/Epsilon.h b/alib2data/src/string/Epsilon.h
index 3d478256f7..bf39c0cf98 100644
--- a/alib2data/src/string/Epsilon.h
+++ b/alib2data/src/string/Epsilon.h
@@ -59,7 +59,7 @@ public:
 	static Epsilon EPSILON;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<Epsilon>();
 	}
 };
 
diff --git a/alib2data/src/string/LinearString.h b/alib2data/src/string/LinearString.h
index 82395fbf5b..914386b1e3 100644
--- a/alib2data/src/string/LinearString.h
+++ b/alib2data/src/string/LinearString.h
@@ -75,7 +75,7 @@ public:
 	virtual operator std::string() const;
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<LinearString>();
 	}
 };
 
diff --git a/alib2data/test-src/std/StdVisitorTest.cpp b/alib2data/test-src/std/StdVisitorTest.cpp
index 073c523d34..dbd7e2cedb 100644
--- a/alib2data/test-src/std/StdVisitorTest.cpp
+++ b/alib2data/test-src/std/StdVisitorTest.cpp
@@ -73,7 +73,7 @@ public:
 	}
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<Tmp1>();
 	}
 
 	int getData() const {
@@ -130,7 +130,7 @@ public:
 	}
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<Tmp2>();
 	}
 
 	double getData() const {
@@ -191,7 +191,7 @@ public:
 	}
 
 	virtual int selfTypeId() const {
-		return typeId(*this);
+		return typeId<Tmp3>();
 	}
 
 	const std::string& getData() const {
-- 
GitLab