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{};
uint32_t flag{};
//unsafe
bool Invoke(const sarray<ArgsView>& ArgsList)const;
//safe
bool Invoke(std::vector<ArgsView>& ArgsList)const;
//unsafe
bool Invoke(const std::vector<ArgsView>& ArgsList)const;
template<typename R, typename... Args>
R Call(Args&&... args)const;
template<typename Func, typename... Args>
auto Call(Func func, Args&&... args)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>
class Field;
/*

View File

@ -1,18 +1,13 @@
#include "uclass.h"
namespace refl {
template<typename R, typename ...Args>
inline R FieldPtr::Call(Args&& ...args)const
template<typename Func, typename... Args>
inline auto FieldPtr::Call(Func func, Args&& ...args)const
{
using MethodType = R(*)(Args...);
MethodType fptr = (MethodType)data.method;
if constexpr (std::is_same_v<R, void>) {
fptr(std::forward<Args>(args)...);
}
else {
return fptr(std::forward<Args>(args)...);
}
using MemberFunc = decltype(fetch_method_t(func));
MemberFunc fptr = (MemberFunc)data.method;
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;
if (Call) {
Call(this, ArgsList);
@ -55,18 +50,9 @@ namespace refl {
return{};
}
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 {
public:
inline static char data[GetArgsSize<T>()]{};
inline static char data[fetch_args_size<T>()]{};
inline static int index{0};
template<typename V>
static FieldPtr MakeField(V T::* ptr, Name name)

View File

@ -15,19 +15,26 @@ namespace refl {
template<typename T>
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>
struct TypeInfoImpl;
template<typename T>
struct real_type {
using type = std::remove_cv_t<std::remove_reference_t<T>>;
using type = std::remove_cv_t<T>;
};
template<typename T>
struct real_type<T&> {
using type = std::remove_cv_t<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;
//转化为指针类型

View File

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

View File

@ -14,6 +14,9 @@ namespace refl {
cls.vtable.InitObject = &MyUClass::InitObject<T>;
cls.vtable.CopyObject = &MyUClass::CopyObject<T>;
}
else {
cls.flag = CLASS_TRIVIAL_FLAG;
}
return cls;
}
void Set(void* ptr,const T& t) {
@ -42,30 +45,25 @@ namespace refl {
auto& UList = static_cast<const MyUClass*>(cls)->UList;
return { UList.data(), UList.data() + UList.size() };
}
static R Call(const FieldPtr* field, Args... args) {
MethodType fptr = (MethodType)field->data.method;
if constexpr (std::is_same_v<R, void>) {
fptr(args...);
}
else {
return fptr(args...);
}
}
static void Call(const FieldPtr* field, const std::vector<ArgsView>& ArgsList) {
//这里顺序似乎是不确定的,但是我实际运用是对的
//如果使用make_index_sequence,会多一次函数调用
//为什么包裹一层迭代器,就不会出现警告了
static void Call(const FieldPtr* field, const sarray<ArgsView>& ArgsList) {
assert(sizeof...(Args) <= ArgsList.size());
if constexpr (std::is_same_v<R, void>) {
MethodType fptr = (MethodType)field->data.method;
auto param = ArgsList.rbegin();
fptr(param++->cast_to<Args>()...);
auto param = ArgsList.end();
fptr((param--->cast_to<Args>())...);
}
else {
MethodType fptr = (MethodType)field->data.method;
auto param = ArgsList.rbegin();
auto ret = ArgsList.begin();
auto param = ArgsList.end();
auto ret = ArgsList.get();
if (ret->cls == &TypeInfo<R*>::StaticClass) {
*(R*)ret->val = fptr(param++->cast_to<Args>()...);
*(R*)ret->val = fptr((param--->cast_to<Args>())...);
}
else {
fptr(param++->cast_to<Args>()...);
fptr((param--->cast_to<Args>())...);
}
}
}
@ -76,7 +74,7 @@ namespace refl {
}
if constexpr (sizeof...(Args) > 0) {
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:
@ -85,48 +83,20 @@ namespace refl {
MyUClass cls(type_name<MethodType>().View(), sizeof(MethodType));
cls.vtable.GetParams = &MyUClass::GetParams;
cls.vtable.Call = &MyUClass::Call;
cls.flag = CLASS_TRIVIAL_FLAG;
cls.BuildUList();
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>
class UClass_Meta : public UClass {
public:
using FieldsType = decltype(T::__MakeFields());
FieldsType Fields{ T::__MakeFields() };
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>) {
parent = &TypeInfo<P>::StaticClass;
}

View File

@ -16,15 +16,14 @@ namespace refl {
//左值=>caller变量地址
template<typename T>
constexpr ArgsView(T&& v): val(&v), cls(&TypeInfo<args_type_t<T>*>::StaticClass){
if constexpr (std::is_same_v<args_type_t<T>, void*>) {
val = v;
cls = &TypeInfo<args_type_t<T>>::StaticClass;
}
else if constexpr (std::is_same_v<args_type_t<T>, ArgsView>) {
if constexpr (std::is_same_v<args_type_t<T>, ArgsView>) {
val = v.val;
cls = v.cls;
}
}
template<typename T>
constexpr ArgsView(T* v) : val(v), cls(&TypeInfo<args_type_t<T>*>::StaticClass) {
}
template<typename T>//参数 T* => T*
constexpr inline T cast_to() const {
if constexpr (std::is_pointer_v<T>) {
@ -61,7 +60,7 @@ namespace refl {
struct ArgsValueList{
void* data;
ArgsView* ptr;
int num{0};
int num;
bool isMemoryOwner{false};
ArgsValueList(const sarray<ArgsValue>& args,void* memory = nullptr);
~ArgsValueList();
@ -69,10 +68,10 @@ namespace refl {
};
class ObjectView {
public:
const char* ptr;
const void* ptr;
const UClass* cls;
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:
template<typename T>
@ -81,7 +80,7 @@ namespace refl {
template<typename 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);

View File

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

View File

@ -27,8 +27,9 @@ namespace refl {
FieldPtr::Data method = { offset };
return { name, &TypeInfo<real_type_t<R>(*)(const void*,real_type_t<Args>...)>::StaticClass, method, value,flag };
}
//用处不大---------------begin
template<typename T>
consteval int GetStaticField(Name name) {
consteval int GetStaticFieldID(Name name) {
auto fields = T::__MakeStaticFields();
auto first = fields.begin();
for (auto& field : fields) {
@ -39,7 +40,7 @@ namespace refl {
return 0;
}
template<typename T>
consteval int GetStaticField(bool(* fptr)(FieldPtr)) {
consteval int GetStaticFieldID(bool(* fptr)(FieldPtr)) {
auto fields = T::__MakeStaticFields();
auto first = fields.begin();
for (auto& field : fields) {
@ -49,4 +50,17 @@ namespace refl {
}
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
#include <vector>
#include <concepts>
namespace refl {
template<typename T>
@ -7,26 +8,32 @@ namespace refl {
const T* m_ptr;
int m_size;
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{
const T* get() const noexcept {
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) {
return m_ptr + i;
}
return nullptr;
}
constexpr int size() const {
constexpr int size() const noexcept {
return m_size;
}
constexpr const auto begin()const {
constexpr auto begin()const noexcept {
return iterator{ m_ptr };
}
constexpr const auto end() const {
constexpr auto end() const noexcept {
return iterator{ m_ptr + m_size};
}
// Iterator class
@ -38,18 +45,25 @@ namespace refl {
constexpr iterator(const T* p) : ptr(p) {}
// Overload ++ to move to next element
constexpr iterator& operator++() {
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 {
constexpr const T& operator*() const noexcept {
return *ptr;
}
// Overload != to compare iterators
constexpr bool operator!=(const iterator& other) const {
constexpr bool operator!=(const iterator& other) const noexcept {
return ptr != other.ptr;
}
};

View File

@ -14,11 +14,11 @@ struct vec3 : public vec3_parent {
float z = 3;
string name{ "hellohellohellohellohellohello" };
void norm(int x1, int& x2)override {
//x2 = x1 * x2;
//cout << x2 << "vec3::norm" << endl;
x2 = x1 * x2;
cout << x2 << "vec3::norm" << endl;
}
virtual float norm1(int& x1) {
//x1 = x1 * x * y * z;
x1 = x1 * x * y * z;
//x = x1;
//y = x1 - 1;
//z = x1 - 10;
@ -26,13 +26,17 @@ struct vec3 : public vec3_parent {
return x1;
}
static void norm2(int x1 = 10) {
//cout << x1 << "::norm2" << endl;
cout << x1 << "::norm2" << endl;
}
static void norm3(int x1 = 10) {
x1 = x1 * 10;
//cout << x1 << "::norm3" << endl;
cout << x1 << "::norm3" << endl;
}
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() {
return std::array{
MakeStaticField(&vec3::x, "x"),

View File

@ -1,23 +1,23 @@
#include "refl/vertex.h"
#include "refl/std/sarray.h"
#include <array>
struct object {
};
template<typename T>
void testInitObject(){
if constexpr (has_init_object<T>::value){
auto InitObject = &T::__InitObject;
}
}
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 field = cls.GetField(GetStaticField<vec3>("norm"));
auto field = cls.GetField(GetStaticFieldID<vec3>("norm"));
auto ov = cls.New();
int x = 10;
auto ov = cls.New<vec3>();
ov->norm(x, x);
field->Call<void>((void*)ov, 10, x);
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;
}