/* * LinearString.cpp * * Created on: Nov 23, 2013 * Author: Jan Travnicek */ #include "LinearString.h" #include "../exception/AlibException.h" #include <cassert> #include <sstream> #include <algorithm> #include <typeinfo> #include "CyclicString.h" #include "Epsilon.h" namespace string { LinearString::LinearString() { } 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) { this->alphabet = std::move(alphabet); setContent(std::move(data)); } 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 = std::set<alphabet::Symbol>(data.begin(), data.end()); m_Data = std::move(data); } StringBase* LinearString::clone() const { return new LinearString(*this); } StringBase* LinearString::plunder() && { return new LinearString(std::move(*this)); } 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."); return alphabet.erase(symbol); } void LinearString::appendSymbol(const alphabet::Symbol& symbol) { if(alphabet.count(symbol) == 0) throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" not in the alphabet."); m_Data.push_back(symbol); } void LinearString::appendSymbol(alphabet::Symbol&& symbol) { if(alphabet.count(symbol) == 0) throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" not in the alphabet."); m_Data.push_back(std::move(symbol)); } bool LinearString::operator<(const StringBase& other) const { return other > *this; } bool LinearString::operator ==(const StringBase& other) const { return other == *this; } bool LinearString::operator >(const StringBase& other) const { return other < *this; } const std::vector<alphabet::Symbol>& LinearString::getContent() const { return this->m_Data; } void LinearString::setContent(std::vector<alphabet::Symbol> data) { std::set<alphabet::Symbol> minimalAlphabet(data.begin(), data.end()); std::set<alphabet::Symbol> unknownSymbols; std::set_difference(minimalAlphabet.begin(), minimalAlphabet.end(), alphabet.begin(), alphabet.end(), std::inserter(unknownSymbols, unknownSymbols.end())); if(unknownSymbols.size() > 0) throw exception::AlibException("Input symbols not in the alphabet."); this->m_Data = std::move(data); } bool LinearString::isEmpty() const { return this->m_Data.size() == 0; } bool LinearString::operator<(const LinearString& other) const { return std::tie(m_Data, alphabet) < std::tie(other.m_Data, other.alphabet); } bool LinearString::operator<(const CyclicString& other) const { if(this->isEmpty() && other.isEmpty()) return alphabet < other.getAlphabet(); return typeid(*this).before(typeid(other)); } bool LinearString::operator<(const Epsilon& other) const { if(this->isEmpty()) return alphabet < other.getAlphabet(); return typeid(*this).before(typeid(other)); } bool LinearString::operator==(const LinearString& other) const { return m_Data == other.m_Data && alphabet == other.getAlphabet(); } bool LinearString::operator==(const CyclicString& other) const { if(this->isEmpty() && other.isEmpty()) return alphabet == other.getAlphabet(); return false; } bool LinearString::operator==(const Epsilon& other) const { if(this->isEmpty()) return alphabet == other.getAlphabet(); return false; } void LinearString::operator >>(std::ostream& out) const { if( this->isEmpty() ) { out << "(Epsilon)"; } else { out << "(LinearString "; for(const alphabet::Symbol& symbol : this->m_Data) out << symbol; out << ")"; } } LinearString::operator std::string () const { std::stringstream ss; if( this->isEmpty() ) { ss << "E"; } else { ss << "\""; for(const alphabet::Symbol& symbol : this->m_Data) ss << (std::string) symbol; ss << "\""; } return std::move(ss).str(); } } /* namespace string */