2024-11-17 14:39:24 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <QString>
|
|
|
|
#include <QList>
|
|
|
|
#include <functional>
|
|
|
|
#include "cmds_basic.h"
|
|
|
|
|
|
|
|
namespace validate {
|
|
|
|
template<typename T> class Validator {
|
|
|
|
public:
|
2024-11-18 15:33:51 +00:00
|
|
|
virtual QString name() const {
|
|
|
|
return QString();
|
|
|
|
}
|
2024-11-17 14:39:24 +00:00
|
|
|
virtual bool check(T value) const {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
virtual void getDepict(datas::IDataObject& self_description) { }
|
|
|
|
};
|
|
|
|
template<typename T> class ValidatorReceiver {
|
|
|
|
public:
|
2024-11-17 15:03:54 +00:00
|
|
|
virtual void append(Validator<T>* inst) { }
|
2024-11-17 14:39:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-11-19 14:52:59 +00:00
|
|
|
template<typename... Args> struct ValidateTemplet;
|
2024-11-17 14:39:24 +00:00
|
|
|
template<> struct ValidateTemplet<> {
|
|
|
|
template<typename Ret>
|
|
|
|
bool validateFor(Inlet::SignatureImpl<Ret>& value_sequence) const {
|
|
|
|
return true;
|
|
|
|
}
|
2024-11-18 15:33:51 +00:00
|
|
|
|
|
|
|
virtual void getDepict(datas::IDataObject& self_description) const {}
|
2024-11-17 14:39:24 +00:00
|
|
|
};
|
2024-11-19 14:52:59 +00:00
|
|
|
template<typename Head, typename... Rest>
|
|
|
|
struct ValidateTemplet<Head, Rest...> : public ValidateTemplet<Rest...> {
|
2024-11-17 14:39:24 +00:00
|
|
|
private:
|
2024-11-19 14:52:59 +00:00
|
|
|
QList<Validator<Head>*> validator_list;
|
2024-11-17 14:39:24 +00:00
|
|
|
|
|
|
|
public:
|
2024-11-19 14:52:59 +00:00
|
|
|
void add(Validator<Head>* vinst) {
|
2024-11-17 14:39:24 +00:00
|
|
|
validator_list << vinst;
|
|
|
|
}
|
2024-11-19 14:52:59 +00:00
|
|
|
bool check(Head value) const {
|
2024-11-17 14:39:24 +00:00
|
|
|
for (auto u : validator_list)
|
2024-11-17 15:03:54 +00:00
|
|
|
if (!u->check(value))
|
2024-11-17 14:39:24 +00:00
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename Ret>
|
2024-11-19 14:52:59 +00:00
|
|
|
bool validateFor(Inlet::SignatureImpl<Ret, Head, Rest...>& value_sequence) const {
|
|
|
|
Head head_value = value_sequence.getArgs0();
|
2024-11-17 14:39:24 +00:00
|
|
|
if (!check(head_value))
|
|
|
|
return false;
|
2024-11-19 14:52:59 +00:00
|
|
|
return ValidateTemplet<Rest...>::validateFor(value_sequence);
|
2024-11-17 14:39:24 +00:00
|
|
|
}
|
2024-11-18 15:33:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
virtual void getDepict(datas::IDataObject& self_description) const {
|
|
|
|
auto args_head = self_description.newObject();
|
|
|
|
for (auto vinst : validator_list) {
|
|
|
|
auto vdesc = self_description.newObject();
|
|
|
|
vinst->getDepict(*vdesc);
|
|
|
|
args_head->setChild(vinst->name(), vdesc);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto args_array = std::dynamic_pointer_cast<datas::IDataArray>(self_description.getChild(u8"ArgsList"));
|
|
|
|
args_array->append(args_head);
|
|
|
|
self_description.setChild(u8"ArgsList", args_array);
|
2024-11-19 14:52:59 +00:00
|
|
|
ValidateTemplet<Rest...>::getDepict(self_description);
|
2024-11-18 15:33:51 +00:00
|
|
|
}
|
2024-11-17 14:39:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-11-19 14:52:59 +00:00
|
|
|
template<int idx, typename... Args> struct ElmPos;
|
2024-11-17 14:39:24 +00:00
|
|
|
|
2024-11-19 14:52:59 +00:00
|
|
|
template<typename Head, typename... Rest>
|
|
|
|
struct ElmPos<0, ValidateTemplet<Head, Rest...>> {
|
|
|
|
using value_type = Head;
|
|
|
|
using templet_type = ValidateTemplet<Head, Rest...>;
|
2024-11-17 14:39:24 +00:00
|
|
|
};
|
2024-11-19 14:52:59 +00:00
|
|
|
template<int idx, typename Head, typename... Rest>
|
|
|
|
struct ElmPos<idx, ValidateTemplet<Head, Rest...>> {
|
|
|
|
using value_type = typename ElmPos<idx - 1, ValidateTemplet<Rest...>>::value_type;
|
|
|
|
using templet_type = typename ElmPos<idx - 1, ValidateTemplet<Rest...>>::templet_type;
|
2024-11-17 14:39:24 +00:00
|
|
|
};
|
|
|
|
|
2024-11-19 14:52:59 +00:00
|
|
|
template<int idx, typename Head, typename... Rest>
|
|
|
|
void __validator_insert_helper(ValidateTemplet<Head, Rest...>& target,
|
|
|
|
Validator<typename ElmPos<idx, ValidateTemplet<Head, Rest...>>::value_type>* inst) {
|
|
|
|
using templet_type = typename ElmPos<idx, ValidateTemplet<Head, Rest...>>::templet_type;
|
2024-11-17 14:39:24 +00:00
|
|
|
target.templet_type::add(inst);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-11-19 14:52:59 +00:00
|
|
|
template<int n, typename... Args> class SlicePosition;
|
2024-11-17 14:39:24 +00:00
|
|
|
|
|
|
|
template<typename S, typename T> class SliceValidator : public Validator<S> {
|
|
|
|
private:
|
|
|
|
std::function<T(S)> _proc_conv;
|
|
|
|
Validator<T> _sub_validator;
|
|
|
|
|
|
|
|
public:
|
|
|
|
SliceValidator(std::function<T(S)> proc, Validator<T> vinst)
|
|
|
|
: _proc_conv(proc), _sub_validator(vinst) { }
|
|
|
|
|
|
|
|
virtual bool check(S value) const {
|
|
|
|
auto t_value = _proc_conv(value);
|
|
|
|
return _sub_validator.check(t_value);
|
|
|
|
}
|
|
|
|
};
|
2024-11-19 14:52:59 +00:00
|
|
|
template<int n, typename... Args> class ArgsPosition
|
|
|
|
: public ValidatorReceiver<typename ElmPos<n, ValidateTemplet<Args...>>::value_type> {
|
2024-11-17 14:39:24 +00:00
|
|
|
public:
|
2024-11-19 14:52:59 +00:00
|
|
|
using Param = typename ElmPos<n, ValidateTemplet<Args...>>::value_type;
|
2024-11-17 14:39:24 +00:00
|
|
|
|
2024-11-19 14:52:59 +00:00
|
|
|
ArgsPosition(ValidateTemplet<Args...>& target) :_templet_bind(target) { }
|
2024-11-17 14:39:24 +00:00
|
|
|
|
2024-11-19 14:52:59 +00:00
|
|
|
ArgsPosition<n, Args...>& operator&(Validator<Param>* vinst) {
|
2024-11-17 14:39:24 +00:00
|
|
|
append(vinst);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2024-11-19 14:52:59 +00:00
|
|
|
template<typename Slice>
|
|
|
|
SlicePosition<n, Param, Slice, ArgsPosition<n, Args...>>
|
|
|
|
slice(std::function<Slice(Param)> slice_fun) {
|
|
|
|
return SlicePosition<n, Param, Slice, ArgsPosition<n, Args...>>(*this, slice_fun);
|
2024-11-17 14:39:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ValidatorReceiver
|
2024-11-19 14:52:59 +00:00
|
|
|
virtual void append(Validator<Param>* inst) {
|
|
|
|
__validator_insert_helper<n, Args...>(_templet_bind, inst);
|
2024-11-17 14:39:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2024-11-19 14:52:59 +00:00
|
|
|
ValidateTemplet<Args...>& _templet_bind;
|
2024-11-17 14:39:24 +00:00
|
|
|
};
|
2024-11-19 14:52:59 +00:00
|
|
|
template<int n, typename S, typename T, typename... Args>
|
|
|
|
class SlicePosition<n, S, T, ArgsPosition<n, Args...>> : public ValidatorReceiver<T> {
|
2024-11-17 14:39:24 +00:00
|
|
|
public:
|
2024-11-19 14:52:59 +00:00
|
|
|
SlicePosition(ValidatorReceiver<S>& host, std::function<T(S)> func)
|
2024-11-17 14:39:24 +00:00
|
|
|
:_conv_func(func), _prev_bind(host) { }
|
|
|
|
|
2024-11-19 14:52:59 +00:00
|
|
|
SlicePosition<n, S, T, ArgsPosition<n, Args...>>& operator&(Validator<T>* vinst) {
|
2024-11-17 14:39:24 +00:00
|
|
|
append(vinst);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2024-11-19 14:52:59 +00:00
|
|
|
template<typename Slice>
|
|
|
|
SlicePosition<n, T, Slice, ArgsPosition<n, Args...>>
|
|
|
|
slice(std::function<Slice(T)> slice_fun) {
|
|
|
|
return SlicePosition<n, T, Slice, ArgsPosition<n, Args...>>(*this, slice_fun);
|
2024-11-17 14:39:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ValidatorReceiver
|
2024-11-19 14:52:59 +00:00
|
|
|
virtual void append(Validator<T>* inst) {
|
|
|
|
SliceValidator<S, T> mid_validator(_conv_func, inst);
|
2024-11-17 14:39:24 +00:00
|
|
|
_prev_bind.append(mid_validator);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2024-11-19 14:52:59 +00:00
|
|
|
std::function<T(S)> _conv_func;
|
|
|
|
ValidatorReceiver<S>& _prev_bind;
|
2024-11-17 14:39:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class IValidatorTemplet {
|
|
|
|
public:
|
|
|
|
virtual bool doValidate(Inlet::IRunbase* inst) const = 0;
|
2024-11-18 15:33:51 +00:00
|
|
|
virtual void getDepict(datas::IDataObject& self_description) const = 0;
|
2024-11-17 14:39:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template<void* func, typename... types> struct ValidateImpls;
|
2024-11-19 14:52:59 +00:00
|
|
|
template<void* func, typename Ret, typename... Args>
|
|
|
|
struct ValidateImpls<func, Ret, Args...> : public ValidateTemplet<Args...>, public IValidatorTemplet {
|
2024-11-17 14:39:24 +00:00
|
|
|
quint64 address() const {
|
|
|
|
return (quint64) func;
|
|
|
|
}
|
|
|
|
|
2024-11-19 14:52:59 +00:00
|
|
|
template<int n> ArgsPosition<n, Args...> pos() {
|
|
|
|
return ArgsPosition<n, Args...>(*this);
|
2024-11-17 14:39:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Ivalidatortemplet
|
|
|
|
virtual bool doValidate(Inlet::IRunbase* inst) const {
|
2024-11-19 14:52:59 +00:00
|
|
|
auto valid_data = dynamic_cast<Inlet::CmdsImpl<func, Ret, Args...>*>(inst);
|
|
|
|
return ValidateTemplet<Args...>::validateFor(valid_data->getArgSequence());
|
2024-11-17 14:39:24 +00:00
|
|
|
}
|
2024-11-18 15:33:51 +00:00
|
|
|
|
|
|
|
virtual void getDepict(datas::IDataObject& self_description) const {
|
|
|
|
self_description.setString(u8"ValidateFor", QString::number((qulonglong)func));
|
|
|
|
|
|
|
|
auto array_l = self_description.newArray();
|
|
|
|
self_description.setChild(u8"ArgsList", array_l);
|
2024-11-19 14:52:59 +00:00
|
|
|
ValidateTemplet<Args...>::getDepict(self_description);
|
2024-11-18 15:33:51 +00:00
|
|
|
}
|
2024-11-17 14:39:24 +00:00
|
|
|
};
|
|
|
|
}
|