zengine-old/engine/3rdparty/zlib/include/refl/detail/uclass.inl

142 lines
4.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include "uclass.h"
namespace refl {
template<_ReflCheck_Ctor T>
class UClass_Auto : public UClass {
public:
using UClass::UClass;
using MyUClass = UClass_Auto<T>;
public:
constexpr static MyUClass BuildClass() {
MyUClass cls(type_name<T>().View(), sizeof(T));
if constexpr (!std::is_trivially_copyable_v<T>) {
cls.vtable.InitObject = &MyUClass::InitObject<T>;
cls.vtable.CopyObject = &MyUClass::CopyObject<T>;
}
return cls;
}
};
/*
* 模板优化
* 成员参数转化为const void*
* 引用参数转化为指针
* 返回引用转化为指针
*/
template<typename R, typename... Args>
class UMethod_Auto : public UClass {
using UClass::UClass;
using MethodType = R(*)(Args...);
using MyUClass = UMethod_Auto<R, Args...>;
public:
std::array<const UClass*, sizeof...(Args) + 1> UList{};
static std::vector<const UClass*> GetParams(const UClass* cls) {
auto& UList = static_cast<const MyUClass*>(cls)->UList;
return { UList.data(), UList.data() + UList.size() };
}
static void Call(const FieldPtr& field, std::vector<ArgsView>& ArgsList) {
if constexpr (std::is_same_v<R, void>) {
MethodType fptr = (MethodType)field.data.method;
auto param = ArgsList.rbegin();
fptr(param++->cast_to<Args>()...);
}
else {
MethodType fptr = (MethodType)field.data.method;
auto param = ArgsList.rbegin();
auto ret = ArgsList.begin();
if (ret->cls == &TypeInfo<R*>::StaticClass) {
*(R*)ret->val = fptr(param++->cast_to<Args>()...);
}
else {
fptr(param++->cast_to<Args>()...);
}
}
}
protected:
constexpr void BuildUList() {
if constexpr (!std::is_same_v<R, void>) {
UList[0] = &TypeInfo<R*>::StaticClass;
}
if constexpr (sizeof...(Args) > 0) {
auto ptr = &UList[1];
(..., (*ptr = &TypeInfo<std::remove_pointer_t<Args>*>::StaticClass, ptr++));
}
}
public:
//为了简化判断cls 对象 统统指向 T*
constexpr static MyUClass BuildClass() {
MyUClass cls(type_name<MethodType>().View(), sizeof(MethodType));
cls.vtable.GetParams = &MyUClass::GetParams;
cls.vtable.Call = &MyUClass::Call;
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<_ReflCheck_Ctor_NoUClass T>
struct TypeInfoImpl<T> {
using UClass = UClass_Auto<T>;
inline constexpr static UClass StaticClass = UClass::BuildClass();
};
// 函数指针类型的偏特化
template<typename R, typename... Args>
struct TypeInfoImpl<R(*)(Args...)> {
using UClass = UMethod_Auto<R, Args...>;
inline constexpr static UClass StaticClass = UClass::BuildClass();
};
template<_ReflCheck_UClass T>
struct TypeInfoImpl<T> {
using MyUClass = typename T::MyUClass;
inline static MyUClass StaticClass = []()->MyUClass {
MyUClass cls(type_name<T>().View(), sizeof(T));
T::BuildClass(cls);
auto& vtable = cls.vtable;
if (!vtable.GetField) {
vtable.GetField = &MyUClass::GetField;
}
if constexpr (!std::is_trivially_copyable_v<T>) {
if (!vtable.InitObject) {
//这里一定会创建一个InitObject<T> 模板函数,如何优化
vtable.InitObject = &UClass::InitObject<T>;
}
if (!vtable.CopyObject) {
//这里一定会创建一个CopyObject<T> 模板函数,如何优化
vtable.CopyObject = &UClass::CopyObject<T>;
}
}
return cls;
}();
};
}