rebuild refl

This commit is contained in:
ouczbs 2024-04-15 19:53:39 +08:00
parent a960cb0098
commit 5814d973d7
11 changed files with 143 additions and 120 deletions

View File

@ -46,16 +46,35 @@ namespace refl {
Default value{}; Default value{};
uint32_t flag{}; uint32_t flag{};
//unsafe
bool Invoke(const sarray<ArgsView>& ArgsList)const;
//safe //safe
bool Invoke(std::vector<ArgsView>& ArgsList)const; bool Invoke(std::vector<ArgsView>& ArgsList)const;
//unsafe
bool Invoke(const std::vector<ArgsView>& ArgsList)const;
template<typename R, typename... Args> template<typename Func, typename... Args>
R Call(Args&&... args)const; auto Call(Func func, Args&&... args)const;
std::vector<const UClass*> GetParams() const; std::vector<const UClass*> GetParams() const;
}; };
template<typename T, typename R, typename ...Args>
consteval auto fetch_method_t(R(T::*)(Args...)) {
using MethodType = R(*)(const void*, Args...);
return MethodType{ nullptr };
}
template<typename R, typename ...Args>
consteval auto fetch_method_t(R(*)(Args...)) {
using MethodType = R(*)(Args...);
return MethodType{ nullptr };
}
template<typename T>
consteval int fetch_args_size() {
auto fields = T::__MakeStaticFields();
int size = 0;
for (auto& field : fields) {
size += field.data.offset;
}
return size;
}
template<typename T> template<typename T>
class Field; class Field;
/* /*

View File

@ -1,18 +1,13 @@
#include "uclass.h" #include "uclass.h"
namespace refl { namespace refl {
template<typename R, typename ...Args> template<typename Func, typename... Args>
inline R FieldPtr::Call(Args&& ...args)const inline auto FieldPtr::Call(Func func, Args&& ...args)const
{ {
using MethodType = R(*)(Args...); using MemberFunc = decltype(fetch_method_t(func));
MethodType fptr = (MethodType)data.method; MemberFunc fptr = (MemberFunc)data.method;
if constexpr (std::is_same_v<R, void>) { return fptr(std::forward<Args>(args)...);
fptr(std::forward<Args>(args)...);
}
else {
return fptr(std::forward<Args>(args)...);
}
} }
bool FieldPtr::Invoke(const std::vector<ArgsView>& ArgsList)const{ bool FieldPtr::Invoke(const sarray<ArgsView>& ArgsList)const{
auto Call = type->vtable.Call; auto Call = type->vtable.Call;
if (Call) { if (Call) {
Call(this, ArgsList); Call(this, ArgsList);
@ -55,18 +50,9 @@ namespace refl {
return{}; return{};
} }
template<typename T> template<typename T>
consteval int GetArgsSize() {
auto fields = T::__MakeStaticFields();
int size = 0;
for (auto& field : fields) {
size += field.data.offset;
}
return size;
}
template<typename T>
class Field { class Field {
public: public:
inline static char data[GetArgsSize<T>()]{}; inline static char data[fetch_args_size<T>()]{};
inline static int index{0}; inline static int index{0};
template<typename V> template<typename V>
static FieldPtr MakeField(V T::* ptr, Name name) static FieldPtr MakeField(V T::* ptr, Name name)

View File

@ -15,19 +15,26 @@ namespace refl {
template<typename T> template<typename T>
struct has_init_object<T, std::void_t<decltype(&T::__InitObject)>> : std::true_type {}; struct has_init_object<T, std::void_t<decltype(&T::__InitObject)>> : std::true_type {};
//template<typename T>error::"expected unqualified-id"
//using has_init_object_v = has_init_object<T>::value;
//类型接口 //类型接口
template<typename T> template<typename T>
struct TypeInfoImpl; struct TypeInfoImpl;
template<typename T> template<typename T>
struct real_type { struct real_type {
using type = std::remove_cv_t<std::remove_reference_t<T>>; using type = std::remove_cv_t<T>;
}; };
template<typename T> template<typename T>
struct real_type<T&> { struct real_type<T&> {
using type = std::remove_cv_t<T>*; using type = std::remove_cv_t<T>*;
}; };
template<typename T> template<typename T>
struct real_type<T*> {
using type = std::remove_cv_t<T>*;
};
template<typename T>
using real_type_t = real_type<T>::type; using real_type_t = real_type<T>::type;
//转化为指针类型 //转化为指针类型

View File

@ -3,6 +3,10 @@
#include "field.h" #include "field.h"
#include "view.h" #include "view.h"
namespace refl { namespace refl {
enum ClassFlag :uint32_t {
CLASS_NONE_FLAG = 0,
CLASS_TRIVIAL_FLAG = 1 << 0,
};
struct vtable_uclass struct vtable_uclass
{ {
//class //class
@ -10,7 +14,7 @@ namespace refl {
//function //function
std::vector<const UClass*>(*GetParams)(const UClass*); std::vector<const UClass*>(*GetParams)(const UClass*);
//function //function
void (*Call)(const FieldPtr*, const std::vector<ArgsView>&); void (*Call)(const FieldPtr*, const sarray<ArgsView>& ArgsList);
//object //object
void (*InitObject)(void*); void (*InitObject)(void*);
@ -18,11 +22,12 @@ namespace refl {
void (*DestObject)(void*); void (*DestObject)(void*);
}; };
class UClass{ class UClass{
using enum FieldFlag;
public: public:
using enum FieldFlag;
using enum ClassFlag;
Name name; Name name;
uint32_t size; uint32_t size;
//uint32_t flag; uint32_t flag{0};
const UClass* parent; const UClass* parent;
vtable_uclass vtable{}; vtable_uclass vtable{};
public: public:

View File

@ -14,6 +14,9 @@ namespace refl {
cls.vtable.InitObject = &MyUClass::InitObject<T>; cls.vtable.InitObject = &MyUClass::InitObject<T>;
cls.vtable.CopyObject = &MyUClass::CopyObject<T>; cls.vtable.CopyObject = &MyUClass::CopyObject<T>;
} }
else {
cls.flag = CLASS_TRIVIAL_FLAG;
}
return cls; return cls;
} }
void Set(void* ptr,const T& t) { void Set(void* ptr,const T& t) {
@ -42,30 +45,25 @@ namespace refl {
auto& UList = static_cast<const MyUClass*>(cls)->UList; auto& UList = static_cast<const MyUClass*>(cls)->UList;
return { UList.data(), UList.data() + UList.size() }; return { UList.data(), UList.data() + UList.size() };
} }
static R Call(const FieldPtr* field, Args... args) { //这里顺序似乎是不确定的,但是我实际运用是对的
MethodType fptr = (MethodType)field->data.method; //如果使用make_index_sequence,会多一次函数调用
if constexpr (std::is_same_v<R, void>) { //为什么包裹一层迭代器,就不会出现警告了
fptr(args...); static void Call(const FieldPtr* field, const sarray<ArgsView>& ArgsList) {
} assert(sizeof...(Args) <= ArgsList.size());
else {
return fptr(args...);
}
}
static void Call(const FieldPtr* field, const std::vector<ArgsView>& ArgsList) {
if constexpr (std::is_same_v<R, void>) { if constexpr (std::is_same_v<R, void>) {
MethodType fptr = (MethodType)field->data.method; MethodType fptr = (MethodType)field->data.method;
auto param = ArgsList.rbegin(); auto param = ArgsList.end();
fptr(param++->cast_to<Args>()...); fptr((param--->cast_to<Args>())...);
} }
else { else {
MethodType fptr = (MethodType)field->data.method; MethodType fptr = (MethodType)field->data.method;
auto param = ArgsList.rbegin(); auto param = ArgsList.end();
auto ret = ArgsList.begin(); auto ret = ArgsList.get();
if (ret->cls == &TypeInfo<R*>::StaticClass) { if (ret->cls == &TypeInfo<R*>::StaticClass) {
*(R*)ret->val = fptr(param++->cast_to<Args>()...); *(R*)ret->val = fptr((param--->cast_to<Args>())...);
} }
else { else {
fptr(param++->cast_to<Args>()...); fptr((param--->cast_to<Args>())...);
} }
} }
} }
@ -76,7 +74,7 @@ namespace refl {
} }
if constexpr (sizeof...(Args) > 0) { if constexpr (sizeof...(Args) > 0) {
auto ptr = &UList[1]; auto ptr = &UList[1];
(..., (*ptr = &TypeInfo<std::remove_pointer_t<Args>*>::StaticClass, ptr++)); (..., (*ptr = &TypeInfo<std::remove_cv_t<std::remove_pointer_t<Args>>*>::StaticClass, ptr++));
} }
} }
public: public:
@ -85,48 +83,20 @@ namespace refl {
MyUClass cls(type_name<MethodType>().View(), sizeof(MethodType)); MyUClass cls(type_name<MethodType>().View(), sizeof(MethodType));
cls.vtable.GetParams = &MyUClass::GetParams; cls.vtable.GetParams = &MyUClass::GetParams;
cls.vtable.Call = &MyUClass::Call; cls.vtable.Call = &MyUClass::Call;
cls.flag = CLASS_TRIVIAL_FLAG;
cls.BuildUList(); cls.BuildUList();
return cls; return cls;
} }
}; };
/*
class UClass_Custom : public UClass {
public:
using UClass::UClass;
std::vector<FieldPtr> FList{};
int32_t AttrNum{ 0 };
static const FieldPtr* GetField(const UClass* _cls,const Name& name, bool isMethod){
auto cls = static_cast<const UClass_Custom*>(_cls);
auto& FList = cls->FList;
// 指定开始位置的迭代器
auto start = FList.begin();
if (isMethod) {
start += cls->AttrNum;
}
auto end = FList.end();
for (auto it = start; it != end; ++it) {
if (it->name == name) {
return &*it;
}
}
return nullptr;
}
void BuildClass() {
FList.shrink_to_fit();//缩减容量FList大小不再改变了
vtable.GetField = &UClass_Custom::GetField;
}
};*/
template<typename T, typename P = void> template<typename T, typename P = void>
class UClass_Meta : public UClass { class UClass_Meta : public UClass {
public: public:
using FieldsType = decltype(T::__MakeFields()); using FieldsType = decltype(T::__MakeFields());
FieldsType Fields{ T::__MakeFields() }; FieldsType Fields{ T::__MakeFields() };
UClass_Meta() : UClass(type_name<T>().View(), sizeof(T)){ UClass_Meta() : UClass(type_name<T>().View(), sizeof(T)){
if constexpr (std::is_trivially_copyable_v<T>) {
flag = CLASS_TRIVIAL_FLAG;
}
if constexpr (!std::is_same_v<P, void>) { if constexpr (!std::is_same_v<P, void>) {
parent = &TypeInfo<P>::StaticClass; parent = &TypeInfo<P>::StaticClass;
} }

View File

@ -16,15 +16,14 @@ namespace refl {
//左值=>caller变量地址 //左值=>caller变量地址
template<typename T> template<typename T>
constexpr ArgsView(T&& v): val(&v), cls(&TypeInfo<args_type_t<T>*>::StaticClass){ constexpr ArgsView(T&& v): val(&v), cls(&TypeInfo<args_type_t<T>*>::StaticClass){
if constexpr (std::is_same_v<args_type_t<T>, void*>) { if constexpr (std::is_same_v<args_type_t<T>, ArgsView>) {
val = v;
cls = &TypeInfo<args_type_t<T>>::StaticClass;
}
else if constexpr (std::is_same_v<args_type_t<T>, ArgsView>) {
val = v.val; val = v.val;
cls = v.cls; cls = v.cls;
} }
} }
template<typename T>
constexpr ArgsView(T* v) : val(v), cls(&TypeInfo<args_type_t<T>*>::StaticClass) {
}
template<typename T>//参数 T* => T* template<typename T>//参数 T* => T*
constexpr inline T cast_to() const { constexpr inline T cast_to() const {
if constexpr (std::is_pointer_v<T>) { if constexpr (std::is_pointer_v<T>) {
@ -61,7 +60,7 @@ namespace refl {
struct ArgsValueList{ struct ArgsValueList{
void* data; void* data;
ArgsView* ptr; ArgsView* ptr;
int num{0}; int num;
bool isMemoryOwner{false}; bool isMemoryOwner{false};
ArgsValueList(const sarray<ArgsValue>& args,void* memory = nullptr); ArgsValueList(const sarray<ArgsValue>& args,void* memory = nullptr);
~ArgsValueList(); ~ArgsValueList();
@ -69,10 +68,10 @@ namespace refl {
}; };
class ObjectView { class ObjectView {
public: public:
const char* ptr; const void* ptr;
const UClass* cls; const UClass* cls;
const FieldPtr* cache{ nullptr }; const FieldPtr* cache{ nullptr };
ObjectView(const void* ptr, const UClass* cls) : ptr((const char*)ptr), cls(cls) {} ObjectView(const void* ptr, const UClass* cls) : ptr(ptr), cls(cls) {}
public: public:
template<typename T> template<typename T>
@ -81,7 +80,7 @@ namespace refl {
template<typename T> template<typename T>
bool Set(const Name& name, const T& t); bool Set(const Name& name, const T& t);
bool Invoke(const Name& name,const std::vector<ArgsView>& ArgsList);//这里是内存分配慢呀,这里是可以改成栈容器的 bool Invoke(const Name& name,const sarray<ArgsView>& ArgsList);//这里是内存分配慢呀,这里是可以改成栈容器的
bool Invoke(const Name& name,std::vector<ArgsView>& ArgsList); bool Invoke(const Name& name,std::vector<ArgsView>& ArgsList);

View File

@ -7,12 +7,17 @@ namespace refl {
* 对象从小到大 * 对象从小到大
* 对象从大到小 * 对象从大到小
*/ */
using enum ClassFlag;
bool ArgsView::ConvertTo(const UClass* toClass) { bool ArgsView::ConvertTo(const UClass* toClass) {
//子类转父类 //子类转父类
if (cls->IsChildOf(toClass)) { if (cls->IsChildOf(toClass)) {
cls = toClass; cls = toClass;
return true; return true;
} }
if (cls->flag & CLASS_TRIVIAL_FLAG && toClass->flag & CLASS_TRIVIAL_FLAG) {
cls = toClass;
return true;
}
return false; return false;
} }
ArgsValueList::ArgsValueList(const sarray<ArgsValue>& args, void* memory) ArgsValueList::ArgsValueList(const sarray<ArgsValue>& args, void* memory)
@ -62,7 +67,7 @@ namespace refl {
if (cache && cache->name == name) { if (cache && cache->name == name) {
_cache_get: bool isChild = cache->type->IsChildOf<T>(true); _cache_get: bool isChild = cache->type->IsChildOf<T>(true);
if (isChild) { if (isChild) {
t = *(T*)(ptr + cache->data.offset); t = *(T*)((const char*)ptr + cache->data.offset);
} }
return isChild; return isChild;
} }
@ -82,7 +87,7 @@ namespace refl {
if (cache && cache->name == name) { if (cache && cache->name == name) {
_cache_set: bool isChild = cache->type->IsChildOf<T>(true); _cache_set: bool isChild = cache->type->IsChildOf<T>(true);
if (isChild) { if (isChild) {
*(T*)(ptr + cache->data.offset) = t; *(T*)((const char*)ptr + cache->data.offset) = t;
} }
return isChild; return isChild;
} }
@ -96,7 +101,7 @@ namespace refl {
} }
return false; return false;
} }
bool ObjectView::Invoke(const Name& name,const std::vector<ArgsView>& ArgsList) bool ObjectView::Invoke(const Name& name,const sarray<ArgsView>& ArgsList)
{ {
auto field = cls->GetField(name, true); auto field = cls->GetField(name, true);
if (!field) { if (!field) {

View File

@ -27,8 +27,9 @@ namespace refl {
FieldPtr::Data method = { offset }; FieldPtr::Data method = { offset };
return { name, &TypeInfo<real_type_t<R>(*)(const void*,real_type_t<Args>...)>::StaticClass, method, value,flag }; return { name, &TypeInfo<real_type_t<R>(*)(const void*,real_type_t<Args>...)>::StaticClass, method, value,flag };
} }
//用处不大---------------begin
template<typename T> template<typename T>
consteval int GetStaticField(Name name) { consteval int GetStaticFieldID(Name name) {
auto fields = T::__MakeStaticFields(); auto fields = T::__MakeStaticFields();
auto first = fields.begin(); auto first = fields.begin();
for (auto& field : fields) { for (auto& field : fields) {
@ -39,7 +40,7 @@ namespace refl {
return 0; return 0;
} }
template<typename T> template<typename T>
consteval int GetStaticField(bool(* fptr)(FieldPtr)) { consteval int GetStaticFieldID(bool(* fptr)(FieldPtr)) {
auto fields = T::__MakeStaticFields(); auto fields = T::__MakeStaticFields();
auto first = fields.begin(); auto first = fields.begin();
for (auto& field : fields) { for (auto& field : fields) {
@ -49,4 +50,17 @@ namespace refl {
} }
return 0; return 0;
} }
template<typename T, auto name>
consteval auto GetStaticField() {
constexpr auto fields = T::__StaticFields();
using AutoType = decltype(name);
if constexpr (std::is_same_v<AutoType, int>) {
return std::get<name>(fields);
}
else {
constexpr auto id = GetStaticFieldID<T>(Name(name.Data()));
return std::get<id>(fields);
}
}
//用处不大---------------end
} }

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <vector>
#include <concepts> #include <concepts>
namespace refl { namespace refl {
template<typename T> template<typename T>
@ -7,26 +8,32 @@ namespace refl {
const T* m_ptr; const T* m_ptr;
int m_size; int m_size;
public: 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() :m_ptr(nullptr), m_size(0) {}
constexpr sarray(std::initializer_list<T> list) : m_ptr(list.begin()), m_size(list.size()) {} constexpr sarray(std::initializer_list<T> list) : m_ptr(list.begin()), m_size(list.size()) {}
template<int N> template<int N>
constexpr sarray(const std::array<T, N>& arr):m_ptr(&arr[0]), m_size(arr.size()){} constexpr sarray(const std::array<T, N>& arr):m_ptr(&arr[0]), m_size(arr.size()){}
const T* get() const{ const T* get() const noexcept {
return m_ptr; return m_ptr;
} }
const T* at(int i) const { const T* last()const noexcept {
if (m_size > 0)
return m_ptr + m_size - 1;
return m_ptr;
}
const T* at(int i) const noexcept {
if (i < m_size) { if (i < m_size) {
return m_ptr + i; return m_ptr + i;
} }
return nullptr; return nullptr;
} }
constexpr int size() const { constexpr int size() const noexcept {
return m_size; return m_size;
} }
constexpr const auto begin()const { constexpr auto begin()const noexcept {
return iterator{ m_ptr }; return iterator{ m_ptr };
} }
constexpr const auto end() const { constexpr auto end() const noexcept {
return iterator{ m_ptr + m_size}; return iterator{ m_ptr + m_size};
} }
// Iterator class // Iterator class
@ -38,18 +45,25 @@ namespace refl {
constexpr iterator(const T* p) : ptr(p) {} constexpr iterator(const T* p) : ptr(p) {}
// Overload ++ to move to next element // Overload ++ to move to next element
constexpr iterator& operator++() { constexpr iterator& operator++() noexcept{
++ptr; ++ptr;
return *this; return *this;
} }
//这里其实是--it,而不是it--
constexpr iterator& operator--(int) noexcept {
--ptr;
return *this;
}
constexpr const T* operator->() const noexcept {
return ptr;
}
// Overload * to dereference iterator // Overload * to dereference iterator
constexpr const T& operator*() const { constexpr const T& operator*() const noexcept {
return *ptr; return *ptr;
} }
// Overload != to compare iterators // Overload != to compare iterators
constexpr bool operator!=(const iterator& other) const { constexpr bool operator!=(const iterator& other) const noexcept {
return ptr != other.ptr; return ptr != other.ptr;
} }
}; };

View File

@ -14,11 +14,11 @@ struct vec3 : public vec3_parent {
float z = 3; float z = 3;
string name{ "hellohellohellohellohellohello" }; string name{ "hellohellohellohellohellohello" };
void norm(int x1, int& x2)override { void norm(int x1, int& x2)override {
//x2 = x1 * x2; x2 = x1 * x2;
//cout << x2 << "vec3::norm" << endl; cout << x2 << "vec3::norm" << endl;
} }
virtual float norm1(int& x1) { virtual float norm1(int& x1) {
//x1 = x1 * x * y * z; x1 = x1 * x * y * z;
//x = x1; //x = x1;
//y = x1 - 1; //y = x1 - 1;
//z = x1 - 10; //z = x1 - 10;
@ -26,13 +26,17 @@ struct vec3 : public vec3_parent {
return x1; return x1;
} }
static void norm2(int x1 = 10) { static void norm2(int x1 = 10) {
//cout << x1 << "::norm2" << endl; cout << x1 << "::norm2" << endl;
} }
static void norm3(int x1 = 10) { static void norm3(int x1 = 10) {
x1 = x1 * 10; x1 = x1 * 10;
//cout << x1 << "::norm3" << endl; cout << x1 << "::norm3" << endl;
} }
using MyUClass = UClass_Meta<vec3, vec3_parent>; using MyUClass = UClass_Meta<vec3, vec3_parent>;
//这里好像不需要
consteval static auto __StaticFields() {
return std::make_tuple(&vec3::x, &vec3::y, &vec3::z, &vec3::norm, &vec3::norm1, &vec3::norm2);
};
consteval static auto __MakeStaticFields() { consteval static auto __MakeStaticFields() {
return std::array{ return std::array{
MakeStaticField(&vec3::x, "x"), MakeStaticField(&vec3::x, "x"),

View File

@ -1,23 +1,23 @@
#include "refl/vertex.h" #include "refl/vertex.h"
#include "refl/std/sarray.h" #include "refl/std/sarray.h"
#include <array> #include <array>
struct object {
};
template<typename T>
void testInitObject(){
if constexpr (has_init_object<T>::value){
auto InitObject = &T::__InitObject;
}
}
int main() { int main() {
testInitObject<object>(); auto cls1 = &TypeInfo<void*>::StaticClass;
auto cls2 = &TypeInfo<const void*>::StaticClass;
using type1 = real_type_t<const void*>;
auto& cls = TypeInfo<vec3>::StaticClass; auto& cls = TypeInfo<vec3>::StaticClass;
auto field = cls.GetField(GetStaticField<vec3>("norm")); auto field = cls.GetField(GetStaticFieldID<vec3>("norm"));
auto ov = cls.New();
int x = 10; int x = 10;
auto ov = cls.New<vec3>(); field->Call(&vec3::norm, ov.ptr, x, x);
ov->norm(x, x); field->Invoke({ov.ptr, x, x});
field->Call<void>((void*)ov, 10, 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"; std::cout << "hello world\n";
return 0; return 0;
} }