Program Listing for File validation.hpp¶
↰ Return to documentation for file (lib/options/validation.hpp
)
// ---------------------------------------------------------------------
// This file is part of falcon-core.
//
// Copyright (C) 2015, 2016, 2017 Neuro-Electronics Research Flanders
//
// Falcon-server is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Falcon-server is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with falcon-core. If not, see <http://www.gnu.org/licenses/>.
// ---------------------------------------------------------------------
#pragma once
#include <limits>
#include <regex>
#include <stdexcept>
#include <string>
#include <vector>
#include <algorithm>
#include "units/units.hpp"
#include "../utilities/filesystem.hpp"
namespace options {
class ValidationError : public std::runtime_error {
public:
ValidationError(std::string msg) : std::runtime_error(msg) {}
};
class ConversionError : public std::runtime_error {
public:
ConversionError(std::string msg) : std::runtime_error(msg) {}
};
template <typename T> using ValidatorFunc = std::function<T(const T &)>;
template <typename T>
ValidatorFunc<T> compose(ValidatorFunc<T> f, ValidatorFunc<T> g) {
return [f, g](T x) { return f(g(x)); };
}
template <typename T> class validator {
public:
friend auto operator+(const ValidatorFunc<T> &lhs,
const ValidatorFunc<T> &rhs) {
return compose<T>(rhs, lhs);
}
};
template <typename T> class inrange : public validator<T> {
static_assert(std::is_arithmetic<T>::value,
"inrange validator only supports numerical types.");
public:
using value_type = T;
public:
inrange(T min, T max) : min_(min), max_(max) {}
T operator()(const T &x) const {
if (x < min_ || x > max_) {
throw ValidationError("Value out of range.");
}
return x;
}
protected:
T min_;
T max_;
};
template <typename T> class clamped : public validator<T> {
static_assert(std::is_arithmetic<T>::value,
"clamped validator only supports numerical types.");
public:
using value_type = T;
public:
clamped(T min, T max) : min_(min), max_(max) {}
T operator()(const T &x) const {
T y = x;
std::clamp(y, min_, max_);
return y;
}
protected:
T min_;
T max_;
};
template <typename T> class squared : public validator<T> {
static_assert(std::is_arithmetic<T>::value,
"squared validator only supports numerical types.");
public:
T operator()(const T &x) const { return x * x; }
};
template <typename T> class multiplied : public validator<T> {
static_assert(std::is_arithmetic<T>::value,
"multiplier validator only supports numerical types.");
public:
multiplied(T multiplier) : multiplier_(multiplier) {}
T operator()(const T &x) const { return multiplier_ * x; }
protected:
T multiplier_;
};
class invert : public validator<bool> {
public:
bool operator()(const bool &x) const { return !x; }
};
template <typename T> class zeroismax : public validator<T> {
public:
T operator()(const T &x) {
if (x == 0) {
return std::numeric_limits<T>::max();
} else {
return x;
}
}
};
template <typename T> class notempty : public validator<T> {
public:
T operator()(const T &x) {
if (x.size() == 0) {
throw ValidationError("Container or value cannot be empty.");
}
return x;
}
};
template <typename T> class each : public validator<std::vector<T>> {
public:
each(ValidatorFunc<T> validator) : validator_(validator) {}
std::vector<T> operator()(const std::vector<T> &x) {
std::vector<T> y = x;
std::transform(x.begin(), x.end(), y.begin(), validator_);
return x;
}
protected:
ValidatorFunc<T> validator_;
};
template <typename T> class positive : public validator<T> {
public:
positive(bool strict = false) : strict_(strict) {}
T operator()(const T &x) const {
if ((strict_ && x <= 0) || x < 0) {
if (strict_) {
throw ValidationError("Value cannot be negative or zero.");
} else {
throw ValidationError("Value cannot be negative.");
}
}
return x;
}
protected:
bool strict_;
};
class isfile : public validator<std::string> {
public:
isfile(bool exists = false) : exists_(exists) {}
std::string operator()(const std::string &x) const {
return parse_file(x, exists_).string();
}
protected:
bool exists_;
};
class isdir : public validator<std::string> {
public:
isdir(bool exists = true, bool create = false)
: exists_(exists), create_(create) {}
std::string operator()(const std::string &x) const {
return parse_directory(x, exists_, create_).string();
}
protected:
bool exists_;
bool create_;
};
} // namespace options