PenetrateBase/PenetrateBasic/validate_basic.h

207 lines
6.0 KiB
C
Raw Normal View History

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
};
}