#pragma once #include #include #include #include "cmds_basic.h" namespace validate { template class Validator { public: virtual bool check(T value) const { return false; } virtual void getDepict(datas::IDataObject& self_description) { } }; template class ValidatorReceiver { public: virtual void append(Validator inst) { } }; template struct ValidateTemplet; template<> struct ValidateTemplet<> { template bool validateFor(Inlet::SignatureImpl& value_sequence) const { return true; } }; template struct ValidateTemplet : public ValidateTemplet { private: QList> validator_list; public: void add(Validator vinst) { validator_list << vinst; } bool check(head_type value) const { for (auto u : validator_list) if (!u.check(value)) return false; return true; } template bool validateFor(Inlet::SignatureImpl& value_sequence) const { head_type head_value = value_sequence.getArgs0(); if (!check(head_value)) return false; return ValidateTemplet::validateFor(value_sequence); } }; template struct ElmPos; template struct ElmPos<0, ValidateTemplet> { using value_type = head_type; using templet_type = ValidateTemplet; }; template struct ElmPos> { using value_type = typename ElmPos>::value_type; using templet_type = typename ElmPos>::templet_type; }; template void __validator_insert_helper(ValidateTemplet& target, Validator>::value_type> inst) { using templet_type = typename ElmPos>::templet_type; target.templet_type::add(inst); } template class SlicePosition; template class SliceValidator : public Validator { private: std::function _proc_conv; Validator _sub_validator; public: SliceValidator(std::function proc, Validator 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 class ArgsPosition : public ValidatorReceiver>::value_type> { public: using param_type = typename ElmPos>::value_type; ArgsPosition(ValidateTemplet& target) :_templet_bind(target) { } ArgsPosition& operator&(Validator vinst) { append(vinst); return *this; } template SlicePosition> slice(std::function slice_fun) { return SlicePosition>(*this, slice_fun); } // ValidatorReceiver virtual void append(Validator inst) { __validator_insert_helper(_templet_bind, inst); } private: ValidateTemplet& _templet_bind; }; template class SlicePosition> : public ValidatorReceiver { public: SlicePosition(ValidatorReceiver& host, std::function func) :_conv_func(func), _prev_bind(host) { } SlicePosition>& operator&(Validator vinst) { append(vinst); return *this; } template SlicePosition> slice(std::function slice_fun) { return SlicePosition>(*this, slice_fun); } // ValidatorReceiver virtual void append(Validator inst) { SliceValidator mid_validator(_conv_func, inst); _prev_bind.append(mid_validator); } private: std::function _conv_func; ValidatorReceiver& _prev_bind; }; class IValidatorTemplet { public: virtual bool doValidate(Inlet::IRunbase* inst) const = 0; }; template struct ValidateImpls; template struct ValidateImpls : public ValidateTemplet, public IValidatorTemplet { quint64 address() const { return (quint64) func; } template ArgsPosition pos() { return ArgsPosition(*this); } // Ivalidatortemplet virtual bool doValidate(Inlet::IRunbase* inst) const { auto valid_data = dynamic_cast*>(inst); return ValidateTemplet::validateFor(valid_data->getArgSequence()); } }; }