From 9d2f8aff96afca9f85672daf5a1bea32b67254dc Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sun, 10 Aug 2014 11:53:56 +0200
Subject: [PATCH] introduction common string data

---
 alib2data/src/string/CyclicString.cpp         | 31 +++-------
 alib2data/src/string/CyclicString.h           |  9 +--
 alib2data/src/string/Epsilon.cpp              | 12 ----
 alib2data/src/string/Epsilon.h                |  9 +--
 alib2data/src/string/LinearString.cpp         | 31 +++-------
 alib2data/src/string/LinearString.h           |  9 +--
 alib2data/src/string/StringBase.h             |  2 +-
 .../src/string/common/StringAlphabet.cpp      | 39 +++++++++++++
 alib2data/src/string/common/StringAlphabet.h  | 56 +++++++++++++++++++
 9 files changed, 121 insertions(+), 77 deletions(-)
 create mode 100644 alib2data/src/string/common/StringAlphabet.cpp
 create mode 100644 alib2data/src/string/common/StringAlphabet.h

diff --git a/alib2data/src/string/CyclicString.cpp b/alib2data/src/string/CyclicString.cpp
index d0782928de..aeb46026b3 100644
--- a/alib2data/src/string/CyclicString.cpp
+++ b/alib2data/src/string/CyclicString.cpp
@@ -21,19 +21,23 @@ CyclicString::CyclicString() {
 
 }
 
