Skip to content
Snippets Groups Projects
LinearString.cpp 4.24 KiB
Newer Older
  • Learn to ignore specific revisions
  • Jan Trávníček's avatar
    Jan Trávníček committed
    /*
     * LinearString.cpp
     *
     *  Created on: Nov 23, 2013
     *      Author: Jan Travnicek
     */
    
    #include "LinearString.h"
    
    #include "../exception/AlibException.h"
    
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    #include <cassert>
    #include <sstream>
    #include <algorithm>
    
    Tomáš Pecka's avatar
    Tomáš Pecka committed
    #include <typeinfo>
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    
    
    #include "CyclicString.h"
    #include "Epsilon.h"
    
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    namespace string {
    
    
    LinearString::LinearString() {
    
    LinearString::LinearString(const std::set<alphabet::Symbol>& alphabet, const std::vector<alphabet::Symbol>& data) {
    	this->alphabet = 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 = std::set<alphabet::Symbol>(data.begin(), data.end());
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    }
    
    
    LinearString::LinearString(std::vector<alphabet::Symbol>&& data) {
    	alphabet = std::set<alphabet::Symbol>(data.begin(), data.end());
    
    	m_Data = std::move(data);
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    }
    
    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));
    }
    
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    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);
    }
    
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    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));
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    }
    
    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();
    
    bool LinearString::operator==(const Epsilon& other) const {
    	if(this->isEmpty()) return alphabet == other.getAlphabet();
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    }
    
    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 << ")";
    	}
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    }
    
    LinearString::operator std::string () const {
    	std::stringstream ss;
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    	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();
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    }
    
    } /* namespace string */