schema_editor/comdel/domain/function_signature.cpp

167 lines
5.3 KiB
C++
Raw Permalink Normal View History

2022-05-27 06:18:17 +00:00
#include <map>
#include <utility>
#include "function_signature.h"
namespace domain {
class DivisibleValidator : public FunctionValidator {
public:
DivisibleValidator() : FunctionValidator("divisible", {Value::INT, Value::INT}) {}
bool validate(std::vector<Value> values) override {
if (validateSignature(values)) {
long long first = values[0].asInt();
long long second = values[1].asInt();
return (first % second) == 0;
}
return false;
}
void clear() override {}
};
class LessThenValidator : public FunctionValidator {
public:
LessThenValidator() : FunctionValidator("less_then", {Value::INT, Value::INT}) {}
bool validate(std::vector<Value> values) override {
if (validateSignature(values)) {
long long first = values[0].asInt();
long long second = values[1].asInt();
return first < second;
}
return false;
}
void clear() override {}
};
class GreaterThenValidator : public FunctionValidator {
public:
GreaterThenValidator() : FunctionValidator("greater_then", {Value::INT, Value::INT}) {}
bool validate(std::vector<Value> values) override {
if (validateSignature(values)) {
long long first = values[0].asInt();
long long second = values[1].asInt();
return first > second;
}
return false;
}
void clear() override {}
};
class ContainsAddressValidator : public FunctionValidator {
public:
ContainsAddressValidator() : FunctionValidator("contains_address", {Value::ADDRESS_SPACE, Value::INT}) {}
bool validate(std::vector<Value> values) override {
if (validateSignature(values)) {
AddressSpace space = values[0].asAddressSpace();
long long address = values[1].asInt();
return space.contains(address);
}
return false;
}
void clear() override {}
};
class ContainsValidator : public FunctionValidator {
public:
ContainsValidator() : FunctionValidator("contains", {Value::ADDRESS_SPACE, Value::INT, Value::INT}) {}
bool validate(std::vector<Value> values) override {
if (validateSignature(values)) {
AddressSpace space = values[0].asAddressSpace();
long long start = values[1].asInt();
long long size = values[1].asInt();
return space.contains(start, start + size);
}
return false;
}
void clear() override {}
};
class UniqueValidator : public FunctionValidator {
private:
std::map<std::string, std::vector<std::pair<long long int, long long int>>> spaces;
bool overlaps(long long int start1, long long int end1, long long int start2, long long int end2) {
return std::max((long long int) 0, std::min(end1, end2) - std::max(start1, start2)) > 0;
}
public:
UniqueValidator() : FunctionValidator("unique", {Value::ADDRESS_SPACE, Value::INT, Value::INT}) {}
bool validate(std::vector<Value> values) override {
if (validateSignature(values)) {
std::string space = values[0].asAddressSpace().getName();
long long int start = values[1].asInt();
long long int end = start + values[2].asInt();
if (spaces.count(space) == 0) {
spaces.insert(std::make_pair(space, std::vector<std::pair<long long int, long long int>>{}));
}
for (auto &s: spaces[space]) {
if (overlaps(s.first, s.second, start, end)) {
return false;
}
}
spaces[space].push_back(std::make_pair(start, end));
return true;
}
return false;
}
void clear() override {
spaces.clear();
}
};
std::vector<FunctionValidator *> getSupportedValidators() {
std::vector<FunctionValidator *> validators;
validators.push_back(new DivisibleValidator());
validators.push_back(new LessThenValidator());
validators.push_back(new GreaterThenValidator());
validators.push_back(new ContainsAddressValidator());
validators.push_back(new ContainsValidator());
validators.push_back(new UniqueValidator());
return validators;
}
FunctionValidator::FunctionValidator(std::string name, std::vector<Value::ValueType> signature)
: name(std::move(name)), signature(std::move(signature)) {}
std::string FunctionValidator::getName() {
return name;
}
std::vector<Value::ValueType> FunctionValidator::getSignature() {
return signature;
}
bool FunctionValidator::validateSignature(std::vector<Value> _signature) {
if (this->signature.size() != _signature.size()) {
return false;
}
for (int i = 0; i < this->signature.size(); i++) {
if (this->signature[i] != _signature[i].getType()) {
return false;
}
}
return true;
}
} // namespace domain