From 5f5fef66ae6109dd2b78a03c07d635dbfe3e4c70 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Wed, 11 Jun 2014 10:25:25 +0200
Subject: [PATCH] allow const visitors and use them

---
 alib2/src/alphabet/BlankSymbol.h              |  2 +-
 alib2/src/alphabet/LabeledSymbol.h            |  2 +-
 alib2/src/alphabet/Symbol.h                   |  2 +-
 alib2/src/alphabet/SymbolBase.h               |  2 +-
 alib2/src/alphabet/SymbolToStringComposer.h   |  2 +-
 alib2/src/alphabet/SymbolToXMLComposer.cpp    | 10 +--
 alib2/src/alphabet/SymbolToXMLComposer.h      | 12 ++--
 alib2/src/automaton/Automaton.h               |  2 +-
 alib2/src/automaton/AutomatonBase.h           |  3 +-
 .../src/automaton/AutomatonToXMLComposer.cpp  | 70 +++++++++----------
 alib2/src/automaton/AutomatonToXMLComposer.h  | 64 ++++++++---------
 alib2/src/automaton/FSM/CompactNFA.cpp        |  4 +-
 alib2/src/automaton/FSM/CompactNFA.h          |  2 +-
 alib2/src/automaton/FSM/DFA.h                 |  2 +-
 alib2/src/automaton/FSM/EpsilonNFA.h          |  2 +-
 alib2/src/automaton/FSM/ExtendedNFA.cpp       |  4 +-
 alib2/src/automaton/FSM/ExtendedNFA.h         |  2 +-
 alib2/src/automaton/FSM/NFA.h                 |  2 +-
 alib2/src/automaton/PDA/PDA.h                 |  2 +-
 alib2/src/automaton/TM/OneTapeDTM.h           |  2 +-
 alib2/src/automaton/UnknownAutomaton.h        |  2 +-
 alib2/src/factory/AutomatonFactory.cpp        |  3 +-
 alib2/src/label/IntegerLabel.h                |  2 +-
 alib2/src/label/Label.h                       |  2 +-
 alib2/src/label/LabelBase.h                   |  3 +-
 alib2/src/label/LabelToStringComposer.h       |  2 +-
 alib2/src/label/LabelToXMLComposer.cpp        |  8 +--
 alib2/src/label/LabelToXMLComposer.h          | 10 +--
 alib2/src/label/StringLabel.h                 |  2 +-
 alib2/src/regexp/Alternation.h                |  2 +-
 alib2/src/regexp/Concatenation.h              |  2 +-
 alib2/src/regexp/Iteration.h                  |  2 +-
 alib2/src/regexp/RegExp.h                     |  2 +-
 alib2/src/regexp/RegExpElement.h              |  2 +-
 alib2/src/regexp/RegExpEmpty.h                |  2 +-
 alib2/src/regexp/RegExpEpsilon.h              |  2 +-
 alib2/src/regexp/RegExpSymbol.h               |  2 +-
 alib2/src/regexp/RegExpToStringComposer.cpp   |  6 +-
 alib2/src/regexp/RegExpToStringComposer.h     |  3 +-
 alib2/src/regexp/RegExpToXMLComposer.cpp      | 24 +++----
 alib2/src/regexp/RegExpToXMLComposer.h        | 22 +++---
 alib2/src/std/visitor.hpp                     | 44 +++++++++---
 alib2/src/string/CyclicString.h               |  2 +-
 alib2/src/string/Epsilon.h                    |  2 +-
 alib2/src/string/LinearString.h               |  2 +-
 alib2/src/string/String.h                     |  2 +-
 alib2/src/string/StringBase.h                 |  2 +-
 alib2/src/string/StringToStringComposer.h     |  2 +-
 alib2/src/string/StringToXMLComposer.cpp      | 12 ++--
 alib2/src/string/StringToXMLComposer.h        | 14 ++--
 50 files changed, 197 insertions(+), 183 deletions(-)

