/* * CyclicString.cpp * * Created on: Nov 23, 2013 * Author: Jan Travnicek */ #include "CyclicString.h" #include "../exception/AlibException.h" #include <cassert> #include <sstream> #include <algorithm> #include <typeinfo> #include "LinearString.h" #include "Epsilon.h" namespace string { CyclicString::CyclicString() { } 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) { this->alphabet = std::move(alphabet); setContent(std::move(data)); } CyclicString::CyclicString(const std::vector<alphabet::Symbol>& data) { alphabet = std::set<alphabet::Symbol>(data.begin(), data.end()); setContent(std::move(data)); } CyclicString::CyclicString(std::vector<alphabet::Symbol>&& data) { alphabet = std::set<alphabet::Symbol>(data.begin(), data.end()); setContent(std::move(data)); } StringBase* CyclicString::clone() const { return new CyclicString(*this); } StringBase* CyclicString::plunder() && { return new CyclicString(std::move(*this)); } 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."); return alphabet.erase(symbol); } bool CyclicString::operator <(const StringBase& other) const { return other > *this; } bool CyclicString::operator ==(const StringBase& other) const { return other == *this; } bool CyclicString::operator >(const StringBase& other) const { return other < *this; } const std::vector<alphabet::Symbol>& CyclicString::getContent() const { return this->m_Data; } //serves as both move and copy content setter void CyclicString::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."); m_Data = data; for(unsigned i = 1; i < data.size(); i++) { data.push_back(std::move(data[0])); data.erase(data.begin()); if(m_Data > data) m_Data = data; } } bool CyclicString::isEmpty() const { return this->m_Data.size() == 0; } bool CyclicString::operator<(const LinearString& other) const { if(this->isEmpty() && other.isEmpty()) return alphabet < other.getAlphabet(); return typeid(*this).before(typeid(other)); } bool CyclicString::operator<(const CyclicString& other) const { return std::tie(m_Data, alphabet) < std::tie(other.m_Data, other.alphabet); } bool CyclicString::operator<(const Epsilon& other) const { if(this->isEmpty()) return alphabet < other.getAlphabet(); return typeid(*this).before(typeid(other)); } bool CyclicString::operator==(const LinearString& other) const { if(this->isEmpty() && other.isEmpty()) return alphabet == other.getAlphabet(); return false; } bool CyclicString::operator==(const CyclicString& other) const { return m_Data == other.m_Data && alphabet == other.getAlphabet(); } bool CyclicString::operator==(const Epsilon& other) const { if(this->isEmpty()) return alphabet == other.getAlphabet(); return false; } void CyclicString::operator >>(std::ostream& out) const { if( this->isEmpty() ) { out << "(Epsilon)"; } else { out << "(CyclicString "; for(const alphabet::Symbol& symbol : this->m_Data) out << symbol; out << ")"; } } CyclicString::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 */