Newer
Older
/*
* CyclicString.cpp
*
* Created on: Nov 23, 2013
* Author: Jan Travnicek
*/
#include "CyclicString.h"
#include "../exception/AlibException.h"
#include <cassert>
#include <sstream>
#include <algorithm>
#include "LinearString.h"
#include "Epsilon.h"
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());
CyclicString::CyclicString(std::vector<alphabet::Symbol>&& data) {
alphabet = std::set<alphabet::Symbol>(data.begin(), data.end());
}
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();