#include "uclass.h" namespace refl { template inline auto FieldPtr::Call(Func func, Args&& ...args)const { using MemberFunc = decltype(fetch_method_t(func)); MemberFunc fptr = (MemberFunc)data.method; return fptr(std::forward(args)...); } bool FieldPtr::Invoke(const sarray& ArgsList)const{ auto Call = type->vtable.Call; if (Call) { Call(this, ArgsList); } return Call; } bool FieldPtr::Invoke(std::vector& ArgsList)const { auto Call = type->vtable.Call; if (Call) { auto params = GetParams(); int paramsSize = params.size(); int argsSize = ArgsList.size(); if (argsSize < paramsSize && flag & FIELD_METHOD_VALUE_FLAG) { auto [argsPtr, valueSize] = value.method(); if (argsSize + valueSize >= paramsSize) { for (int i = valueSize + argsSize - paramsSize; i < valueSize; i++) { ArgsList.push_back(*(argsPtr + i)); } argsSize = paramsSize; } } if (argsSize < paramsSize) { return false; } for (int i = 0; i < paramsSize; i++) { if (ArgsList[i].cls != params[i] && !ArgsList[i].ConvertTo(params[i])) { return false; } } Call(this, ArgsList); } return Call; } std::vector FieldPtr::GetParams() const { auto GetParams = type->vtable.GetParams; if (GetParams) { return GetParams(type); } return{}; } template class Field { public: inline static char data[fetch_args_size()]{}; inline static int index{0}; template static FieldPtr MakeField(V T::* ptr, Name name) { FieldPtr::Default value; Offset offset = reinterpret_cast(&(reinterpret_cast(0)->*ptr)); FieldPtr::Data member = { offset }; constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG; return { name, &TypeInfo::StaticClass, member, value, flag }; } template static FieldPtr MakeField(R(*ptr)(Args...), Name name, const sarray& args = {}) { uint32_t flag = FIELD_METHOD_FLAG; FieldPtr::Default value; if (args.size() > 0) { flag |= FIELD_METHOD_VALUE_FLAG; static const ArgsValueList argsValue(args, &data[index]); index += ArgsValueList::GetArgsSize(args); value.method = []() ->std::pair { return { argsValue.ptr , argsValue.num }; }; } FieldPtr::Data method = { *(Method*)&ptr }; return { name, &TypeInfo(*)(real_type_t...)>::StaticClass, method, value, flag }; } template static FieldPtr MakeField(R(T::* ptr)(Args...), Name name, const sarray& args = {}) { uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG; FieldPtr::Default value; if (args.size() > 0) { flag |= FIELD_METHOD_VALUE_FLAG; static const ArgsValueList argsValue(args, &data[index]); index += ArgsValueList::GetArgsSize(args); value.method = []() ->std::pair { return { argsValue.ptr , argsValue.num }; }; } FieldPtr::Data method = { *(Method*)&ptr }; return { name, &TypeInfo(*)(const void*,real_type_t...)>::StaticClass, method, value,flag }; } }; }