diff --git a/alib2/src/alphabet/BlankSymbol.h b/alib2/src/alphabet/BlankSymbol.h
index dca5215d64..671e7a887d 100644
--- a/alib2/src/alphabet/BlankSymbol.h
+++ b/alib2/src/alphabet/BlankSymbol.h
@@ -15,7 +15,7 @@ namespace alphabet {
 /**
  * Represents blank symbol in an alphabet.
  */
-class BlankSymbol : public SymbolBase, public std::element<BlankSymbol, SymbolBase::visitor_type> {
+class BlankSymbol : virtual public SymbolBase, public std::element<BlankSymbol, SymbolBase> {
 public:
 	/**
 	 * Creates a blank symbol.
diff --git a/alib2/src/alphabet/LabeledSymbol.h b/alib2/src/alphabet/LabeledSymbol.h
index 16c0954feb..4e8b236ccb 100644
--- a/alib2/src/alphabet/LabeledSymbol.h
+++ b/alib2/src/alphabet/LabeledSymbol.h
@@ -17,7 +17,7 @@ namespace alphabet {
 /**
  * Represents symbol in an alphabet.
  */
-class LabeledSymbol : public SymbolBase, public std::element<LabeledSymbol, SymbolBase::visitor_type> {
+class LabeledSymbol : virtual public SymbolBase, public std::element<LabeledSymbol, SymbolBase> {
 protected:
 	label::Label label;
 	
diff --git a/alib2/src/alphabet/Symbol.h b/alib2/src/alphabet/Symbol.h
index 6500eedbac..c69839ab0e 100644
--- a/alib2/src/alphabet/Symbol.h
+++ b/alib2/src/alphabet/Symbol.h
@@ -16,7 +16,7 @@ namespace alphabet {
 /**
  * Wrapper around automata.
  */
-class Symbol : public std::element<Symbol, std::visitor<Symbol> > { //TODO toto udělat v std templatované
+class Symbol { //TODO toto udělat v std templatované
 protected:
 	SymbolBase* symbol;
 public:
diff --git a/alib2/src/alphabet/SymbolBase.h b/alib2/src/alphabet/SymbolBase.h
index 98de64cf01..717d2e80f6 100644
--- a/alib2/src/alphabet/SymbolBase.h
+++ b/alib2/src/alphabet/SymbolBase.h
@@ -19,7 +19,7 @@ class BlankSymbol;
 /**
  * Represents symbol in an alphabet.
  */
-class SymbolBase : virtual public std::elementBase<std::visitor<LabeledSymbol, BlankSymbol> > {
+class SymbolBase : virtual public std::elementBase<LabeledSymbol, BlankSymbol> {
 public:
 	virtual ~SymbolBase() noexcept;
 
diff --git a/alib2/src/alphabet/SymbolToStringComposer.h b/alib2/src/alphabet/SymbolToStringComposer.h
index 1488a44362..56acb49b26 100644
--- a/alib2/src/alphabet/SymbolToStringComposer.h
+++ b/alib2/src/alphabet/SymbolToStringComposer.h
@@ -18,7 +18,7 @@ namespace alphabet {
 /**
  * This class contains methods to print XML representation of string to the output stream.
  */
-class SymbolToStringComposer : public Symbol::visitor_type, public SymbolBase::visitor_type {
+class SymbolToStringComposer : public SymbolBase::visitor_type {
 	void Visit(void*, const label::Label& label);
 	void Visit(void*, const Symbol& symbol);
 	void Visit(void*, const LabeledSymbol& symbol);
diff --git a/alib2/src/alphabet/SymbolToXMLComposer.cpp b/alib2/src/alphabet/SymbolToXMLComposer.cpp
index 3eabc5243e..13ec4c900d 100644
--- a/alib2/src/alphabet/SymbolToXMLComposer.cpp
+++ b/alib2/src/alphabet/SymbolToXMLComposer.cpp
@@ -10,20 +10,20 @@
 
 namespace alphabet {
 
-void SymbolToXMLComposer::Visit(void* userData, const label::Label& label) {
+void SymbolToXMLComposer::Visit(void* userData, const label::Label& label) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token((std::string) label, sax::Token::CHARACTER));
 }
 
-void SymbolToXMLComposer::Visit(void* userData, const BlankSymbol&) {
+void SymbolToXMLComposer::Visit(void* userData, const BlankSymbol&) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("BlankSymbol", sax::Token::START_ELEMENT));
 	out.push_back(sax::Token("BlankSymbol", sax::Token::END_ELEMENT));
 }
 
-void SymbolToXMLComposer::Visit(void* userData, const LabeledSymbol& symbol) {
+void SymbolToXMLComposer::Visit(void* userData, const LabeledSymbol& symbol) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("LabeledSymbol", sax::Token::START_ELEMENT));
@@ -31,12 +31,12 @@ void SymbolToXMLComposer::Visit(void* userData, const LabeledSymbol& symbol) {
 	out.push_back(sax::Token("LabeledSymbol", sax::Token::END_ELEMENT));
 }
 
-void SymbolToXMLComposer::Visit(void* userData, const Symbol& symbol) {
+void SymbolToXMLComposer::Visit(void* userData, const Symbol& symbol) const {
 	symbol.getSymbol().Accept(userData, *this);
 
 }
 
-std::list<sax::Token> SymbolToXMLComposer::compose(const Symbol& symbol) {
+std::list<sax::Token> SymbolToXMLComposer::compose(const Symbol& symbol) const {
 	std::list<sax::Token> out;
 	Visit((void*) &out, symbol);
 	return out;
diff --git a/alib2/src/alphabet/SymbolToXMLComposer.h b/alib2/src/alphabet/SymbolToXMLComposer.h
index df5019e2ad..75829d68c2 100644
--- a/alib2/src/alphabet/SymbolToXMLComposer.h
+++ b/alib2/src/alphabet/SymbolToXMLComposer.h
@@ -18,11 +18,11 @@ namespace alphabet {
 /**
  * This class contains methods to print XML representation of string to the output stream.
  */
-class SymbolToXMLComposer : public Symbol::visitor_type, public SymbolBase::visitor_type {
-	void Visit(void*, const label::Label& slabel);
-	void Visit(void*, const Symbol& symbol);
-	void Visit(void*, const LabeledSymbol& symbol);
-	void Visit(void*, const BlankSymbol& symbol);
+class SymbolToXMLComposer : public SymbolBase::const_visitor_type {
+	void Visit(void*, const label::Label& slabel) const;
+	void Visit(void*, const Symbol& symbol) const;
+	void Visit(void*, const LabeledSymbol& symbol) const;
+	void Visit(void*, const BlankSymbol& symbol) const;
 
 public:
 	/**
@@ -30,7 +30,7 @@ public:
 	 * @param string String to print
 	 * @param out output stream to which print the String
 	 */
-	std::list<sax::Token> compose(const Symbol& symbol);
+	std::list<sax::Token> compose(const Symbol& symbol) const;
 };
 
 } /* namespace alphabet */
diff --git a/alib2/src/automaton/Automaton.h b/alib2/src/automaton/Automaton.h
index cdcfd09db4..4c9e0b8d01 100644
--- a/alib2/src/automaton/Automaton.h
+++ b/alib2/src/automaton/Automaton.h
@@ -16,7 +16,7 @@ namespace automaton {
 /**
  * Wrapper around automata.
  */
-class Automaton : public std::element<Automaton, std::visitor<Automaton> > {
+class Automaton {
 protected:
 	AutomatonBase* automaton;
 public:
diff --git a/alib2/src/automaton/AutomatonBase.h b/alib2/src/automaton/AutomatonBase.h
index aac5328d60..bc669805ea 100644
--- a/alib2/src/automaton/AutomatonBase.h
+++ b/alib2/src/automaton/AutomatonBase.h
@@ -9,6 +9,7 @@
 #define AUTOMATON_BASE_H_
 
 #include "../std/visitor.hpp"
+#include <iostream>
 
 namespace automaton {
 
@@ -24,7 +25,7 @@ class OneTapeDTM;
 /**
  * Abstract base class for all automata.
  */
-class AutomatonBase : virtual public std::elementBase<std::visitor<UnknownAutomaton, DFA, NFA, EpsilonNFA, CompactNFA, ExtendedNFA, PDA, OneTapeDTM> > {
+class AutomatonBase : virtual public std::elementBase<UnknownAutomaton, DFA, NFA, EpsilonNFA, CompactNFA, ExtendedNFA, PDA, OneTapeDTM> {
 public:
 	virtual AutomatonBase* clone() const = 0;
 
diff --git a/alib2/src/automaton/AutomatonToXMLComposer.cpp b/alib2/src/automaton/AutomatonToXMLComposer.cpp
index f90fdfbbb7..5fff45b7c9 100644
--- a/alib2/src/automaton/AutomatonToXMLComposer.cpp
+++ b/alib2/src/automaton/AutomatonToXMLComposer.cpp
@@ -10,7 +10,7 @@
 
 namespace automaton {
 
-void AutomatonToXMLComposer::printStates(std::list<sax::Token>& out, const std::set<State>& states, std::string tagName) {
+void AutomatonToXMLComposer::printStates(std::list<sax::Token>& out, const std::set<State>& states, std::string tagName) const {
 	out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT));
 	for (auto& state : states) {
 		printState(out, state, "state");
@@ -18,7 +18,7 @@ void AutomatonToXMLComposer::printStates(std::list<sax::Token>& out, const std::
 	out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT));
 }
 
-void AutomatonToXMLComposer::printSymbols(std::list<sax::Token>& out, const std::set<alphabet::Symbol>& symbols, std::string tagName) {
+void AutomatonToXMLComposer::printSymbols(std::list<sax::Token>& out, const std::set<alphabet::Symbol>& symbols, std::string tagName) const {
 	out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT));
 	for (auto& symbol : symbols) {
 		printSymbol(out, symbol, "symbol");
@@ -26,7 +26,7 @@ void AutomatonToXMLComposer::printSymbols(std::list<sax::Token>& out, const std:
 	out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT));
 }
 
-void AutomatonToXMLComposer::printSymbols(std::list<sax::Token>& out, const std::vector<alphabet::Symbol>& symbols, std::string tagName) {
+void AutomatonToXMLComposer::printSymbols(std::list<sax::Token>& out, const std::vector<alphabet::Symbol>& symbols, std::string tagName) const {
 	out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT));
 	for (auto& symbol : symbols) {
 		printSymbol(out, symbol, "symbol");
@@ -34,13 +34,13 @@ void AutomatonToXMLComposer::printSymbols(std::list<sax::Token>& out, const std:
 	out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT));
 }
 
-void AutomatonToXMLComposer::printShift(std::list<sax::Token>& out, const Shift shift, std::string tagName) {
+void AutomatonToXMLComposer::printShift(std::list<sax::Token>& out, const Shift shift, std::string tagName) const {
 	out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT));
 	out.push_back(sax::Token(SHIFT_NAMES [shift], sax::Token::CHARACTER));
 	out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT));
 }
 
-void AutomatonToXMLComposer::printTransitions(std::list<sax::Token>& out, const UnknownAutomaton& automaton) {
+void AutomatonToXMLComposer::printTransitions(std::list<sax::Token>& out, const UnknownAutomaton& automaton) const {
 	out.push_back(sax::Token("transitions", sax::Token::START_ELEMENT));
 	for (auto& transition : automaton.getTransitions()) {
 		out.push_back(sax::Token("transition", sax::Token::START_ELEMENT));
@@ -73,7 +73,7 @@ void AutomatonToXMLComposer::printTransitions(std::list<sax::Token>& out, const
 }
 
 
-void AutomatonToXMLComposer::printTransitions(std::list<sax::Token>& out, const DFA& automaton) {
+void AutomatonToXMLComposer::printTransitions(std::list<sax::Token>& out, const DFA& automaton) const {
 	out.push_back(sax::Token("transitions", sax::Token::START_ELEMENT));
 	for(auto& transition : automaton.getTransitions()) {
 		out.push_back(sax::Token("transition", sax::Token::START_ELEMENT));
@@ -88,7 +88,7 @@ void AutomatonToXMLComposer::printTransitions(std::list<sax::Token>& out, const
 	out.push_back(sax::Token("transitions", sax::Token::END_ELEMENT));
 }
 
-void AutomatonToXMLComposer::printTransitions(std::list<sax::Token>& out, const NFA& automaton) {
+void AutomatonToXMLComposer::printTransitions(std::list<sax::Token>& out, const NFA& automaton) const {
 	out.push_back(sax::Token("transitions", sax::Token::START_ELEMENT));
 	for(auto& transition : automaton.getTransitions()) {
 		for(auto& targetState: transition.second) {
@@ -105,7 +105,7 @@ void AutomatonToXMLComposer::printTransitions(std::list<sax::Token>& out, const
 	out.push_back(sax::Token("transitions", sax::Token::END_ELEMENT));
 }
 
-void AutomatonToXMLComposer::printTransitions(std::list<sax::Token>& out, const EpsilonNFA& automaton) {
+void AutomatonToXMLComposer::printTransitions(std::list<sax::Token>& out, const EpsilonNFA& automaton) const {
 	out.push_back(sax::Token("transitions", sax::Token::START_ELEMENT));
 	for(auto& transition : automaton.getTransitions()) {
 		for(auto& targetState: transition.second) {
@@ -122,19 +122,19 @@ void AutomatonToXMLComposer::printTransitions(std::list<sax::Token>& out, const
 	out.push_back(sax::Token("transitions", sax::Token::END_ELEMENT));
 }
 
-void AutomatonToXMLComposer::printState(std::list<sax::Token>& out, const State& state, std::string tagName) {
+void AutomatonToXMLComposer::printState(std::list<sax::Token>& out, const State& state, std::string tagName) const {
 	out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT));
 	out.push_back(sax::Token(state.getName(), sax::Token::CHARACTER));
 	out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT));
 }
 
-void AutomatonToXMLComposer::printInput(std::list<sax::Token>& out, const alphabet::Symbol& symbol, std::string tagName) {
+void AutomatonToXMLComposer::printInput(std::list<sax::Token>& out, const alphabet::Symbol& symbol, std::string tagName) const {
 	out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT));
 	out.push_back(sax::Token((std::string) symbol, sax::Token::CHARACTER));
 	out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT));
 }
 
-void AutomatonToXMLComposer::printInput(std::list<sax::Token>& out, const std::variant<string::Epsilon, alphabet::Symbol>& symbol, std::string tagName) {
+void AutomatonToXMLComposer::printInput(std::list<sax::Token>& out, const std::variant<string::Epsilon, alphabet::Symbol>& symbol, std::string tagName) const {
 	out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT));
 	if(symbol.is<string::Epsilon>()) {
 		out.push_back(sax::Token("epsilon", sax::Token::START_ELEMENT));
@@ -148,7 +148,7 @@ void AutomatonToXMLComposer::printInput(std::list<sax::Token>& out, const std::v
 	out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT));
 }
 
-void AutomatonToXMLComposer::printSymbol(std::list<sax::Token>& out, const alphabet::Symbol& symbol, std::string tagName) {
+void AutomatonToXMLComposer::printSymbol(std::list<sax::Token>& out, const alphabet::Symbol& symbol, std::string tagName) const {
 	out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT));
 	if(symbol.getSymbol() == alphabet::BlankSymbol::BLANK) {
 		out.push_back(sax::Token("blank", sax::Token::START_ELEMENT));
@@ -159,13 +159,13 @@ void AutomatonToXMLComposer::printSymbol(std::list<sax::Token>& out, const alpha
 	out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT));
 }
 
-std::list<sax::Token> AutomatonToXMLComposer::compose(const AutomatonBase& automaton) {
+std::list<sax::Token> AutomatonToXMLComposer::compose(const AutomatonBase& automaton) const {
 	std::list<sax::Token> out;
 	automaton.Accept((void*) &out, *this);
 	return out;
 }
 
-std::list<sax::Token> AutomatonToXMLComposer::compose(const UnknownAutomaton& automaton) {
+std::list<sax::Token> AutomatonToXMLComposer::compose(const UnknownAutomaton& automaton) const {
 	std::list<sax::Token> out;
 	out.push_back(sax::Token("automaton", sax::Token::START_ELEMENT));
 	
@@ -200,7 +200,7 @@ std::list<sax::Token> AutomatonToXMLComposer::compose(const UnknownAutomaton& au
 	return out;
 }
 
-std::list<sax::Token> AutomatonToXMLComposer::compose(const DFA& automaton) {
+std::list<sax::Token> AutomatonToXMLComposer::compose(const DFA& automaton) const {
 	std::list<sax::Token> out;
 	out.push_back(sax::Token("DFA", sax::Token::START_ELEMENT));
 
@@ -214,7 +214,7 @@ std::list<sax::Token> AutomatonToXMLComposer::compose(const DFA& automaton) {
 	return out;
 }
 
-std::list<sax::Token> AutomatonToXMLComposer::compose(const NFA& automaton) {
+std::list<sax::Token> AutomatonToXMLComposer::compose(const NFA& automaton) const {
 	std::list<sax::Token> out;
 	out.push_back(sax::Token("NFA", sax::Token::START_ELEMENT));
 
@@ -228,7 +228,7 @@ std::list<sax::Token> AutomatonToXMLComposer::compose(const NFA& automaton) {
 	return out;
 }
 
-std::list<sax::Token> AutomatonToXMLComposer::compose(const EpsilonNFA& automaton) {
+std::list<sax::Token> AutomatonToXMLComposer::compose(const EpsilonNFA& automaton) const {
 	std::list<sax::Token> out;
 	out.push_back(sax::Token("EpsilonNFA", sax::Token::START_ELEMENT));
 
@@ -242,67 +242,67 @@ std::list<sax::Token> AutomatonToXMLComposer::compose(const EpsilonNFA& automato
 	return out;
 }
 
-std::list<sax::Token> AutomatonToXMLComposer::compose(const ExtendedNFA& automaton) {
+std::list<sax::Token> AutomatonToXMLComposer::compose(const ExtendedNFA& automaton) const {
 	std::list<sax::Token> out;
 	return out;
 }
 
-std::list<sax::Token> AutomatonToXMLComposer::compose(const CompactNFA& automaton) {
+std::list<sax::Token> AutomatonToXMLComposer::compose(const CompactNFA& automaton) const {
 	std::list<sax::Token> out;
 	return out;
 }
 
-std::list<sax::Token> AutomatonToXMLComposer::compose(const PDA& automaton) {
+std::list<sax::Token> AutomatonToXMLComposer::compose(const PDA& automaton) const {
 	std::list<sax::Token> out;
 	return out;
 }
 
-std::list<sax::Token> AutomatonToXMLComposer::compose(const OneTapeDTM& automaton) {
+std::list<sax::Token> AutomatonToXMLComposer::compose(const OneTapeDTM& automaton) const {
 	std::list<sax::Token> out;
 	return out;
 }
 
 
-std::list<sax::Token> AutomatonToXMLComposer::compose(const Automaton& automaton) {
+std::list<sax::Token> AutomatonToXMLComposer::compose(const Automaton& automaton) const {
 	std::list<sax::Token> out;
-	automaton.Accept((void*) &out, *this);
+	automaton.getAutomaton().Accept((void*) &out, *this);
 	return out;
 }
 
-void AutomatonToXMLComposer::Visit(void* data, const Automaton& automaton) {
+void AutomatonToXMLComposer::Visit(void* data, const Automaton& automaton) const {
 	*((std::list<sax::Token>*) data) = this->compose(automaton);
 }
 
-void AutomatonToXMLComposer::Visit(void* data, const UnknownAutomaton& automaton) {
+void AutomatonToXMLComposer::Visit(void* data, const UnknownAutomaton& automaton) const {
 	*((std::list<sax::Token>*) data) = this->compose(automaton);
 }
 
-void AutomatonToXMLComposer::Visit(void* data, const EpsilonNFA& automaton) {
+void AutomatonToXMLComposer::Visit(void* data, const EpsilonNFA& automaton) const {
 	*((std::list<sax::Token>*) data) = this->compose(automaton);
 }
 
-void AutomatonToXMLComposer::Visit(void* data, const NFA& automaton) {
+void AutomatonToXMLComposer::Visit(void* data, const NFA& automaton) const {
 	*((std::list<sax::Token>*) data) = this->compose(automaton);
 }
 
-void AutomatonToXMLComposer::Visit(void* data, const DFA& automaton) {
+void AutomatonToXMLComposer::Visit(void* data, const DFA& automaton) const {
 	*((std::list<sax::Token>*) data) = this->compose(automaton);
 }
 
-void AutomatonToXMLComposer::Visit(void* data, const ExtendedNFA& automaton) {
+void AutomatonToXMLComposer::Visit(void* data, const ExtendedNFA& automaton) const {
 	*((std::list<sax::Token>*) data) = this->compose(automaton);
 }
 
-void AutomatonToXMLComposer::Visit(void* data, const CompactNFA& automaton) {
-	*((std::list<sax::Token>*) data) = this->compose(automaton);;
+void AutomatonToXMLComposer::Visit(void* data, const CompactNFA& automaton) const {
+	*((std::list<sax::Token>*) data) = this->compose(automaton);
 }
 
-void AutomatonToXMLComposer::Visit(void* data, const PDA& automaton) {
-	*((std::list<sax::Token>*) data) = this->compose(automaton);;
+void AutomatonToXMLComposer::Visit(void* data, const PDA& automaton) const {
+	*((std::list<sax::Token>*) data) = this->compose(automaton);
 }
 
-void AutomatonToXMLComposer::Visit(void* data, const OneTapeDTM& automaton) {
-	*((std::list<sax::Token>*) data) = this->compose(automaton);;
+void AutomatonToXMLComposer::Visit(void* data, const OneTapeDTM& automaton) const {
+	*((std::list<sax::Token>*) data) = this->compose(automaton);
 }
 
 } /* namespace automaton */
diff --git a/alib2/src/automaton/AutomatonToXMLComposer.h b/alib2/src/automaton/AutomatonToXMLComposer.h
index 06e3430bdd..6ccaf9ea4f 100644
--- a/alib2/src/automaton/AutomatonToXMLComposer.h
+++ b/alib2/src/automaton/AutomatonToXMLComposer.h
@@ -22,32 +22,32 @@ namespace automaton {
 /**
  * This class contains methods to print XML representation of automata to the output stream.
  */
-class AutomatonToXMLComposer : public Automaton::visitor_type, public AutomatonBase::visitor_type {
-	void Visit(void*, const Automaton& automaton);
-	void Visit(void*, const UnknownAutomaton& automaton);
-	void Visit(void*, const EpsilonNFA& automaton);
-	void Visit(void*, const NFA& automaton);
-	void Visit(void*, const DFA& automaton);
-	void Visit(void*, const ExtendedNFA& automaton);
-	void Visit(void*, const CompactNFA& automaton);
-	void Visit(void*, const PDA& automaton);
-	void Visit(void*, const OneTapeDTM& automaton);
+class AutomatonToXMLComposer : public AutomatonBase::const_visitor_type {
+	void Visit(void*, const Automaton& automaton) const;
+	void Visit(void*, const UnknownAutomaton& automaton) const;
+	void Visit(void*, const EpsilonNFA& automaton) const;
+	void Visit(void*, const NFA& automaton) const;
+	void Visit(void*, const DFA& automaton) const;
+	void Visit(void*, const ExtendedNFA& automaton) const;
+	void Visit(void*, const CompactNFA& automaton) const;
+	void Visit(void*, const PDA& automaton) const;
+	void Visit(void*, const OneTapeDTM& automaton) const;
 
 protected:
-	static void printStates(std::list<sax::Token>&, const std::set<State>& states, std::string tagName);
-	static void printSymbols(std::list<sax::Token>&, const std::set<alphabet::Symbol>& symbols, std::string tagName);
-	static void printSymbols(std::list<sax::Token>&, const std::vector<alphabet::Symbol>& symbols, std::string tagName);
-	static void printShift(std::list<sax::Token>&, const Shift shift, std::string tagName);
+	void printStates(std::list<sax::Token>&, const std::set<State>& states, std::string tagName) const;
+	void printSymbols(std::list<sax::Token>&, const std::set<alphabet::Symbol>& symbols, std::string tagName) const;
+	void printSymbols(std::list<sax::Token>&, const std::vector<alphabet::Symbol>& symbols, std::string tagName) const;
+	void printShift(std::list<sax::Token>&, const Shift shift, std::string tagName) const;
 
-	static void printTransitions(std::list<sax::Token>&, const UnknownAutomaton& automaton);
-	static void printTransitions(std::list<sax::Token>&, const EpsilonNFA& automaton);
-	static void printTransitions(std::list<sax::Token>&, const NFA& automaton);
-	static void printTransitions(std::list<sax::Token>&, const DFA& automaton);
+	void printTransitions(std::list<sax::Token>&, const UnknownAutomaton& automaton) const;
+	void printTransitions(std::list<sax::Token>&, const EpsilonNFA& automaton) const;
+	void printTransitions(std::list<sax::Token>&, const NFA& automaton) const;
+	void printTransitions(std::list<sax::Token>&, const DFA& automaton) const;
 
-	static void printState(std::list<sax::Token>&, const State& state, std::string tagName);
-	static void printSymbol(std::list<sax::Token>&, const alphabet::Symbol& symbol, std::string tagName);
-	static void printInput(std::list<sax::Token>& out, const alphabet::Symbol& symbol, std::string tagName);
-	static void printInput(std::list<sax::Token>&, const std::variant<string::Epsilon, alphabet::Symbol>&, std::string);
+	void printState(std::list<sax::Token>&, const State& state, std::string tagName) const;
+	void printSymbol(std::list<sax::Token>&, const alphabet::Symbol& symbol, std::string tagName) const;
+	void printInput(std::list<sax::Token>& out, const alphabet::Symbol& symbol, std::string tagName) const;
+	void printInput(std::list<sax::Token>&, const std::variant<string::Epsilon, alphabet::Symbol>&, std::string) const;
 
 public:
 	/**
@@ -55,18 +55,18 @@ public:
 	 * @param automaton automaton to print
 	 * @return list of xml tokens representing the automaton
 	 */
-	std::list<sax::Token> compose(const AutomatonBase& automaton);
+	std::list<sax::Token> compose(const AutomatonBase& automaton) const;
 
-	std::list<sax::Token> compose(const Automaton& automaton);
+	std::list<sax::Token> compose(const Automaton& automaton) const;
 	
-	std::list<sax::Token> compose(const UnknownAutomaton& automaton);
-	std::list<sax::Token> compose(const DFA& automaton);
-	std::list<sax::Token> compose(const NFA& automaton);
-	std::list<sax::Token> compose(const EpsilonNFA& automaton);
-	std::list<sax::Token> compose(const ExtendedNFA& automaton);
-	std::list<sax::Token> compose(const CompactNFA& automaton);
-	std::list<sax::Token> compose(const PDA& automaton);
-	std::list<sax::Token> compose(const OneTapeDTM& automaton);
+	std::list<sax::Token> compose(const UnknownAutomaton& automaton) const;
+	std::list<sax::Token> compose(const DFA& automaton) const;
+	std::list<sax::Token> compose(const NFA& automaton) const;
+	std::list<sax::Token> compose(const EpsilonNFA& automaton) const;
+	std::list<sax::Token> compose(const ExtendedNFA& automaton) const;
+	std::list<sax::Token> compose(const CompactNFA& automaton) const;
+	std::list<sax::Token> compose(const PDA& automaton) const;
+	std::list<sax::Token> compose(const OneTapeDTM& automaton) const;
 };
 
 } /* namespace automaton */
diff --git a/alib2/src/automaton/FSM/CompactNFA.cpp b/alib2/src/automaton/FSM/CompactNFA.cpp
index f9fe803140..e415f46bed 100644
--- a/alib2/src/automaton/FSM/CompactNFA.cpp
+++ b/alib2/src/automaton/FSM/CompactNFA.cpp
@@ -60,13 +60,13 @@ bool CompactNFA::addTransition(const State& from, const string::String& input, c
 	if (states.find(to) == states.end())
 		throw AutomatonException("State \"" + to.getName() + "\" doesn't exist.");
 
-	std::pair<State, string::String> key = make_pair(from, input);
+	std::pair<State, string::String> key = std::make_pair(from, input);
 	
 	return transitions[key].insert(to).second;
 }
 
 bool CompactNFA::removeTransition(const State& from, const string::String& input, const State& to) {
-	std::pair<State, string::String> key = make_pair(from, input);
+	std::pair<State, string::String> key = std::make_pair(from, input);
 	
 	return transitions[key].erase(to);
 }
diff --git a/alib2/src/automaton/FSM/CompactNFA.h b/alib2/src/automaton/FSM/CompactNFA.h
index 6e6b498a24..9c25705881 100644
--- a/alib2/src/automaton/FSM/CompactNFA.h
+++ b/alib2/src/automaton/FSM/CompactNFA.h
@@ -20,7 +20,7 @@ namespace automaton {
  * Represents Finite Automaton.
  * Can store nondeterministic finite automaton without epsilon transitions.
  */
-class CompactNFA : public AutomatonBase, public std::element<CompactNFA, AutomatonBase::visitor_type>, public MultiInitialStates, public InputAlphabet {
+class CompactNFA : virtual public AutomatonBase, public std::element<CompactNFA, AutomatonBase>, public MultiInitialStates, public InputAlphabet {
 protected:
 	std::map<std::pair<State, string::String>, std::set<State> > transitions;
 public:
diff --git a/alib2/src/automaton/FSM/DFA.h b/alib2/src/automaton/FSM/DFA.h
index 59952216a0..03a2a203da 100644
--- a/alib2/src/automaton/FSM/DFA.h
+++ b/alib2/src/automaton/FSM/DFA.h
@@ -20,7 +20,7 @@ namespace automaton {
  * Represents Finite Automaton.
  * Can store nondeterministic finite automaton without epsilon transitions.
  */
-class DFA : public AutomatonBase, public std::element<DFA, AutomatonBase::visitor_type>, public SingleInitialState, public InputAlphabet {
+class DFA : virtual public AutomatonBase, public std::element<DFA, AutomatonBase>, public SingleInitialState, public InputAlphabet {
 protected:
 	std::map<std::pair<State, alphabet::Symbol>, State> transitions;
 public:
diff --git a/alib2/src/automaton/FSM/EpsilonNFA.h b/alib2/src/automaton/FSM/EpsilonNFA.h
index 09398a52d9..61fa4c44fc 100644
--- a/alib2/src/automaton/FSM/EpsilonNFA.h
+++ b/alib2/src/automaton/FSM/EpsilonNFA.h
@@ -22,7 +22,7 @@ namespace automaton {
  * Represents Finite Automaton.
  * Can store nondeterministic finite automaton with epsilon transitions.
  */
-class EpsilonNFA : public AutomatonBase, public std::element<EpsilonNFA, AutomatonBase::visitor_type>, public MultiInitialStates, public InputAlphabet {
+class EpsilonNFA : virtual public AutomatonBase, public std::element<EpsilonNFA, AutomatonBase>, public MultiInitialStates, public InputAlphabet {
 protected:
 	std::map<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol> >, std::set<State> > transitions;
 public:
diff --git a/alib2/src/automaton/FSM/ExtendedNFA.cpp b/alib2/src/automaton/FSM/ExtendedNFA.cpp
index 315a312c12..92cfd5f787 100644
--- a/alib2/src/automaton/FSM/ExtendedNFA.cpp
+++ b/alib2/src/automaton/FSM/ExtendedNFA.cpp
@@ -60,13 +60,13 @@ bool ExtendedNFA::addTransition(const State& from, const regexp::RegExp& input,
 	if (states.find(to) == states.end())
 		throw AutomatonException("State \"" + to.getName() + "\" doesn't exist.");
 
-	std::pair<State, regexp::RegExp> key = make_pair(from, input);
+	std::pair<State, regexp::RegExp> key = std::make_pair(from, input);
 	
 	return transitions[key].insert(to).second;
 }
 
 bool ExtendedNFA::removeTransition(const State& from, const regexp::RegExp& input, const State& to) {
-	std::pair<State, regexp::RegExp> key = make_pair(from, input);
+	std::pair<State, regexp::RegExp> key = std::make_pair(from, input);
 	
 	return transitions[key].erase(to);
 }
diff --git a/alib2/src/automaton/FSM/ExtendedNFA.h b/alib2/src/automaton/FSM/ExtendedNFA.h
index dfcb73fd9b..b3715bd4f8 100644
--- a/alib2/src/automaton/FSM/ExtendedNFA.h
+++ b/alib2/src/automaton/FSM/ExtendedNFA.h
@@ -20,7 +20,7 @@ namespace automaton {
  * Represents Finite Automaton.
  * Can store nondeterministic finite automaton without epsilon transitions.
  */
-class ExtendedNFA : public AutomatonBase, public std::element<ExtendedNFA, AutomatonBase::visitor_type>, public MultiInitialStates, public InputAlphabet {
+class ExtendedNFA : virtual public AutomatonBase, public std::element<ExtendedNFA, AutomatonBase>, public MultiInitialStates, public InputAlphabet {
 protected:
 	std::map<std::pair<State, regexp::RegExp>, std::set<State> > transitions;
 public:
diff --git a/alib2/src/automaton/FSM/NFA.h b/alib2/src/automaton/FSM/NFA.h
index 11a0acb2e1..6ac9bca3af 100644
--- a/alib2/src/automaton/FSM/NFA.h
+++ b/alib2/src/automaton/FSM/NFA.h
@@ -21,7 +21,7 @@ namespace automaton {
  * Represents Finite Automaton.
  * Can store nondeterministic finite automaton without epsilon transitions.
  */
-class NFA : public AutomatonBase, public std::element<NFA, AutomatonBase::visitor_type>, public MultiInitialStates, public InputAlphabet {
+class NFA : virtual public AutomatonBase, public std::element<NFA, AutomatonBase>, public MultiInitialStates, public InputAlphabet {
 protected:
 	std::map<std::pair<State, alphabet::Symbol>, std::set<State> > transitions;
 public:
diff --git a/alib2/src/automaton/PDA/PDA.h b/alib2/src/automaton/PDA/PDA.h
index 2594295d00..125097599d 100644
--- a/alib2/src/automaton/PDA/PDA.h
+++ b/alib2/src/automaton/PDA/PDA.h
@@ -23,7 +23,7 @@ namespace automaton {
 /**
  * Push Down Automaton
  */
-class PDA: public AutomatonBase, public std::element<PDA, AutomatonBase::visitor_type>, public MultiInitialStates, public InputAlphabet {
+class PDA: virtual public AutomatonBase, public std::element<PDA, AutomatonBase>, public MultiInitialStates, public InputAlphabet {
 protected:
 	std::set<alphabet::Symbol> stackAlphabet;
 	std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::set<std::pair<State, std::vector<alphabet::Symbol> > > > transitions;
diff --git a/alib2/src/automaton/TM/OneTapeDTM.h b/alib2/src/automaton/TM/OneTapeDTM.h
index b6963eb07e..ae9b995a0a 100644
--- a/alib2/src/automaton/TM/OneTapeDTM.h
+++ b/alib2/src/automaton/TM/OneTapeDTM.h
@@ -22,7 +22,7 @@ namespace automaton {
 /**
  * One tape turing machine
  */
-class OneTapeDTM : public AutomatonBase, public std::element<OneTapeDTM, AutomatonBase::visitor_type>, public SingleInitialState, public BlankSymbolInputTapeAlphabet {
+class OneTapeDTM : virtual public AutomatonBase, public std::element<OneTapeDTM, AutomatonBase>, public SingleInitialState, public BlankSymbolInputTapeAlphabet {
 protected:
 	std::map<std::pair<State, alphabet::Symbol>, std::tuple<State, alphabet::Symbol, Shift> > transitions;
 
diff --git a/alib2/src/automaton/UnknownAutomaton.h b/alib2/src/automaton/UnknownAutomaton.h
index e6a2304f4b..63ddcc95bc 100644
--- a/alib2/src/automaton/UnknownAutomaton.h
+++ b/alib2/src/automaton/UnknownAutomaton.h
@@ -21,7 +21,7 @@ namespace automaton {
 /**
  * Class representing unknown automaton parsed from XML.
  */
-class UnknownAutomaton : public AutomatonBase, public std::element<UnknownAutomaton, AutomatonBase::visitor_type> {
+class UnknownAutomaton : virtual public AutomatonBase, public std::element<UnknownAutomaton, AutomatonBase> {
 protected:
 	std::set<State> states;
 	std::set<State> initialStates;
diff --git a/alib2/src/factory/AutomatonFactory.cpp b/alib2/src/factory/AutomatonFactory.cpp
index 0a2c5b5364..62b8136a46 100644
--- a/alib2/src/factory/AutomatonFactory.cpp
+++ b/alib2/src/factory/AutomatonFactory.cpp
@@ -79,8 +79,7 @@ void AutomatonFactory::toStream(const AutomatonBase& automaton, std::ostream& ou
 }
 
 std::list<sax::Token> AutomatonFactory::compose(const AutomatonBase& automaton) {
-	AutomatonToXMLComposer composer;
-	return composer.compose(automaton);
+	return alib::ToXMLComposers::automatonComposer.compose(automaton);
 }
 
 } /* namespace automaton */
diff --git a/alib2/src/label/IntegerLabel.h b/alib2/src/label/IntegerLabel.h
index 6e41d55b81..e18da16d5c 100644
--- a/alib2/src/label/IntegerLabel.h
+++ b/alib2/src/label/IntegerLabel.h
@@ -17,7 +17,7 @@ namespace label {
 /**
  * Represents symbol in an alphabet.
  */
-class IntegerLabel : public LabelBase, public std::element<IntegerLabel, LabelBase::visitor_type>{
+class IntegerLabel : virtual public LabelBase, public std::element<IntegerLabel, LabelBase>{
 protected:
 	int label;
 public:
diff --git a/alib2/src/label/Label.h b/alib2/src/label/Label.h
index 8ad0a16128..608c440433 100644
--- a/alib2/src/label/Label.h
+++ b/alib2/src/label/Label.h
@@ -16,7 +16,7 @@ namespace label {
 /**
  * Wrapper around automata.
  */
-class Label : public std::element<Label, std::visitor<Label> > {
+class Label {
 protected:
 	LabelBase* label;
 public:
diff --git a/alib2/src/label/LabelBase.h b/alib2/src/label/LabelBase.h
index 0e7a04b15f..0944135707 100644
--- a/alib2/src/label/LabelBase.h
+++ b/alib2/src/label/LabelBase.h
@@ -9,6 +9,7 @@
 #define LABEL_BASE_H_
 
 #include "../std/visitor.hpp"
+#include <iostream>
 
 namespace label {
 
@@ -18,7 +19,7 @@ class IntegerLabel;
 /**
  * Abstract base class for all automata.
  */
-class LabelBase : virtual public std::elementBase<std::visitor<StringLabel, IntegerLabel> > {
+class LabelBase : public std::elementBase<StringLabel, IntegerLabel> {
 public:
 	virtual LabelBase* clone() const = 0;
 
diff --git a/alib2/src/label/LabelToStringComposer.h b/alib2/src/label/LabelToStringComposer.h
index 414885ee9d..4ca9954035 100644
--- a/alib2/src/label/LabelToStringComposer.h
+++ b/alib2/src/label/LabelToStringComposer.h
@@ -18,7 +18,7 @@ namespace label {
 /**
  * This class contains methods to print XML representation of string to the output stream.
  */
-class LabelToStringComposer : public Label::visitor_type, public LabelBase::visitor_type {
+class LabelToStringComposer : public LabelBase::visitor_type {
 	void Visit(void*, const Label& label);
 	void Visit(void*, const IntegerLabel& label);
 	void Visit(void*, const StringLabel& label);
diff --git a/alib2/src/label/LabelToXMLComposer.cpp b/alib2/src/label/LabelToXMLComposer.cpp
index be4d4bd141..229737171d 100644
--- a/alib2/src/label/LabelToXMLComposer.cpp
+++ b/alib2/src/label/LabelToXMLComposer.cpp
@@ -12,7 +12,7 @@
 
 namespace label {
 
-void LabelToXMLComposer::Visit(void* userData, const IntegerLabel& label) {
+void LabelToXMLComposer::Visit(void* userData, const IntegerLabel& label) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("IntegerLabel", sax::Token::START_ELEMENT));
@@ -20,7 +20,7 @@ void LabelToXMLComposer::Visit(void* userData, const IntegerLabel& label) {
 	out.push_back(sax::Token("IntegerLabel", sax::Token::END_ELEMENT));
 }
 
-void LabelToXMLComposer::Visit(void* userData, const StringLabel& label) {
+void LabelToXMLComposer::Visit(void* userData, const StringLabel& label) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("StringLabel", sax::Token::START_ELEMENT));
@@ -28,12 +28,12 @@ void LabelToXMLComposer::Visit(void* userData, const StringLabel& label) {
 	out.push_back(sax::Token("StringLabel", sax::Token::END_ELEMENT));
 }
 
-void LabelToXMLComposer::Visit(void* userData, const Label& label) {
+void LabelToXMLComposer::Visit(void* userData, const Label& label) const {
 	label.getLabel().Accept(userData, *this);
 
 }
 
-std::list<sax::Token> LabelToXMLComposer::compose(const Label& label) {
+std::list<sax::Token> LabelToXMLComposer::compose(const Label& label) const {
 	std::list<sax::Token> out;
 	Visit((void*) &out, label);
 	return out;
diff --git a/alib2/src/label/LabelToXMLComposer.h b/alib2/src/label/LabelToXMLComposer.h
index 4c86edeadb..740ce69108 100644
--- a/alib2/src/label/LabelToXMLComposer.h
+++ b/alib2/src/label/LabelToXMLComposer.h
@@ -17,10 +17,10 @@ namespace label {
 /**
  * This class contains methods to print XML representation of string to the output stream.
  */
-class LabelToXMLComposer : public Label::visitor_type, public LabelBase::visitor_type {
-	void Visit(void*, const Label& label);
-	void Visit(void*, const StringLabel& label);
-	void Visit(void*, const IntegerLabel& label);
+class LabelToXMLComposer : public LabelBase::const_visitor_type {
+	void Visit(void*, const Label& label) const;
+	void Visit(void*, const StringLabel& label) const;
+	void Visit(void*, const IntegerLabel& label) const;
 
 public:
 	/**
@@ -28,7 +28,7 @@ public:
 	 * @param string String to print
 	 * @param out output stream to which print the String
 	 */
-	std::list<sax::Token> compose(const Label& label);
+	std::list<sax::Token> compose(const Label& label) const;
 };
 
 } /* namespace label */
diff --git a/alib2/src/label/StringLabel.h b/alib2/src/label/StringLabel.h
index e1d14f17a1..925a79781f 100644
--- a/alib2/src/label/StringLabel.h
+++ b/alib2/src/label/StringLabel.h
@@ -18,7 +18,7 @@ namespace label {
 /**
  * Represents symbol in an alphabet.
  */
-class StringLabel : public LabelBase, public std::element<StringLabel, LabelBase::visitor_type>{
+class StringLabel : virtual public LabelBase, public std::element<StringLabel, LabelBase>{
 protected:
 	std::string label;
 public:
diff --git a/alib2/src/regexp/Alternation.h b/alib2/src/regexp/Alternation.h
index 8d6b1498c2..26fb5df538 100644
--- a/alib2/src/regexp/Alternation.h
+++ b/alib2/src/regexp/Alternation.h
@@ -17,7 +17,7 @@ namespace regexp {
  * Represents alternation operator in the regular expression. Contains list of RegExpElement
  * as operands of the operator.
  */
-class Alternation: public RegExpElement, public std::element<Alternation, RegExpElement::visitor_type> {
+class Alternation: virtual public RegExpElement, public std::element<Alternation, RegExpElement> {
 protected:
 	/**
 	 * @copydoc RegExpElement::clone() const
diff --git a/alib2/src/regexp/Concatenation.h b/alib2/src/regexp/Concatenation.h
index de3430d129..7aad061167 100644
--- a/alib2/src/regexp/Concatenation.h
+++ b/alib2/src/regexp/Concatenation.h
@@ -17,7 +17,7 @@ namespace regexp {
  * Represents concatenation operator in the regular expression. Contains list of RegExpElement
  * as operands of the operator.
  */
-class Concatenation: public RegExpElement, public std::element<Concatenation, RegExpElement::visitor_type> {
+class Concatenation: virtual public RegExpElement, public std::element<Concatenation, RegExpElement> {
 protected:
 	/**
 	 * @copydoc RegExpElement::clone() const
diff --git a/alib2/src/regexp/Iteration.h b/alib2/src/regexp/Iteration.h
index 18d226158c..fb3ef21d3f 100644
--- a/alib2/src/regexp/Iteration.h
+++ b/alib2/src/regexp/Iteration.h
@@ -17,7 +17,7 @@ namespace regexp {
  * Represents iteration operator in the regular expression. Contains one RegExpElement
  * as operand.
  */
-class Iteration: public RegExpElement, public std::element<Iteration, RegExpElement::visitor_type> {
+class Iteration: virtual public RegExpElement, public std::element<Iteration, RegExpElement> {
 protected:
 	RegExpElement* element;
 
diff --git a/alib2/src/regexp/RegExp.h b/alib2/src/regexp/RegExp.h
index f213e33c20..32b55891cc 100644
--- a/alib2/src/regexp/RegExp.h
+++ b/alib2/src/regexp/RegExp.h
@@ -23,7 +23,7 @@ class RegExpElement;
  * Represents regular expression parsed from the XML. Regular expression is stored
  * as a tree of RegExpElement.
  */
-class RegExp : public std::element<RegExp, std::visitor<RegExp> > {
+class RegExp {
 protected:
 	RegExpElement* regExp;
 	
diff --git a/alib2/src/regexp/RegExpElement.h b/alib2/src/regexp/RegExpElement.h
index 604e546e25..7aca59838f 100644
--- a/alib2/src/regexp/RegExpElement.h
+++ b/alib2/src/regexp/RegExpElement.h
@@ -27,7 +27,7 @@ class RegExpEpsilon;
 /**
  * Abstract class representing element in the regular expression. Can be operator or symbol.
  */
-class RegExpElement : virtual public std::elementBase<std::visitor<Alternation, Concatenation, Iteration, RegExpSymbol, RegExpEmpty, RegExpEpsilon> > {
+class RegExpElement : virtual public std::elementBase<Alternation, Concatenation, Iteration, RegExpSymbol, RegExpEmpty, RegExpEpsilon> {
 protected:
 	/* 
 	 * Parent regexp contanining this instance of RegExpElement
diff --git a/alib2/src/regexp/RegExpEmpty.h b/alib2/src/regexp/RegExpEmpty.h
index 64b28a08aa..bd5466f445 100644
--- a/alib2/src/regexp/RegExpEmpty.h
+++ b/alib2/src/regexp/RegExpEmpty.h
@@ -15,7 +15,7 @@ namespace regexp {
 /**
  * Represents empty regular expression in the regular expression.
  */
-class RegExpEmpty: public RegExpElement, public std::element<RegExpEmpty, RegExpElement::visitor_type> {
+class RegExpEmpty: virtual public RegExpElement, public std::element<RegExpEmpty, RegExpElement> {
 protected:
 	/**
 	 * @copydoc RegExpElement::clone() const
diff --git a/alib2/src/regexp/RegExpEpsilon.h b/alib2/src/regexp/RegExpEpsilon.h
index f36f3f25e4..bb4b7406a3 100644
--- a/alib2/src/regexp/RegExpEpsilon.h
+++ b/alib2/src/regexp/RegExpEpsilon.h
@@ -15,7 +15,7 @@ namespace regexp {
 /**
  * Represents epsilon in the regular expression.
  */
-class RegExpEpsilon: public RegExpElement, public std::element<RegExpEpsilon, RegExpElement::visitor_type> {
+class RegExpEpsilon: virtual public RegExpElement, public std::element<RegExpEpsilon, RegExpElement> {
 protected:
 	/**
 	 * @copydoc RegExpElement::clone() const
diff --git a/alib2/src/regexp/RegExpSymbol.h b/alib2/src/regexp/RegExpSymbol.h
index 8f8d25e8a7..b4c9e00d1f 100644
--- a/alib2/src/regexp/RegExpSymbol.h
+++ b/alib2/src/regexp/RegExpSymbol.h
@@ -17,7 +17,7 @@ namespace regexp {
 /**
  * Represents symbol in the regular expression. Contains name of the symbol.
  */
-class RegExpSymbol : public RegExpElement, public std::element<RegExpSymbol, RegExpElement::visitor_type> {
+class RegExpSymbol : virtual public RegExpElement, public std::element<RegExpSymbol, RegExpElement> {
 protected:
 	alphabet::Symbol symbol;
 
diff --git a/alib2/src/regexp/RegExpToStringComposer.cpp b/alib2/src/regexp/RegExpToStringComposer.cpp
index ac09f0a062..0e610d7548 100644
--- a/alib2/src/regexp/RegExpToStringComposer.cpp
+++ b/alib2/src/regexp/RegExpToStringComposer.cpp
@@ -12,11 +12,7 @@
 namespace regexp {
 
 void RegExpToStringComposer::Visit(void* userData, const RegExp& regexp) {
-	regexp.Accept(userData, *this);
-}
-
-void RegExpToStringComposer::Visit(void* userData, const RegExp::element_type& regexp) {
-	regexp.Accept(userData, *this);
+	regexp.getRegExp().Accept(userData, *this);
 }
 
 void RegExpToStringComposer::Visit(void* userData, const RegExpElement::element_type& element) {
diff --git a/alib2/src/regexp/RegExpToStringComposer.h b/alib2/src/regexp/RegExpToStringComposer.h
index e7e2ce39ad..4eba2a2d49 100644
--- a/alib2/src/regexp/RegExpToStringComposer.h
+++ b/alib2/src/regexp/RegExpToStringComposer.h
@@ -14,7 +14,7 @@
 
 namespace regexp {
 
-class RegExpToStringComposer : public RegExp::visitor_type, public RegExpElement::visitor_type {
+class RegExpToStringComposer : public RegExpElement::visitor_type {
 	void Visit(void*, const Alternation& alternation);
 	void Visit(void*, const Concatenation& concatenation);
 	void Visit(void*, const Iteration& iteration);
@@ -27,7 +27,6 @@ class RegExpToStringComposer : public RegExp::visitor_type, public RegExpElement
 	
 	void Visit(void*, const RegExp& empty);
 	
-	void Visit(void*, const RegExp::element_type& regexp);
 public:
 	/**
 	 * Composes string representation of RegExp.
diff --git a/alib2/src/regexp/RegExpToXMLComposer.cpp b/alib2/src/regexp/RegExpToXMLComposer.cpp
index adb9e53146..3f5245d364 100644
--- a/alib2/src/regexp/RegExpToXMLComposer.cpp
+++ b/alib2/src/regexp/RegExpToXMLComposer.cpp
@@ -9,7 +9,7 @@
 
 namespace regexp {
 
-void RegExpToXMLComposer::Visit(void* userData, const RegExp& regexp) {
+void RegExpToXMLComposer::Visit(void* userData, const RegExp& regexp) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("regexp", sax::Token::START_ELEMENT));
@@ -26,15 +26,11 @@ void RegExpToXMLComposer::Visit(void* userData, const RegExp& regexp) {
 	out.push_back(sax::Token("regexp", sax::Token::END_ELEMENT));
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const RegExp::element_type& regexp) {
-	regexp.Accept(userData, *this);
-}
-
-void RegExpToXMLComposer::Visit(void* userData, const RegExpElement::element_type& element) {
+void RegExpToXMLComposer::Visit(void* userData, const RegExpElement::element_type& element) const {
 	element.Accept(userData, *this);
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const Alternation& alternation) {
+void RegExpToXMLComposer::Visit(void* userData, const Alternation& alternation) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("alternation", sax::Token::START_ELEMENT));
@@ -45,7 +41,7 @@ void RegExpToXMLComposer::Visit(void* userData, const Alternation& alternation)
 	out.push_back(sax::Token("alternation", sax::Token::END_ELEMENT));
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const Concatenation& concatenation) {
+void RegExpToXMLComposer::Visit(void* userData, const Concatenation& concatenation) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("concatenation", sax::Token::START_ELEMENT));
@@ -57,7 +53,7 @@ void RegExpToXMLComposer::Visit(void* userData, const Concatenation& concatenati
 
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const Iteration& iteration) {
+void RegExpToXMLComposer::Visit(void* userData, const Iteration& iteration) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("iteration", sax::Token::START_ELEMENT));
@@ -66,7 +62,7 @@ void RegExpToXMLComposer::Visit(void* userData, const Iteration& iteration) {
 	out.push_back(sax::Token("iteration", sax::Token::END_ELEMENT));
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const RegExpSymbol& symbol) {
+void RegExpToXMLComposer::Visit(void* userData, const RegExpSymbol& symbol) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("symbol", sax::Token::START_ELEMENT));
@@ -74,23 +70,23 @@ void RegExpToXMLComposer::Visit(void* userData, const RegExpSymbol& symbol) {
 	out.push_back(sax::Token("symbol", sax::Token::END_ELEMENT));
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const RegExpEpsilon&) {
+void RegExpToXMLComposer::Visit(void* userData, const RegExpEpsilon&) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("epsilon", sax::Token::START_ELEMENT));
 	out.push_back(sax::Token("epsilon", sax::Token::END_ELEMENT));
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const RegExpEmpty&) {
+void RegExpToXMLComposer::Visit(void* userData, const RegExpEmpty&) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("empty", sax::Token::START_ELEMENT));
 	out.push_back(sax::Token("empty", sax::Token::END_ELEMENT));
 }
 
-std::list<sax::Token> RegExpToXMLComposer::compose(const RegExp& regexp) {
+std::list<sax::Token> RegExpToXMLComposer::compose(const RegExp& regexp) const {
 	std::list<sax::Token> out;
-	regexp.Accept((void*) &out, *this);
+	Visit((void*) &out, regexp);
 	return out;
 }
 
diff --git a/alib2/src/regexp/RegExpToXMLComposer.h b/alib2/src/regexp/RegExpToXMLComposer.h
index b6ed8cdc01..4a8de9cb3f 100644
--- a/alib2/src/regexp/RegExpToXMLComposer.h
+++ b/alib2/src/regexp/RegExpToXMLComposer.h
@@ -18,20 +18,18 @@ namespace regexp {
 /**
  * This class contains methods to print XML representation of regular expression to the output stream.
  */
-class RegExpToXMLComposer : public RegExp::visitor_type, public RegExpElement::visitor_type {
-	void Visit(void*, const Alternation& alternation);
-	void Visit(void*, const Concatenation& concatenation);
-	void Visit(void*, const Iteration& iteration);
-	void Visit(void*, const RegExpSymbol& symbol);
-	void Visit(void*, const RegExpEpsilon& epsilon);
-	void Visit(void*, const RegExpEmpty& empty);
+class RegExpToXMLComposer : public RegExpElement::const_visitor_type {
+	void Visit(void*, const Alternation& alternation) const;
+	void Visit(void*, const Concatenation& concatenation) const;
+	void Visit(void*, const Iteration& iteration) const;
+	void Visit(void*, const RegExpSymbol& symbol) const;
+	void Visit(void*, const RegExpEpsilon& epsilon) const;
+	void Visit(void*, const RegExpEmpty& empty) const;
 	
-	void Visit(void*, const RegExpElement::element_type& element);
+	void Visit(void*, const RegExpElement::element_type& element) const;
 	
 	
-	void Visit(void*, const RegExp& empty);
-	
-	void Visit(void*, const RegExp::element_type& regexp);
+	void Visit(void*, const RegExp& empty) const;
 
 public:
 	/**
@@ -39,7 +37,7 @@ public:
 	 * @param regexp RegExp to print
 	 * @returns list of xml tokens.
 	 */
-	std::list<sax::Token> compose(const RegExp& regexp);
+	std::list<sax::Token> compose(const RegExp& regexp) const;
 };
 
 } /* namespace regexp */
diff --git a/alib2/src/std/visitor.hpp b/alib2/src/std/visitor.hpp
index e2efd9813a..ded39b2bdc 100644
--- a/alib2/src/std/visitor.hpp
+++ b/alib2/src/std/visitor.hpp
@@ -9,15 +9,13 @@
 #ifndef VISITOR_H_
 #define VISITOR_H_
 
-#include <tuple>
-
 namespace std {
 
 // Visitor template declaration
 template<typename... Types>
 class visitor;
 
-// specialization for single type    
+// specialization for single type
 template<typename T>
 class visitor<T> {
 public:
@@ -34,23 +32,49 @@ public:
     virtual void Visit(void* userData, const T & visitable) = 0;
 };
 
-template<typename VisitorType>
+// Visitor template declaration
+template<typename... Types>
+class const_visitor;
+
+// specialization for single type
+template<typename T>
+class const_visitor<T> {
+public:
+    virtual void Visit(void* userData, const T & visitable) const = 0;
+};
+
+// specialization for multiple types
+template<typename T, typename... Types>
+class const_visitor<T, Types...> : public const_visitor<Types...> {
+public:
+    // promote the function(s) from the base class
+    using const_visitor<Types...>::Visit;
+
+    virtual void Visit(void* userData, const T & visitable) const = 0;
+};
+
+template<typename... Types>
 class elementBase {
 public:
-    typedef VisitorType visitor_type;
+    typedef visitor<Types...> visitor_type;
+    typedef const_visitor<Types...> const_visitor_type;
     typedef elementBase element_type;
 
-    virtual void Accept(void* userData, VisitorType& visitor) const = 0;
+    virtual void Accept(void* userData, visitor<Types...>& visitor) const = 0;
+    virtual void Accept(void* userData, const const_visitor<Types...>& visitor) const = 0;
 };
 
-template<typename Derived, typename VisitorType>
-class element : virtual public elementBase<VisitorType> {
+template<typename Derived, typename Base>
+class element : virtual public Base {
 public:
-    virtual void Accept(void* userData, VisitorType& visitor) const {
+    virtual void Accept(void* userData, typename Base::visitor_type& visitor) const {
+        visitor.Visit(userData, static_cast<const Derived&>(*this));
+    }
+    virtual void Accept(void* userData, const typename Base::const_visitor_type& visitor) const {
         visitor.Visit(userData, static_cast<const Derived&>(*this));
     }
 };
 
 } /* namespace std */
 
-#endif /* VISITOR_H_ */
\ No newline at end of file
+#endif /* VISITOR_H_ */
diff --git a/alib2/src/string/CyclicString.h b/alib2/src/string/CyclicString.h
index 2137aaaf76..2444eaa70e 100644
--- a/alib2/src/string/CyclicString.h
+++ b/alib2/src/string/CyclicString.h
@@ -22,7 +22,7 @@ namespace string {
  * Represents regular expression parsed from the XML. Regular expression is stored
  * as a tree of CyclicStringElement.
  */
-class CyclicString : public StringBase, public std::element<CyclicString, StringBase::visitor_type> {
+class CyclicString : virtual public StringBase, public std::element<CyclicString, StringBase> {
 protected:
 	std::vector<alphabet::Symbol> m_Data;
 
diff --git a/alib2/src/string/Epsilon.h b/alib2/src/string/Epsilon.h
index 7fba33014f..2d42d13dbb 100644
--- a/alib2/src/string/Epsilon.h
+++ b/alib2/src/string/Epsilon.h
@@ -22,7 +22,7 @@ namespace string {
  * Represents epsilon. Regular expression is stored
  * as a tree of EpsilonElement.
  */
-class Epsilon : public StringBase, public std::element<Epsilon, StringBase::visitor_type> {
+class Epsilon : virtual public StringBase, public std::element<Epsilon, StringBase> {
 protected:
 
 	virtual bool testSymbol( const alphabet::Symbol & symbol ) const;
diff --git a/alib2/src/string/LinearString.h b/alib2/src/string/LinearString.h
index a3969c2d35..4fb4b0ffdc 100644
--- a/alib2/src/string/LinearString.h
+++ b/alib2/src/string/LinearString.h
@@ -22,7 +22,7 @@ namespace string {
  * Represents regular expression parsed from the XML. Regular expression is stored
  * as a tree of LinearStringElement.
  */
-class LinearString : public StringBase, public std::element<LinearString, StringBase::visitor_type> {
+class LinearString : virtual public StringBase, public std::element<LinearString, StringBase> {
 protected:
 	std::vector<alphabet::Symbol> m_Data;
 
diff --git a/alib2/src/string/String.h b/alib2/src/string/String.h
index b50a54acdd..668f1994f6 100644
--- a/alib2/src/string/String.h
+++ b/alib2/src/string/String.h
@@ -20,7 +20,7 @@ class StringBase;
 /**
  * Wrapper around strings.
  */
-class String : public std::element<String, std::visitor<String> > {
+class String {
 protected:
 	StringBase* string;
 	std::set<alphabet::Symbol> alphabet;
diff --git a/alib2/src/string/StringBase.h b/alib2/src/string/StringBase.h
index 5d299f5a36..45885a3891 100644
--- a/alib2/src/string/StringBase.h
+++ b/alib2/src/string/StringBase.h
@@ -25,7 +25,7 @@ class Epsilon;
 /**
  * Represents string in an alphabet.
  */
-class StringBase : virtual public std::elementBase<std::visitor<Epsilon, LinearString, CyclicString> > {
+class StringBase : virtual public std::elementBase<Epsilon, LinearString, CyclicString> {
 protected:
 	const String* parentString;
 
diff --git a/alib2/src/string/StringToStringComposer.h b/alib2/src/string/StringToStringComposer.h
index c2375c125f..223b221d11 100644
--- a/alib2/src/string/StringToStringComposer.h
+++ b/alib2/src/string/StringToStringComposer.h
@@ -18,7 +18,7 @@ namespace string {
 /**
  * This class contains methods to print XML representation of string to the output stream.
  */
-class StringToStringComposer : public String::visitor_type, public StringBase::visitor_type {
+class StringToStringComposer : public StringBase::visitor_type {
 	void Visit(void*, const alphabet::Symbol& symbol);
 	void Visit(void*, const String& string);
 	void Visit(void*, const LinearString& string);
diff --git a/alib2/src/string/StringToXMLComposer.cpp b/alib2/src/string/StringToXMLComposer.cpp
index e37cebd0f2..480825fb05 100644
--- a/alib2/src/string/StringToXMLComposer.cpp
+++ b/alib2/src/string/StringToXMLComposer.cpp
@@ -12,7 +12,7 @@
 
 namespace string {
 
-void StringToXMLComposer::Visit(void* userData, const alphabet::Symbol& symbol) {
+void StringToXMLComposer::Visit(void* userData, const alphabet::Symbol& symbol) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("symbol", sax::Token::START_ELEMENT));
@@ -20,14 +20,14 @@ void StringToXMLComposer::Visit(void* userData, const alphabet::Symbol& symbol)
 	out.push_back(sax::Token("symbol", sax::Token::END_ELEMENT));
 }
 
-void StringToXMLComposer::Visit(void* userData, const Epsilon&) {
+void StringToXMLComposer::Visit(void* userData, const Epsilon&) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("Epsilon", sax::Token::START_ELEMENT));
 	out.push_back(sax::Token("Epsilon", sax::Token::END_ELEMENT));
 }
 
-void StringToXMLComposer::Visit(void* userData, const CyclicString& string) {
+void StringToXMLComposer::Visit(void* userData, const CyclicString& string) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("CyclicString", sax::Token::START_ELEMENT));
@@ -37,7 +37,7 @@ void StringToXMLComposer::Visit(void* userData, const CyclicString& string) {
 	out.push_back(sax::Token("CyclicString", sax::Token::END_ELEMENT));
 }
 
-void StringToXMLComposer::Visit(void* userData, const LinearString& string) {
+void StringToXMLComposer::Visit(void* userData, const LinearString& string) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("LinearString", sax::Token::START_ELEMENT));
@@ -47,12 +47,12 @@ void StringToXMLComposer::Visit(void* userData, const LinearString& string) {
 	out.push_back(sax::Token("LinearString", sax::Token::END_ELEMENT));
 }
 
-void StringToXMLComposer::Visit(void* userData, const String& string) {
+void StringToXMLComposer::Visit(void* userData, const String& string) const {
 	string.getString().Accept(userData, *this);
 
 }
 
-std::list<sax::Token> StringToXMLComposer::compose(const String& string) {
+std::list<sax::Token> StringToXMLComposer::compose(const String& string) const {
 	std::list<sax::Token> out;
 	Visit((void*) &out, string);
 	return out;
diff --git a/alib2/src/string/StringToXMLComposer.h b/alib2/src/string/StringToXMLComposer.h
index e8b245c4cd..548c3467e8 100644
--- a/alib2/src/string/StringToXMLComposer.h
+++ b/alib2/src/string/StringToXMLComposer.h
@@ -18,12 +18,12 @@ namespace string {
 /**
  * This class contains methods to print XML representation of string to the output stream.
  */
-class StringToXMLComposer : public String::visitor_type, public StringBase::visitor_type {
-	void Visit(void*, const alphabet::Symbol& symbol);
-	void Visit(void*, const String& string);
-	void Visit(void*, const LinearString& string);
-	void Visit(void*, const CyclicString& string);
-	void Visit(void*, const Epsilon& string);
+class StringToXMLComposer : public StringBase::const_visitor_type {
+	void Visit(void*, const alphabet::Symbol& symbol) const;
+	void Visit(void*, const String& string) const;
+	void Visit(void*, const LinearString& string) const;
+	void Visit(void*, const CyclicString& string) const;
+	void Visit(void*, const Epsilon& string) const;
 
 public:
 	/**
@@ -31,7 +31,7 @@ public:
 	 * @param string String to print
 	 * @param out output stream to which print the String
 	 */
-	std::list<sax::Token> compose(const String& string);
+	std::list<sax::Token> compose(const String& string) const;
 };
 
 } /* namespace string */
-- 
GitLab