pause refl,need ast tool

This commit is contained in:
ouczbs 2024-04-16 16:17:13 +08:00
parent 5814d973d7
commit 75a304bf73
12 changed files with 202 additions and 70 deletions

View File

@ -23,6 +23,7 @@ namespace refl {
FIELD_METHOD_FLAG = 1 << 2,
FIELD_METHOD_VALUE_FLAG = 1 << 3
};
using enum FieldFlag;
struct FieldPtr {
union Data
{
@ -49,12 +50,12 @@ namespace refl {
//unsafe
bool Invoke(const sarray<ArgsView>& ArgsList)const;
//safe
bool Invoke(std::vector<ArgsView>& ArgsList)const;
bool Invoke(svector<ArgsView>& ArgsList)const;
template<typename Func, typename... Args>
auto Call(Func func, Args&&... args)const;
std::vector<const UClass*> GetParams() const;
sarray<const UClass*> GetParams() const;
};
template<typename T, typename R, typename ...Args>
consteval auto fetch_method_t(R(T::*)(Args...)) {

View File

@ -14,7 +14,7 @@ namespace refl {
}
return Call;
}
bool FieldPtr::Invoke(std::vector<ArgsView>& ArgsList)const {
bool FieldPtr::Invoke(svector<ArgsView>& ArgsList)const {
auto Call = type->vtable.Call;
if (Call) {
auto params = GetParams();
@ -33,8 +33,10 @@ namespace refl {
return false;
}
for (int i = 0; i < paramsSize; i++) {
if (ArgsList[i].cls != params[i] && !ArgsList[i].ConvertTo(params[i])) {
auto a = ArgsList.front();
auto p = params.front();
for (auto e = params.back(); p < e; ++p, ++a) {
if (a->cls != *p && !a->ConvertTo(*p)) {
return false;
}
}
@ -42,7 +44,7 @@ namespace refl {
}
return Call;
}
std::vector<const UClass*> FieldPtr::GetParams() const {
sarray<const UClass*> FieldPtr::GetParams() const {
auto GetParams = type->vtable.GetParams;
if (GetParams) {
return GetParams(type);
@ -52,8 +54,8 @@ namespace refl {
template<typename T>
class Field {
public:
inline static char data[fetch_args_size<T>()]{};
inline static int index{0};
inline static char s_data[fetch_args_size<T>()]{};
inline static int s_index{0};
template<typename V>
static FieldPtr MakeField(V T::* ptr, Name name)
{
@ -69,8 +71,8 @@ namespace refl {
FieldPtr::Default value;
if (args.size() > 0) {
flag |= FIELD_METHOD_VALUE_FLAG;
static const ArgsValueList argsValue(args, &data[index]);
index += ArgsValueList::GetArgsSize(args);
static const ArgsValueList argsValue(args, &Field<T>::s_data[Field<T>::s_index]);
Field<T>::s_index += ArgsValueList::GetArgsSize(args);
value.method = []() ->std::pair<ArgsView*, int> {
return { argsValue.ptr , argsValue.num };
};
@ -84,8 +86,8 @@ namespace refl {
FieldPtr::Default value;
if (args.size() > 0) {
flag |= FIELD_METHOD_VALUE_FLAG;
static const ArgsValueList argsValue(args, &data[index]);
index += ArgsValueList::GetArgsSize(args);
static const ArgsValueList argsValue(args, &s_data[s_index]);
s_index += ArgsValueList::GetArgsSize(args);
value.method = []() ->std::pair<ArgsView*, int> {
return { argsValue.ptr , argsValue.num };
};

View File

@ -7,12 +7,13 @@ namespace refl {
CLASS_NONE_FLAG = 0,
CLASS_TRIVIAL_FLAG = 1 << 0,
};
using enum ClassFlag;
struct vtable_uclass
{
//class
const FieldPtr* (*GetField)(const UClass*, const Name&, bool);
const FieldPtr* (*GetField)(const UClass*, const Name&, int);
//function
std::vector<const UClass*>(*GetParams)(const UClass*);
sarray<const UClass*>(*GetParams)(const UClass*);
//function
void (*Call)(const FieldPtr*, const sarray<ArgsView>& ArgsList);
@ -23,8 +24,6 @@ namespace refl {
};
class UClass{
public:
using enum FieldFlag;
using enum ClassFlag;
Name name;
uint32_t size;
uint32_t flag{0};
@ -77,9 +76,9 @@ namespace refl {
return false;
}
public:
const FieldPtr* GetField(const Name& name, bool isMethod)const {
const FieldPtr* GetField(const Name& name, int index)const {
if (vtable.GetField) {
return vtable.GetField(this, name, isMethod);
return vtable.GetField(this, name, index);
}
return nullptr;
}

View File

@ -41,9 +41,9 @@ namespace refl {
public:
std::array<const UClass*, sizeof...(Args) + 1> UList{};
static std::vector<const UClass*> GetParams(const UClass* cls) {
static sarray<const UClass*> GetParams(const UClass* cls) {
auto& UList = static_cast<const MyUClass*>(cls)->UList;
return { UList.data(), UList.data() + UList.size() };
return sarray<const UClass*>(&UList.front(),UList.size());
}
//这里顺序似乎是不确定的,但是我实际运用是对的
//如果使用make_index_sequence,会多一次函数调用
@ -58,7 +58,7 @@ namespace refl {
else {
MethodType fptr = (MethodType)field->data.method;
auto param = ArgsList.end();
auto ret = ArgsList.get();
auto ret = ArgsList.front();
if (ret->cls == &TypeInfo<R*>::StaticClass) {
*(R*)ret->val = fptr((param--->cast_to<Args>())...);
}
@ -106,11 +106,14 @@ namespace refl {
else {
vtable.InitObject = &UClass::InitObject<T>;
}
vtable.GetField = &UClass_Meta::GetField;
}
const FieldPtr* GetField(int index) const {
return &Fields[index];
}
const FieldPtr* GetField(const Name& name, int index = 0) const{
static const FieldPtr* GetField(const UClass* _cls,const Name& name, int index = 0){
auto cls = static_cast<const UClass_Meta*>(_cls);
auto& Fields = cls->Fields;
constexpr int length = std::tuple_size<FieldsType>::value;
auto ptr = index < length ? &Fields[index] : nullptr;
for (int i = index; i < length; i++, ptr++) {

View File

@ -1,7 +1,7 @@
#pragma once
#include <string>
#include "type.h"
#include "../std/sarray.h"
#include "field.h"
namespace refl {
class UClass;
class FieldPtr;
@ -82,7 +82,7 @@ namespace refl {
bool Invoke(const Name& name,const sarray<ArgsView>& ArgsList);//这里是内存分配慢呀,这里是可以改成栈容器的
bool Invoke(const Name& name,std::vector<ArgsView>& ArgsList);
bool Invoke(const Name& name,svector<ArgsView>& ArgsList);
ObjectView Parent();
};

View File

@ -27,6 +27,7 @@ namespace refl {
isMemoryOwner = true;
data = malloc(GetArgsSize(args));
ptr = (ArgsView*)data;
assert(data != nullptr);
}
char* pData = ((char*)data) + num * sizeof(ArgsView);
for (auto& arg : args) {
@ -35,7 +36,7 @@ namespace refl {
ptr->val = pData;
ptr->cls = arg.cls;
ptr++;
pData += arg.cls->size;
pData += arg.type->size;
}
ptr = (ArgsView*)data;
}
@ -71,7 +72,7 @@ namespace refl {
}
return isChild;
}
auto field = cls->GetField(name, false);
auto field = cls->GetField(name, 0);
if (field) {
cache = field;
goto _cache_get;
@ -91,7 +92,7 @@ namespace refl {
}
return isChild;
}
auto field = cls->GetField(name, false);
auto field = cls->GetField(name, 0);
if (field) {
cache = field;
goto _cache_set;
@ -103,7 +104,7 @@ namespace refl {
}
bool ObjectView::Invoke(const Name& name,const sarray<ArgsView>& ArgsList)
{
auto field = cls->GetField(name, true);
auto field = cls->GetField(name, 0);
if (!field) {
if (cls->parent) {
return Parent().Invoke(name, ArgsList);
@ -112,9 +113,9 @@ namespace refl {
}
return field->Invoke(ArgsList);
}
bool ObjectView::Invoke(const Name& name, std::vector<ArgsView>& ArgsList)
bool ObjectView::Invoke(const Name& name, svector<ArgsView>& ArgsList)
{
auto field = cls->GetField(name, true);
auto field = cls->GetField(name, 0);
if (!field) {
if (cls->parent) {
return Parent().Invoke(name, ArgsList);

View File

@ -0,0 +1,35 @@
#pragma once
/*
#define REGISTER_CLASS(cls) using _T = cls;
#define MAKE_STATIC_FIELD(member, ...) \
MakeStaticField(&_T::member, #member, __VA_ARGS__)
#define MAKE_FIELD(member, ...) \
Field<_T>::MakeField(&_T::member, #member, __VA_ARGS__)
#define REGISTER_FIELDS()\
consteval static auto __MakeStaticFields() {\
return std::array{\
MAKE_FIELD_LIST(MAKE_STATIC_FIELD)\
};\
}\
static auto __MakeFields() {\
return std::array{\
MAKE_FIELD_LIST(MAKE_FIELD)\
};\
}
#define MAKE_FIELD_LIST(MACRO) \
MACRO(x), \
MACRO(y), \
MACRO(z), \
MACRO(norm, {10,9}), \
MACRO(norm1, {1}), \
MACRO(norm2, {2}),
REGISTER_CLASS(vec3)
REGISTER_FIELDS()
#undef MAKE_FIELD_LIST
*/

View File

@ -1,7 +1,9 @@
#pragma once
#include "detail/uclass.inl"
#include "detail/view.inl"
#include "detail/field.inl"
#include "std/sarray.h"
#include "macro.h"
namespace refl {
template<typename T, typename Obj>
consteval FieldPtr MakeStaticField(T Obj::* ptr, Name name) {

View File

@ -1,40 +1,37 @@
#pragma once
#include <vector>
#include "svector.h"
#include <concepts>
namespace refl {
template<typename T>
class sarray {
protected:
const T* m_ptr;
int m_size;
int m_count;
public:
constexpr sarray(const std::vector<T>& list) : m_ptr(&list.front()), m_size(list.size()) {}
constexpr sarray() :m_ptr(nullptr), m_size(0) {}
constexpr sarray(std::initializer_list<T> list) : m_ptr(list.begin()), m_size(list.size()) {}
template<int N>
constexpr sarray(const std::array<T, N>& arr):m_ptr(&arr[0]), m_size(arr.size()){}
const T* get() const noexcept {
constexpr sarray(const T* ptr, int count) : m_ptr(ptr), m_count(count) {}
constexpr sarray(const svector<T>& vec) : m_ptr(vec.front()), m_count(vec.size()) {}
constexpr sarray() :m_ptr(nullptr), m_count(0) {}
constexpr sarray(std::initializer_list<T> list) : m_ptr(list.begin()), m_count(list.size()) {}
const T* front() const noexcept {
return m_ptr;
}
const T* last()const noexcept {
if (m_size > 0)
return m_ptr + m_size - 1;
return m_ptr;
const T* back()const noexcept {
return m_ptr + m_count;
}
const T* at(int i) const noexcept {
if (i < m_size) {
if (i < m_count) {
return m_ptr + i;
}
return nullptr;
}
constexpr int size() const noexcept {
return m_size;
return m_count;
}
constexpr auto begin()const noexcept {
return iterator{ m_ptr };
}
constexpr auto end() const noexcept {
return iterator{ m_ptr + m_size};
return iterator{ m_ptr + m_count};
}
// Iterator class
class iterator {

View File

@ -0,0 +1,67 @@
#pragma once
#include <array>
#include <concepts>
namespace refl {
template<typename T>
class svector {
protected:
T* m_ptr;
int m_count;
int m_capicty;
public:
constexpr svector() :m_ptr(nullptr), m_count(0), m_capicty(0){}
constexpr svector(T* ptr, int size, int count) : m_ptr(ptr), m_capicty(size), m_count(count){}
T* front()const noexcept {
return m_ptr;
}
T* back()const noexcept {
return m_ptr + m_count;
}
void push_back(const T& t) {
if (m_count < m_capicty) {
*(m_ptr + m_count) = t;
m_count++;
}
}
constexpr int size() const noexcept {
return m_count;
}
constexpr auto begin()const noexcept {
return iterator{ m_ptr };
}
constexpr auto end() const noexcept {
return iterator{ m_ptr + m_count };
}
// Iterator class
class iterator {
private:
const T* ptr;
public:
constexpr iterator(const T* p) : ptr(p) {}
// Overload ++ to move to next element
constexpr iterator& operator++() noexcept {
++ptr;
return *this;
}
//这里其实是--it,而不是it--
constexpr iterator& operator--(int) noexcept {
--ptr;
return *this;
}
constexpr const T* operator->() const noexcept {
return ptr;
}
// Overload * to dereference iterator
constexpr const T& operator*() const noexcept {
return *ptr;
}
// Overload != to compare iterators
constexpr bool operator!=(const iterator& other) const noexcept {
return ptr != other.ptr;
}
};
};
}

View File

@ -3,8 +3,9 @@
using namespace std;
using namespace refl;
struct vec3_parent {
virtual void norm(int x1, int& x2) {
virtual int norm(int x1, int& x2) {
x2 = x1 * x2;
return x2;
//cout << x2 << "vec3_parent::norm" << endl;
}
};
@ -13,9 +14,12 @@ struct vec3 : public vec3_parent {
float y = 2;
float z = 3;
string name{ "hellohellohellohellohellohello" };
void norm(int x1, int& x2)override {
x2 = x1 * x2;
cout << x2 << "vec3::norm" << endl;
int norm(int x1, int& x2)override {
int tmp = x1 * 2 + 1;
x1 = x2;
x2 = tmp;
return x2;
//cout << x2 << "vec3::norm" << endl;
}
virtual float norm1(int& x1) {
x1 = x1 * x * y * z;

View File

@ -1,23 +1,44 @@
#include "refl/vertex.h"
#include "refl/std/sarray.h"
#include <array>
int main() {
auto cls1 = &TypeInfo<void*>::StaticClass;
auto cls2 = &TypeInfo<const void*>::StaticClass;
using type1 = real_type_t<const void*>;
auto& cls = TypeInfo<vec3>::StaticClass;
auto field = cls.GetField(GetStaticFieldID<vec3>("norm"));
auto ov = cls.New();
int x = 10;
field->Call(&vec3::norm, ov.ptr, x, x);
field->Invoke({ov.ptr, x, x});
std::vector<ArgsView> ArgsList{{}, ov.ptr, x, x};
field->Invoke(ArgsList);
sarray<ArgsView> sa(ArgsList);
field->Invoke(sa);
UMethod_Auto<void, const void*, int, int*>::Call(field, { ov.ptr, x, x });
//fetchUMethod(&vec3::norm)->Call(field, ov.ptr, x, &x);
std::cout << "hello world\n";
return 0;
#include <benchmark/benchmark.h>
auto cls = &TypeInfo<vec3>::StaticClass;
vec3 v;
auto ov = cls->New((void*)&v);
constexpr Name func("norm");
void TestRefl1(benchmark::State& state) {
int x = 1, y = 2;
for (auto _ : state) {
std::array<ArgsView, 4> arr{&x, ov.ptr};
svector<ArgsView> svec(&arr.front(), arr.size(), 2);
ov.Invoke("norm", svec);
}
}
BENCHMARK(TestRefl1);
void TestRefl2(benchmark::State& state) {
int x = 1, y = 2;
constexpr auto id = GetStaticFieldID<vec3>(func);
auto field = cls->GetField(id);
for (auto _ : state) {
std::array<ArgsView, 4> arr{&x, ov.ptr};
svector<ArgsView> svec(&arr.front(), arr.size(), 2);
field->Invoke(svec);
}
}
BENCHMARK(TestRefl2);
void TestRefl3(benchmark::State& state) {
int x = 1, y = 2;
constexpr auto id = GetStaticFieldID<vec3>(func);
auto field = cls->GetField(id);
for (auto _ : state) {
field->Invoke({ &x,ov.ptr, x, y });
}
}
BENCHMARK(TestRefl3);
void TestCPlusPlus(benchmark::State& state) {
int x = 1, y = 2;
for (auto _ : state) {
x = v.norm(x, y);
}
}
BENCHMARK(TestCPlusPlus);
BENCHMARK_MAIN();