PenetrateBase/PenetrateBasic/validation.h

160 lines
4.7 KiB
C++

#pragma once
#include <QString>
#include <QList>
#include <iostream>
#include <functional>
namespace validate {
template<typename T> class validator {
public:
virtual bool check(T value) const {
return false;
}
};
template<typename T> class validator_receiver {
public:
virtual void append(validator<T> inst) { }
};
template<typename... args_type> struct check_delegation;
template<> struct check_delegation<> {
void prest() {
std::cout << "ends" << std::endl;
}
};
template<typename head_type, typename... rest_type>
struct check_delegation<head_type, rest_type...> : public check_delegation<rest_type...> {
private:
QList<validator<head_type>> validator_list;
public:
void add(validator<head_type> vinst) {
validator_list << vinst;
}
bool check(head_type value) {
for (auto u : validator_list)
if (!u.check(value))
return false;
return true;
}
void prest() {
std::cout << "[-]" << validator_list.size() << std::endl;
check_delegation<rest_type...>::prest();
}
};
template<int idx, typename... args_type> struct elm_pos;
template<typename head_type, typename... rest_type>
struct elm_pos<0, check_delegation<head_type, rest_type...>> {
using value_type = head_type;
using templet_type = check_delegation<head_type, rest_type...>;
};
template<int idx, typename head_type, typename... rest_type>
struct elm_pos<idx, check_delegation<head_type, rest_type...>> {
using value_type = typename elm_pos<idx - 1, check_delegation<rest_type...>>::value_type;
using templet_type = typename elm_pos<idx - 1, check_delegation<rest_type...>>::templet_type;
};
template<int idx, typename head_type, typename... rest_type>
void __validator_insert_helper(check_delegation<head_type, rest_type...>& target,
validator<typename elm_pos<idx, check_delegation<head_type, rest_type...>>::value_type> inst) {
using templet_type = typename elm_pos<idx, check_delegation<head_type, rest_type...>>::templet_type;
target.templet_type::add(inst);
}
template<int n, typename... args_type> class slice_position;
template<typename S, typename T> class slice_validator : public validator<S> {
private:
std::function<T(S)> _proc_conv;
validator<T> _sub_validator;
public:
slice_validator(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);
}
};
template<int n, typename... args_type> class args_position
: public validator_receiver<typename elm_pos<n, check_delegation<args_type...>>::value_type> {
public:
using param_type = typename elm_pos<n, check_delegation<args_type...>>::value_type;
args_position(check_delegation<args_type...>& target) :_templet_bind(target) { }
args_position<n, args_type...>& operator&(validator<param_type> vinst) {
append(vinst);
return *this;
}
template<typename slice_type>
slice_position<n, param_type, slice_type, args_position<n, args_type...>>
slice(std::function<slice_type(param_type)> slice_fun) {
return slice_position<n, param_type, slice_type, args_position<n, args_type...>>(*this, slice_fun);
}
// validator_receiver
virtual void append(validator<param_type> inst) {
__validator_insert_helper<n, args_type...>(_templet_bind, inst);
}
private:
check_delegation<args_type...>& _templet_bind;
};
template<int n, typename s_type, typename t_type, typename... args_type>
class slice_position<n, s_type, t_type, args_position<n, args_type...>> : public validator_receiver<t_type> {
public:
slice_position(validator_receiver<s_type>& host, std::function<t_type(s_type)> func)
:_conv_func(func), _prev_bind(host) { }
slice_position<n, s_type, t_type, args_position<n, args_type...>>& operator&(validator<t_type> vinst) {
append(vinst);
return *this;
}
template<typename slice_type>
slice_position<n, t_type, slice_type, args_position<n, args_type...>>
slice(std::function<slice_type(t_type)> slice_fun) {
return slice_position<n, t_type, slice_type, args_position<n, args_type...>>(*this, slice_fun);
}
// validator_receiver
virtual void append(validator<t_type> inst) {
slice_validator<s_type, t_type> mid_validator(_conv_func, inst);
_prev_bind.append(mid_validator);
}
private:
std::function<t_type(s_type)> _conv_func;
validator_receiver<s_type>& _prev_bind;
};
template<void* func, typename... types> struct validate_helper;
template<void* func, typename return_type, typename... args_type>
struct validate_helper<func, return_type, args_type...> : public check_delegation<args_type...> {
template<int n> args_position<n, args_type...> pos() {
return args_position<n, args_type...>(*this);
}
};
}