From a5bfccc1d8b4391cd668937ae0a3c9bfa99c096b Mon Sep 17 00:00:00 2001 From: ouczbs Date: Wed, 12 Jun 2024 22:07:45 +0800 Subject: [PATCH] refl support ctor list --- .../zlib/include/refl/detail/convert.inl | 4 +- .../3rdparty/zlib/include/refl/detail/field.h | 7 +- .../zlib/include/refl/detail/field.inl | 21 +++- .../3rdparty/zlib/include/refl/detail/meta.h | 3 + .../zlib/include/refl/detail/meta.inl | 28 ++++- .../zlib/include/refl/detail/uclass.h | 103 ++++++++++-------- .../zlib/include/refl/detail/uclass.inl | 90 ++++++++++----- .../3rdparty/zlib/include/refl/detail/view.h | 2 + .../zlib/include/refl/detail/view.inl | 68 ++++++++---- engine/3rdparty/zlib/include/refl/refl.h | 13 +++ engine/3rdparty/zlib/include/zstd/sarray.h | 9 +- 11 files changed, 243 insertions(+), 105 deletions(-) diff --git a/engine/3rdparty/zlib/include/refl/detail/convert.inl b/engine/3rdparty/zlib/include/refl/detail/convert.inl index c85d06a..3db86b2 100644 --- a/engine/3rdparty/zlib/include/refl/detail/convert.inl +++ b/engine/3rdparty/zlib/include/refl/detail/convert.inl @@ -12,9 +12,7 @@ namespace refl { } inline bool Convert::Construct(Any& dst, const Any& src) { - if (dst.Check(src.cls)) { - dst.cls->parent->InitObject((void*)dst.ptr); - dst.cls->parent->CopyObject((void*)dst.ptr, src.ptr); + if (dst.cls->CtorObject((void*)dst.ptr, src)) { return true; } auto it = ClassMap.find(dst.cls); diff --git a/engine/3rdparty/zlib/include/refl/detail/field.h b/engine/3rdparty/zlib/include/refl/detail/field.h index 9ced667..bd43889 100644 --- a/engine/3rdparty/zlib/include/refl/detail/field.h +++ b/engine/3rdparty/zlib/include/refl/detail/field.h @@ -36,7 +36,9 @@ namespace refl { FIELD_MEMBER_FLAG = 1 << 0, FIELD_ATTRIBUTE_FLAG = 1 << 1, FIELD_METHOD_FLAG = 1 << 2, - FIELD_METHOD_VALUE_FLAG = 1 << 3 + FIELD_METHOD_VALUE_FLAG = 1 << 3, + FIELD_CTOR_FLAG = 1 << 4, + FIELD_CTOR_VALUE_FLAG = 1 << 5, }; using enum FieldFlag; struct FieldPtr { @@ -61,6 +63,9 @@ namespace refl { //safe bool Invoke(svector& ArgsList)const; + template + bool Invokes(TArgsList& ArgsList)const; + template auto Call(Func func, Args&&... args)const; diff --git a/engine/3rdparty/zlib/include/refl/detail/field.inl b/engine/3rdparty/zlib/include/refl/detail/field.inl index 7455487..9e39491 100644 --- a/engine/3rdparty/zlib/include/refl/detail/field.inl +++ b/engine/3rdparty/zlib/include/refl/detail/field.inl @@ -34,7 +34,7 @@ namespace refl { if (argsSize < paramsSize) { return false; } - Any* a = ArgsList.front(); + auto a = ArgsList.front(); auto p = params.front(); for (auto e = params.back(); p < e; ++p, ++a) { if (a->cls != *p && !a->Check(*p)) { @@ -45,6 +45,25 @@ namespace refl { } return Call; } + template + inline bool FieldPtr::Invokes(TArgsList& ArgsList)const { + auto Call = type->vtable.Call; + if (Call) { + sarray params = GetParams(); + if (params.size() != ArgsList.size()) { + return false; + } + auto a = ArgsList.front(); + auto p = params.front(); + for (auto e = params.back(); p < e; ++p, ++a) { + if (a->cls != *p && !a->Check(*p)) { + return false; + } + } + Call(this, ArgsList); + } + return false; + } inline sarray FieldPtr::GetParams() const { auto GetParams = type->vtable.GetParams; if (GetParams) { diff --git a/engine/3rdparty/zlib/include/refl/detail/meta.h b/engine/3rdparty/zlib/include/refl/detail/meta.h index 8531762..c0f13d0 100644 --- a/engine/3rdparty/zlib/include/refl/detail/meta.h +++ b/engine/3rdparty/zlib/include/refl/detail/meta.h @@ -31,6 +31,9 @@ namespace refl { class UClass; class Meta { public: + template + static FieldPtr CtorField(char*& memory, const MemberData& data = {}); + template static FieldPtr MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberData& data = {}); diff --git a/engine/3rdparty/zlib/include/refl/detail/meta.inl b/engine/3rdparty/zlib/include/refl/detail/meta.inl index b846844..84a4010 100644 --- a/engine/3rdparty/zlib/include/refl/detail/meta.inl +++ b/engine/3rdparty/zlib/include/refl/detail/meta.inl @@ -3,7 +3,29 @@ #include "uclass.h" #include "convert.h" namespace refl { - + template + inline FieldPtr Meta::CtorField(char*& memory, const MemberData& data) + { + MethodData method; + uint32_t flag = FIELD_MEMBER_FLAG | FIELD_CTOR_FLAG; + constexpr auto cls = &TypeInfo...)>::StaticClass; + if (data.value.IsValid()) { + flag |= FIELD_CTOR_VALUE_FLAG; + AnyArgs args(data.value, cls->GetParams(), memory); + method.value = args.ToSArray(); + memory += args.Size(); + } + if (data.meta.IsValid()) { + method.meta = data.meta.Change(memory); + Convert::Construct(method.meta, data.meta); + memory += data.meta.Size(); + } + static auto ptr = [](void* mem, Args... args) { + new (mem) T(std::forward(args)...); + }; + method.fptr = { *(Method*)&ptr }; + return { FName("Ctor"), cls, method,flag}; + } template inline FieldPtr Meta::MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberData& data) { @@ -29,7 +51,7 @@ namespace refl { MethodData method; uint32_t flag = FIELD_METHOD_FLAG; constexpr auto cls = &TypeInfo(*)(real_type_t...)>::StaticClass; - if (data.value.IsValid()) { + if (data.value.valid()) { flag |= FIELD_METHOD_VALUE_FLAG; AnyArgs args(data.value, cls->GetParams(), memory); method.value = args.ToSArray(); @@ -49,7 +71,7 @@ namespace refl { MethodData method; uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG; constexpr auto cls = &TypeInfo(*)(const void*, real_type_t...)>::StaticClass; - if (data.value.IsValid()) { + if (data.value.valid()) { flag |= FIELD_METHOD_VALUE_FLAG; AnyArgs args(data.value, cls->GetParams(), memory); method.value = args.ToSArray(); diff --git a/engine/3rdparty/zlib/include/refl/detail/uclass.h b/engine/3rdparty/zlib/include/refl/detail/uclass.h index 2d2c945..9126449 100644 --- a/engine/3rdparty/zlib/include/refl/detail/uclass.h +++ b/engine/3rdparty/zlib/include/refl/detail/uclass.h @@ -2,6 +2,7 @@ #include "field.h" #include "view.h" #include "meta.h" +#include "convert.h" namespace refl { enum ClassFlag :uint32_t { CLASS_NONE_FLAG = 0, @@ -10,10 +11,20 @@ namespace refl { CLASS_ARRAY_FLAG = 1 << 2, }; using enum ClassFlag; + enum EFieldFind :uint32_t { + FIND_ALL_FIELD = 0, + FIND_ALL_MEMBER, + FIND_ALL_METHOD, + FIND_FIELD, + FIND_CTOR, + FIND_MEMBER, + FIND_METHOD, + FIND_METHODS,//函数重载 特别是构造函数 + }; struct vtable_uclass { //class - const FieldPtr* (*GetField)(const UClass*, const Name&, int); + const sarray (*GetFields)(const UClass*, EFieldFind find, const Name& name); //function sarray(*GetParams)(const UClass*); //function @@ -21,9 +32,8 @@ namespace refl { //meta const UClass* (*GetMeta)(const Name&); //object - void (*InitObject)(void*); - void (*CopyObject)(void*, const void*); - void (*DestObject)(void*); + bool (*CtorObject)(void* ptr,const UClass* cls, const sarray& ArgsList); + bool (*DestObject)(void*); }; class UClass{ public: @@ -35,22 +45,22 @@ namespace refl { public: constexpr UClass(std::string_view name, uint32_t size, const UClass* parent = nullptr) :name(name), size(size), parent(parent){} - AnyView New(void* ptr = nullptr) const{ + AnyView New(void* ptr = nullptr, const sarray& ArgsList = {}) const { if (ptr == nullptr) { ptr = malloc(size); - InitObject(ptr); + CtorObject(ptr, ArgsList); } return { ptr , this }; } template - T* New(T* ptr = nullptr) const{ + T* New(T* ptr = nullptr, const sarray& ArgsList = {}) const{ if (!IsChildOf()) { return nullptr; } if (ptr == nullptr) { ptr = (T*)malloc(size); } - InitObject(ptr); + CtorObject(ptr, ArgsList); return ptr; } bool IsChildOf(const UClass* cls) const { @@ -68,27 +78,33 @@ namespace refl { return IsChildOf(&TypeInfo::StaticClass); } public: - const FieldPtr* GetField(const Name& name, int index)const { - if (vtable.GetField) { - return vtable.GetField(this, name, index); + const sarray GetFields(EFieldFind find, const Name& name)const { + if (vtable.GetFields) { + return vtable.GetFields(this, find, name); } - return nullptr; + return {}; } - void InitObject(void* ptr)const { - if (vtable.InitObject) { - vtable.InitObject(ptr); - } - else { - memset(ptr, 0, size); - } - } - void CopyObject(void* dst, const void* src)const { - if (vtable.CopyObject) { - vtable.CopyObject(dst, src); - } - else { - memcpy(dst, src, size); + bool CtorObject(void* ptr, const sarray& ArgsList = {})const { + if (vtable.CtorObject) { + if (vtable.CtorObject(ptr, this, ArgsList)) { + return true; + } + auto& fieldList = GetFields(EFieldFind::FIND_CTOR, FName("Ctor")); + if (fieldList.empty()) { + return false; + } + if (fieldList.size() == 1) { + return fieldList[0]->Invoke(ArgsList); + } + for (auto& field : fieldList) { + if (field.Invokes(ArgsList)) { + return true; + } + } + return false; } + memset(ptr, 0, size); + return true; } void DestObject(void* ptr)const { if (vtable.DestObject) { @@ -96,30 +112,23 @@ namespace refl { } } public: - template<_ReflCheck_Ctor T> - static void InitObject(void* ptr) { - T obj{}; - std::construct_at((T*)ptr, obj); - } template - static void CopyObject(void* dst, const void* src) { - *(T*)dst = *(T*)src; - } - template<_ReflCheck_Ctor T, int N> - static void InitObject(void* ptr) { - T* tptr = (T*)ptr; - T obj{}; - for (int i = 0; i < N; i++) { - std::construct_at(tptr++, obj); + static bool CtorObject(void* ptr, const UClass* cls, const sarray& ArgsList = {}) { + int size = ArgsList.size(); + if (size == 0) { + if constexpr (std::is_trivially_constructible_v) { + std::construct_at((T*)ptr); + return true; + } + else { + throw "refl::error:: no default construct function!!!"; + } } - } - template - static void CopyObject(void* dst, const void* src) { - T* tdst = (T*)dst; - const T* tsrc = (const T*)src; - for (int i = 0; i < N; i++) { - *tdst++ = *tsrc++; + if (size == 1 && ArgsList[0]->Check(cls)) { + *(T*)ptr = *(const T*)ArgsList[0]->ptr; + return true; } + return false; } }; } \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/detail/uclass.inl b/engine/3rdparty/zlib/include/refl/detail/uclass.inl index 939b36a..3b10e59 100644 --- a/engine/3rdparty/zlib/include/refl/detail/uclass.inl +++ b/engine/3rdparty/zlib/include/refl/detail/uclass.inl @@ -10,20 +10,14 @@ namespace refl { public: consteval static MyUClass BuildClass() { MyUClass cls(type_name().View(), sizeof(T)); - if constexpr (!std::is_trivially_copyable_v) { - cls.vtable.InitObject = &MyUClass::InitObject; - cls.vtable.CopyObject = &MyUClass::CopyObject; - } - else if constexpr (std::is_pointer_v){ + cls.vtable.CtorObject = &MyUClass::CtorObject; + if constexpr (std::is_pointer_v){ using RawT = std::remove_pointer_t; cls.flag = CLASS_POINTER_FLAG; if constexpr (!std::is_same_v) { cls.parent = &TypeInfo::StaticClass; } } - else { - cls.flag = CLASS_TRIVIAL_FLAG; - } if constexpr (requires {typename T::MyMetas; }) { cls.vtable.GetMeta = &T::MyMetas::GetMeta; } @@ -44,15 +38,11 @@ namespace refl { public: consteval static MyUClass BuildClass() { MyUClass cls(type_name().View(), sizeof(T) * N, &TypeInfo::StaticClass); - if constexpr (!std::is_trivially_copyable_v) { - cls.vtable.InitObject = &MyUClass::InitObject; - cls.vtable.CopyObject = &MyUClass::CopyObject; - } - else if constexpr (std::is_pointer_v) { + if constexpr (std::is_pointer_v) { cls.flag = CLASS_POINTER_FLAG | CLASS_ARRAY_FLAG; } else { - cls.flag = CLASS_TRIVIAL_FLAG | CLASS_ARRAY_FLAG; + cls.flag = CLASS_ARRAY_FLAG; } return cls; } @@ -133,32 +123,72 @@ namespace refl { if constexpr (!std::is_same_v) { parent = &TypeInfo

::StaticClass; } - if constexpr (requires(void* ptr) {T::__InitObject(ptr);}) { - vtable.InitObject = &T::__InitObject; - } - else { - vtable.InitObject = &UClass::InitObject; - } if constexpr (requires(const Name & name) { T::MyMetas::GetMeta(name); }) { vtable.GetMeta = &T::MyMetas::GetMeta; } - vtable.GetField = &UClass_Meta::GetField; + vtable.GetFields = &UClass_Meta::GetFields; } const FieldPtr* GetField(int index) const { return &Fields[index]; } - static const FieldPtr* GetField(const UClass* _cls,const Name& name, int index = 0){ - auto cls = static_cast(_cls); - auto& Fields = cls->Fields; + const sarray GetFields(EFieldFind find, const Name& name) const { constexpr int length = std::tuple_size::value; - auto ptr = index < length ? &Fields[index] : nullptr; - for (int i = index; i < length; i++, ptr++) { - if (name == ptr->name) { - return ptr; + constexpr int MemberCount = MyMeta::MyStatic::MemberCount(); + constexpr int CtorCount = MyMeta::MyStatic::CtorCount(); + switch (find) { + case EFieldFind::FIND_ALL_FIELD: + return sarray(&Fields[0], length); + case EFieldFind::FIND_ALL_MEMBER: + return sarray(&Fields[0], MemberCount); + case EFieldFind::FIND_ALL_METHOD: + return sarray(&Fields[MemberCount + CtorCount], length - MemberCount - CtorCount); + case EFieldFind::FIND_CTOR: + return sarray(&Fields[MemberCount], CtorCount); + case EFieldFind::FIND_FIELD: + for (int i = 0; i < length; i++) { + if (name == Fields[i].name) { + return sarray(&Fields[i], 1); + } } + return {}; + case EFieldFind::FIND_MEMBER: + for (int i = 0; i < MemberCount; i++) { + if (name == Fields[i].name) { + return sarray(&Fields[i], 1); + } + } + return {}; + case EFieldFind::FIND_METHOD: + for (int i = MemberCount + CtorCount; i < length; i++) { + if (name == Fields[i].name) { + return sarray(&Fields[i], 1); + } + } + return {}; + case EFieldFind::FIND_METHODS: + { + int first = 0,count = 0; + for (int i = MemberCount + CtorCount; i < length; i++) { + if (name == Fields[i].name) { + if (!count) { + first = i; + } + count++; + } + else if (count) { + return sarray(&Fields[first], count); + } + } + return {}; } - return nullptr; - } + default: + return {}; + } + } + static const sarray GetFields(const UClass* _cls, EFieldFind find, const Name& name) { + auto cls = static_cast(_cls); + return cls->GetFields(find, name); + } }; //基础类型的偏特化 diff --git a/engine/3rdparty/zlib/include/refl/detail/view.h b/engine/3rdparty/zlib/include/refl/detail/view.h index ca1b01b..ba9fc38 100644 --- a/engine/3rdparty/zlib/include/refl/detail/view.h +++ b/engine/3rdparty/zlib/include/refl/detail/view.h @@ -29,6 +29,8 @@ namespace refl { bool Invoke(const Name& name,svector& ArgsList); + bool Invokes(const Name& name, const sarray& ArgsList); + bool Invokes(const Name& name, svector& ArgsList); AnyView Parent(); }; } \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/refl/detail/view.inl b/engine/3rdparty/zlib/include/refl/detail/view.inl index fcbdce3..428332c 100644 --- a/engine/3rdparty/zlib/include/refl/detail/view.inl +++ b/engine/3rdparty/zlib/include/refl/detail/view.inl @@ -12,13 +12,7 @@ namespace refl { auto p2 = toClass->parent; assert(p1 && p2); //子类转父类 - if (p1->IsChildOf(p2)) { - return true; - } - if (p1->flag & CLASS_TRIVIAL_FLAG && p2->flag & CLASS_TRIVIAL_FLAG && p1->size >= p2->size) { - return true; - } - return false; + return p1->IsChildOf(p2); } inline constexpr int Any::Size()const { @@ -94,9 +88,9 @@ namespace refl { } return isChild; } - auto field = cls->GetField(name, 0); - if (field) { - cache = field; + auto& fieldList = cls->GetFields(EFieldFind::FIND_MEMBER, name); + if (fieldList.valid()) { + cache = fieldList.front(); goto _cache_get; } if (cls->parent) { @@ -114,9 +108,9 @@ namespace refl { } return isChild; } - auto field = cls->GetField(name, 0); - if (field) { - cache = field; + auto& fieldList = cls->GetFields(EFieldFind::FIND_MEMBER, name); + if (fieldList.valid()) { + cache = fieldList.front(); goto _cache_set; } if (cls->parent) { @@ -126,25 +120,61 @@ namespace refl { } inline bool AnyView::Invoke(const Name& name,const sarray& ArgsList) { - auto field = cls->GetField(name, 0); - if (!field) { + auto& fieldList = cls->GetFields(EFieldFind::FIND_METHOD, name); + if (fieldList.empty()) { if (cls->parent) { return Parent().Invoke(name, ArgsList); } return false; } - return field->Invoke(ArgsList); + return fieldList[0]->Invoke(ArgsList); } inline bool AnyView::Invoke(const Name& name, svector& ArgsList) { - auto field = cls->GetField(name, 0); - if (!field) { + auto fieldList = cls->GetFields(EFieldFind::FIND_METHOD, name); + if (fieldList.empty()) { if (cls->parent) { return Parent().Invoke(name, ArgsList); } return false; } - return field->Invoke(ArgsList); + return fieldList[0]->Invoke(ArgsList); + } + inline bool AnyView::Invokes(const Name& name, const sarray& ArgsList) + { + auto fieldList = cls->GetFields(EFieldFind::FIND_METHOD, name); + if (fieldList.empty()) { + if (cls->parent) { + return Parent().Invoke(name, ArgsList); + } + return false; + } + if(fieldList.size() == 1) + return fieldList[0]->Invoke(ArgsList); + for (auto& field : fieldList) { + if (field.Invokes(ArgsList)) { + return true; + } + } + return false; + } + inline bool AnyView::Invokes(const Name& name, svector& ArgsList) + { + auto fieldList = cls->GetFields(EFieldFind::FIND_METHOD, name); + if (fieldList.empty()) { + if (cls->parent) { + return Parent().Invoke(name, ArgsList); + } + return false; + } + if (fieldList.size() == 1) + return fieldList[0]->Invoke(ArgsList); + for (auto& field : fieldList) { + if (field.Invokes(ArgsList)) { + return true; + } + } + return false; } inline AnyView AnyView::Parent() { return { ptr, cls ? cls->parent : nullptr }; diff --git a/engine/3rdparty/zlib/include/refl/refl.h b/engine/3rdparty/zlib/include/refl/refl.h index b61798a..8454e56 100644 --- a/engine/3rdparty/zlib/include/refl/refl.h +++ b/engine/3rdparty/zlib/include/refl/refl.h @@ -6,6 +6,17 @@ #include "detail/meta.inl" #include "macro.h" namespace refl { + template + consteval FieldPtr StaticCtorField(const MemberData& data = {}) { + uint32_t flag = FIELD_CTOR_FLAG; + auto cls = &TypeInfo...)>::StaticClass; + Offset offset = AnyArgs::GetArgsSize(data.value, cls->GetParams()); + if (data.meta.IsValid()) { + offset += data.meta.Size(); + } + FieldPtr::Data method(offset); + return {FName("Ctor"),cls,method, flag}; + } template consteval FieldPtr StaticMemberField(T Obj::* ptr, const Name& name, const MemberData& data = {}) { Offset offset = data.value.IsValid() ? sizeof(T) : 0; @@ -38,6 +49,7 @@ namespace refl { FieldPtr::Data method(offset); return { name, cls,method,flag }; } + /* //用处不大---------------begin template<_ReflCheck_Meta T> consteval int GetStaticFieldID(const Name& name) { @@ -74,4 +86,5 @@ namespace refl { } } //用处不大---------------end + */ } \ No newline at end of file diff --git a/engine/3rdparty/zlib/include/zstd/sarray.h b/engine/3rdparty/zlib/include/zstd/sarray.h index 4eb96d5..e50f045 100644 --- a/engine/3rdparty/zlib/include/zstd/sarray.h +++ b/engine/3rdparty/zlib/include/zstd/sarray.h @@ -8,6 +8,7 @@ namespace zstd { const T* m_ptr; int m_count; public: + constexpr sarray(const T& ptr) : m_ptr(&ptr), m_count(1) {} constexpr sarray(const T* ptr, int count) : m_ptr(ptr), m_count(count) {} constexpr sarray(const svector& vec) : m_ptr(vec.front()), m_count(vec.size()) {} constexpr sarray() : m_ptr(nullptr), m_count(0) {} @@ -24,7 +25,13 @@ namespace zstd { } return nullptr; } - constexpr bool IsValid() const noexcept { + constexpr const T* operator[](int i) const noexcept { + if (i < m_count) { + return m_ptr + i; + } + return nullptr; + } + constexpr bool valid() const noexcept { return m_count > 0; } constexpr bool empty() const noexcept {