-
Jan Trávníček authoredJan Trávníček authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
RegExp.cpp 3.95 KiB
/*
* RegExp.cpp
*
* Created on: Nov 23, 2013
* Author: Martin Zak
*/
#include "RegExp.h"
#include "../AlibException.h"
#include "RegExpEmpty.h"
#include "RegExpSymbol.h"
#include <iostream>
#include <algorithm>
#include "../std/set.hpp"
namespace regexp {
RegExp::RegExp() {
this->regExp = new RegExpEmpty();
}
RegExp::RegExp(const std::set<alphabet::Symbol>& alphabet, const RegExpElement& regExp) : alphabet(alphabet) {
this->regExp = NULL;
setRegExp(regExp);
}
RegExp::RegExp(std::set<alphabet::Symbol>&& alphabet, RegExpElement&& regExp) : alphabet(std::move(alphabet)) {
this->regExp = NULL;
setRegExp(std::move(regExp));
}
RegExp::RegExp(const RegExpElement& regExp) {
regExp.computeMinimalAlphabet(alphabet);
this->regExp = NULL;
setRegExp(regExp);
}
RegExp::RegExp(RegExpElement&& regExp) {
regExp.computeMinimalAlphabet(alphabet);
this->regExp = NULL;
setRegExp(std::move(regExp));
}
RegExp::RegExp(const RegExp& other) : regExp(other.regExp->clone()), alphabet(other.alphabet) {
this->regExp->attachRegExp(this);
}
RegExp::RegExp(RegExp&& other) noexcept : regExp(other.regExp), alphabet(std::move(other.alphabet) ) {
this->regExp->attachRegExp(this);
other.regExp = NULL;
}
RegExp& RegExp::operator=(const RegExp& other) {
if (this == &other) {
return *this;
}
*this = RegExp(other);
return *this;
}
RegExp& RegExp::operator=(RegExp&& other) noexcept {
std::swap(this->regExp, other.regExp);
std::swap(this->alphabet, other.alphabet);
return *this;
}
RegExp::~RegExp() noexcept {
delete regExp;
}
const RegExpElement& RegExp::getRegExp() const {
return *regExp;
}
RegExpElement& RegExp::getRegExp() {
return *regExp;
}
void RegExp::setRegExp(const RegExpElement& regExp) {
delete this->regExp;
this->regExp = regExp.clone();
if(!this->regExp->attachRegExp(this))
throw alib::AlibException("Input symbols not in the alphabet.");
}
void RegExp::setRegExp(RegExpElement&& regExp) {
delete this->regExp;
this->regExp = std::move(regExp).plunder();
if(!this->regExp->attachRegExp(this))
throw alib::AlibException("Input symbols not in the alphabet.");
}
const std::set<alphabet::Symbol>& RegExp::getAlphabet() const {
return alphabet;
}
bool RegExp::addSymbolToAlphabet(const alphabet::Symbol & symbol) {
return alphabet.insert(symbol).second;
}
void RegExp::setAlphabet(const std::set<alphabet::Symbol> & symbols) {
std::set<alphabet::Symbol> minimalAlphabet;
this->regExp->computeMinimalAlphabet(minimalAlphabet);
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 alib::AlibException("Input symbols are used.");
this->alphabet = symbols;
}
bool RegExp::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) {
if(this->regExp->testSymbol(symbol))
throw alib::AlibException("Input symbol \"" + (std::string) symbol + "\" is used.");
return alphabet.erase(symbol);
}
bool RegExp::isEmpty() const {
return regExp->isEmpty();
}
bool RegExp::containsEmptyString() const {
return regExp->containsEmptyString();
}
std::ostream& operator <<(std::ostream& out, const RegExp& regExp) {
out << "(RegExp " << *(regExp.regExp) << ")";
return out;
}
bool RegExp::operator<(const RegExp& other) const {
if(*(this->regExp) < *(other.regExp)) {
return true;
} else if(*(this->regExp) > *(other.regExp)) {
return false;
} else {
return this->alphabet < other.alphabet;
}
}
bool RegExp::operator<=(const RegExp& other) const {
return !(other > *this);
}
bool RegExp::operator==(const RegExp& other) const {
return *(this->regExp) == *(other.regExp) && this->alphabet == other.alphabet;
}
bool RegExp::operator!=(const RegExp& other) const {
return !(*this == other);
}
bool RegExp::operator>(const RegExp& other) const {
return other < *this;
}
bool RegExp::operator>=(const RegExp& other) const {
return !(*this < other);
}
} /* namespace regexp */