-CyclicString::CyclicString(const std::set<alphabet::Symbol>& alphabet, const std::vector<alphabet::Symbol>& data) : alphabet(alphabet) {
+CyclicString::CyclicString(const std::set<alphabet::Symbol>& alphabet, const std::vector<alphabet::Symbol>& data) {
+	this->alphabet = alphabet;
 	setContent(data);
 }
 
-CyclicString::CyclicString(std::set<alphabet::Symbol>&& alphabet, std::vector<alphabet::Symbol>&& data) : alphabet(std::move(alphabet)) {
+CyclicString::CyclicString(std::set<alphabet::Symbol>&& alphabet, std::vector<alphabet::Symbol>&& data) {
+	this->alphabet = std::move(alphabet);
 	setContent(std::move(data));
 }
 
-CyclicString::CyclicString(const std::vector<alphabet::Symbol>& data) : alphabet(data.begin(), data.end()) {
+CyclicString::CyclicString(const std::vector<alphabet::Symbol>& data) {
+	alphabet = std::set<alphabet::Symbol>(data.begin(), data.end());
 	m_Data = data;
 }
 
-CyclicString::CyclicString(std::vector<alphabet::Symbol>&& data) : alphabet(data.begin(), data.end()) {
+CyclicString::CyclicString(std::vector<alphabet::Symbol>&& data) {
+	alphabet = std::set<alphabet::Symbol>(data.begin(), data.end());
 	m_Data = std::move(data);
 }
 
@@ -45,25 +49,6 @@ StringBase* CyclicString::plunder() && {
 	return new CyclicString(std::move(*this));
 }
 
-const std::set<alphabet::Symbol>& CyclicString::getAlphabet() const {
-	return alphabet;
-}
-
-bool CyclicString::addSymbolToAlphabet(const alphabet::Symbol & symbol) {
-	return alphabet.insert(symbol).second;
-}
-
-void CyclicString::setAlphabet(const std::set<alphabet::Symbol> & symbols) {
-	std::set<alphabet::Symbol> minimalAlphabet(m_Data.begin(), m_Data.end());
-	std::set<alphabet::Symbol> removedSymbols;
-	std::set_difference(minimalAlphabet.begin(), minimalAlphabet.end(), symbols.begin(), symbols.end(), std::inserter(removedSymbols, removedSymbols.end()));
-
-	if(removedSymbols.size() > 0)
-		throw exception::AlibException("Input symbols are used.");
-
-	this->alphabet = symbols;
-}
-
 bool CyclicString::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) {
 	if(std::any_of(m_Data.begin(), m_Data.end(), [&](const alphabet::Symbol & s) { return s == symbol; } ) )
 		throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" is used.");
diff --git a/alib2data/src/string/CyclicString.h b/alib2data/src/string/CyclicString.h
index 0bc8247f66..8038079534 100644
--- a/alib2data/src/string/CyclicString.h
+++ b/alib2data/src/string/CyclicString.h
@@ -15,6 +15,7 @@
 #include "../std/visitor.hpp"
 #include "../alphabet/Symbol.h"
 #include "StringBase.h"
+#include "common/StringAlphabet.h"
 
 namespace string {
 
@@ -22,8 +23,7 @@ namespace string {
  * Represents regular expression parsed from the XML. Regular expression is stored
  * as a tree of CyclicStringElement.
  */
-class CyclicString : public std::element<CyclicString, StringBase> {
-	std::set<alphabet::Symbol> alphabet;
+class CyclicString : public std::element<CyclicString, StringBase>, public StringAlphabet {
 	std::vector<alphabet::Symbol> m_Data;
 public:
 	CyclicString();
@@ -35,10 +35,7 @@ public:
 	virtual StringBase* clone() const;
 	virtual StringBase* plunder() &&;
 
-	const std::set<alphabet::Symbol>& getAlphabet() const;
-	bool addSymbolToAlphabet(const alphabet::Symbol & symbol);
-	void setAlphabet(const std::set<alphabet::Symbol>& alphabet);
-	bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol);
+	virtual bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol);
 
 	virtual bool operator <(const StringBase& other) const;
 	virtual bool operator ==(const StringBase& other) const;
diff --git a/alib2data/src/string/Epsilon.cpp b/alib2data/src/string/Epsilon.cpp
index a1f1672ef0..5c27657ada 100644
--- a/alib2data/src/string/Epsilon.cpp
+++ b/alib2data/src/string/Epsilon.cpp
@@ -26,18 +26,6 @@ StringBase* Epsilon::plunder() && {
 	return new Epsilon(std::move(*this));
 }
 
-const std::set<alphabet::Symbol>& Epsilon::getAlphabet() const {
-	return alphabet;
-}
-
-bool Epsilon::addSymbolToAlphabet(const alphabet::Symbol & symbol) {
-	return alphabet.insert(symbol).second;
-}
-
-void Epsilon::setAlphabet(const std::set<alphabet::Symbol> & symbols) {
-	this->alphabet = symbols;
-}
-
 bool Epsilon::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) {
 	return alphabet.erase(symbol);
 }
diff --git a/alib2data/src/string/Epsilon.h b/alib2data/src/string/Epsilon.h
index f7d2f467e0..680355fe0d 100644
--- a/alib2data/src/string/Epsilon.h
+++ b/alib2data/src/string/Epsilon.h
@@ -15,6 +15,7 @@
 #include "../std/visitor.hpp"
 #include "../alphabet/Symbol.h"
 #include "StringBase.h"
+#include "common/StringAlphabet.h"
 
 namespace string {
 
@@ -22,18 +23,14 @@ namespace string {
  * Represents epsilon. Regular expression is stored
  * as a tree of EpsilonElement.
  */
-class Epsilon : public std::element<Epsilon, StringBase> {
-	std::set<alphabet::Symbol> alphabet;
+class Epsilon : public std::element<Epsilon, StringBase>, public StringAlphabet {
 public:
 	Epsilon();
 
 	virtual StringBase* clone() const;
 	virtual StringBase* plunder() &&;
 
-	const std::set<alphabet::Symbol>& getAlphabet() const;
-	bool addSymbolToAlphabet(const alphabet::Symbol & symbol);
-	void setAlphabet(const std::set<alphabet::Symbol>& alphabet);
-	bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol);
+	virtual bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol);
 
 	virtual bool operator <(const StringBase& other) const;
 	virtual bool operator ==(const StringBase& other) const;
diff --git a/alib2data/src/string/LinearString.cpp b/alib2data/src/string/LinearString.cpp
index 3a10cec683..c9390c15b6 100644
--- a/alib2data/src/string/LinearString.cpp
+++ b/alib2data/src/string/LinearString.cpp
@@ -21,19 +21,23 @@ LinearString::LinearString() {
 
 }
 
-LinearString::LinearString(const std::set<alphabet::Symbol>& alphabet, const std::vector<alphabet::Symbol>& data) : alphabet(alphabet) {
+LinearString::LinearString(const std::set<alphabet::Symbol>& alphabet, const std::vector<alphabet::Symbol>& data) {
+	this->alphabet = alphabet;
 	setContent(data);
 }
 
-LinearString::LinearString(std::set<alphabet::Symbol>&& alphabet, std::vector<alphabet::Symbol>&& data) : alphabet(std::move(alphabet)) {
+LinearString::LinearString(std::set<alphabet::Symbol>&& alphabet, std::vector<alphabet::Symbol>&& data) {
+	this->alphabet = std::move(alphabet);
 	setContent(std::move(data));
 }
 
-LinearString::LinearString(const std::vector<alphabet::Symbol>& data) : alphabet(data.begin(), data.end()) {
+LinearString::LinearString(const std::vector<alphabet::Symbol>& data) {
+	alphabet = std::set<alphabet::Symbol>(data.begin(), data.end());
 	m_Data = data;
 }
 
-LinearString::LinearString(std::vector<alphabet::Symbol>&& data) : alphabet(data.begin(), data.end()) {
+LinearString::LinearString(std::vector<alphabet::Symbol>&& data) {
+	alphabet = std::set<alphabet::Symbol>(data.begin(), data.end());
 	m_Data = std::move(data);
 }
 
@@ -45,25 +49,6 @@ StringBase* LinearString::plunder() && {
 	return new LinearString(std::move(*this));
 }
 
-const std::set<alphabet::Symbol>& LinearString::getAlphabet() const {
-	return alphabet;
-}
-
-bool LinearString::addSymbolToAlphabet(const alphabet::Symbol & symbol) {
-	return alphabet.insert(symbol).second;
-}
-
-void LinearString::setAlphabet(const std::set<alphabet::Symbol> & symbols) {
-	std::set<alphabet::Symbol> minimalAlphabet(m_Data.begin(), m_Data.end());
-	std::set<alphabet::Symbol> removedSymbols;
-	std::set_difference(minimalAlphabet.begin(), minimalAlphabet.end(), symbols.begin(), symbols.end(), std::inserter(removedSymbols, removedSymbols.end()));
-
-	if(removedSymbols.size() > 0)
-		throw exception::AlibException("Input symbols are used.");
-
-	this->alphabet = symbols;
-}
-
 bool LinearString::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) {
 	if(std::any_of(m_Data.begin(), m_Data.end(), [&](const alphabet::Symbol & s) { return s == symbol; } ) )
 		throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" is used.");
diff --git a/alib2data/src/string/LinearString.h b/alib2data/src/string/LinearString.h
index 89b33a2f3d..eb3c2f9e8e 100644
--- a/alib2data/src/string/LinearString.h
+++ b/alib2data/src/string/LinearString.h
@@ -15,6 +15,7 @@
 #include "../std/visitor.hpp"
 #include "../alphabet/Symbol.h"
 #include "StringBase.h"
+#include "common/StringAlphabet.h"
 
 namespace string {
 
@@ -22,8 +23,7 @@ namespace string {
  * Represents regular expression parsed from the XML. Regular expression is stored
  * as a tree of LinearStringElement.
  */
-class LinearString : public std::element<LinearString, StringBase> {
-	std::set<alphabet::Symbol> alphabet;
+class LinearString : public std::element<LinearString, StringBase>, public StringAlphabet {
 	std::vector<alphabet::Symbol> m_Data;
 
 public:
@@ -36,10 +36,7 @@ public:
 	virtual StringBase* clone() const;
 	virtual StringBase* plunder() &&;
 
-	const std::set<alphabet::Symbol>& getAlphabet() const;
-	bool addSymbolToAlphabet(const alphabet::Symbol & symbol);
-	void setAlphabet(const std::set<alphabet::Symbol>& alphabet);
-	bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol);
+	virtual bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol);
 
 	/**
 	 * @param element to append
diff --git a/alib2data/src/string/StringBase.h b/alib2data/src/string/StringBase.h
index fc8edb5e45..d69637fa06 100644
--- a/alib2data/src/string/StringBase.h
+++ b/alib2data/src/string/StringBase.h
@@ -34,7 +34,7 @@ public:
 
 	bool operator<=(const StringBase& other) const;
 
-	bool operator !=(const StringBase& other) const;
+	bool operator!=(const StringBase& other) const;
 
 	virtual bool operator==(const StringBase& other) const = 0;
 	virtual bool operator==(const LinearString& other) const = 0;
diff --git a/alib2data/src/string/common/StringAlphabet.cpp b/alib2data/src/string/common/StringAlphabet.cpp
new file mode 100644
index 0000000000..4b81ba221b
--- /dev/null
+++ b/alib2data/src/string/common/StringAlphabet.cpp
@@ -0,0 +1,39 @@
+/*
+ * InputAlphabet.cpp
+ *
+ *  Created on: Apr 16, 2013
+ *      Author: Jan Travnicek
+ */
+
+#include "StringAlphabet.h"
+
+#include <algorithm>
+
+namespace string {
+
+const std::set<alphabet::Symbol>& StringAlphabet::getAlphabet() const {
+	return alphabet;
+}
+
+bool StringAlphabet::addSymbolToAlphabet(const alphabet::Symbol& symbol) {
+	return alphabet.insert(symbol).second;
+}
+
+void StringAlphabet::setAlphabet(const std::set<alphabet::Symbol>& newSymbols) {
+	std::set<alphabet::Symbol> removed;
+	std::set_difference(alphabet.begin(), alphabet.end(), newSymbols.begin(), newSymbols.end(), std::inserter(removed, removed.end()));
+
+	std::set<alphabet::Symbol> added;
+	std::set_difference(newSymbols.begin(), newSymbols.end(), alphabet.begin(), alphabet.end(), std::inserter(added, added.end()));
+	
+	for(const alphabet::Symbol& removedSymbol : removed) {
+		removeSymbolFromAlphabet(removedSymbol);
+	}
+
+	for(const alphabet::Symbol& addedSymbol : added) {
+		addSymbolToAlphabet(addedSymbol);
+	}
+}
+
+} /* namespace string */
+
diff --git a/alib2data/src/string/common/StringAlphabet.h b/alib2data/src/string/common/StringAlphabet.h
new file mode 100644
index 0000000000..a4c0365d65
--- /dev/null
+++ b/alib2data/src/string/common/StringAlphabet.h
@@ -0,0 +1,56 @@
+/*
+ * Alphabet.h
+ *
+ *  Created on: Apr 10, 2013
+ *      Author: Jan Travnicek
+ */
+
+#ifndef STRING_ALPHABET_H_
+#define STRING_ALPHABET_H_
+
+#include <set>
+#include "../../alphabet/Symbol.h"
+
+
+namespace string {
+
+/**
+ * Abstract base class for all strings. Contains common elements of strings.
+ */
+class StringAlphabet {
+protected:
+	std::set<alphabet::Symbol> alphabet;
+public:
+	/**
+	 * Adds input symbol to input alphabet.
+	 * @param symbol Symbol to add
+	 * @throws AutomatonException when symbol already exists
+	 */
+	bool addSymbolToAlphabet(const alphabet::Symbol& symbol);
+
+	/**
+	 * Sets input symbols of the string.
+	 * @param symbols Symbols to set
+	 * @throws AutomatonException when symbol already exists
+	 */
+	void setAlphabet(const std::set<alphabet::Symbol>& symbols);
+
+	/**
+	 * Removes input symbol from the input alphabet.
+	 * @param symbol Symbol to remove
+	 * @throws AutomatonException when symbol is not present in input alphabet
+	 * or when symbol is part of the transition
+	 */
+	virtual bool removeSymbolFromAlphabet(const alphabet::Symbol& symbol) = 0;
+
+	/**
+	 * @return the input alphabet
+	 */
+	const std::set<alphabet::Symbol>& getAlphabet() const;
+
+};
+
+} /* namespace string */
+
+#endif /* STRING_ALPHABET_H_ */
+
-- 
GitLab