zengine-old/engine/3rdparty/zlib/include/refl/detail/uclass.inl
2024-06-21 22:21:32 +08:00

225 lines
6.8 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 <array>
#include "uclass.h"
namespace refl {
template <class T>
concept _ReflCheck_Metas = requires(const Name & name) { MetaImpl<T>::MyMetas::GetMeta(name); };
template<_ReflCheck_Ctor T>
class UClass_Auto : public UClass {
public:
using UClass::UClass;
using MyUClass = UClass_Auto<T>;
public:
consteval static MyUClass BuildClass() {
MyUClass cls(type_name<T>().View(), sizeof(T));
if constexpr (std::is_pointer_v<T>){
using RawT = std::remove_pointer_t<T>;
cls.flag = CLASS_POINTER_FLAG;
if constexpr (!std::is_same_v<RawT, void>) {
cls.parent = &TypeInfo<RawT>::StaticClass;
}
}
else {
cls.vtable.CtorObject = &MyUClass::CtorObject<T>;
}
if constexpr (_ReflCheck_Metas<T>) {
cls.vtable.GetMeta = &MetaImpl<T>::MyMetas::GetMeta;
}
return cls;
}
void Set(void* ptr,const T& t) {
*(T*)ptr = t;
}
T& Get(void* ptr) {
return *(T*)ptr;
}
};
template<_ReflCheck_Ctor T, int N>
class UClass_Array : public UClass {
public:
using UClass::UClass;
using MyUClass = UClass_Array<T, N>;
public:
consteval static MyUClass BuildClass() {
MyUClass cls(type_name<T[N]>().View(), sizeof(T) * N, &TypeInfo<T>::StaticClass);
if constexpr (std::is_pointer_v<T>) {
cls.flag = CLASS_POINTER_FLAG | CLASS_ARRAY_FLAG;
}
else {
cls.flag = CLASS_ARRAY_FLAG;
}
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{};
consteval sarray<const UClass*> GetParams()const {
return sarray<const UClass*>(&UList.front(), UList.size());
}
static sarray<const UClass*> GetParams(const UClass* cls) {
auto& UList = static_cast<const MyUClass*>(cls)->UList;
return sarray<const UClass*>(&UList.front(),UList.size());
}
//这里顺序似乎是不确定的,但是我实际运用是对的
//如果使用make_index_sequence,会多一次函数调用
//为什么包裹一层迭代器,就不会出现警告了
static void Call(const FieldPtr* field, const sarray<Any>& ArgsList) {
assert(sizeof...(Args) <= ArgsList.size());
if constexpr (std::is_same_v<R, void>) {
MethodType fptr = (MethodType)field->data.method.fptr;
auto param = ArgsList.end();
fptr((param--->CastTo<Args>())...);
}
else {
MethodType fptr = (MethodType)field->data.method.fptr;
auto param = ArgsList.end();
auto ret = ArgsList.front();
if (ret->cls == &TypeInfo<R>::StaticClass) {
*(R*)ret->ptr = fptr((param--->CastTo<Args>())...);
}
else {
fptr((param--->CastTo<Args>())...);
}
}
}
protected:
consteval 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<args_type_t<Args>>::StaticClass, ptr++));
}
}
public:
//为了简化判断cls 对象 统统指向 T*
consteval static MyUClass BuildClass() {
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;
}
};
template<typename T, typename MyMeta>
class UClass_Meta : public UClass {
public:
using FieldsType = decltype(MyMeta::__MakeFields());
FieldsType Fields{ MyMeta::__MakeFields() };
UClass_Meta() : UClass(type_name<T>().View(), sizeof(T)){
if constexpr (std::is_trivially_copyable_v<T>) {
flag = CLASS_TRIVIAL_FLAG;
}
if constexpr (_ReflCheck_Parent<MyMeta>) {
parent = &TypeInfo<typename MyMeta::Parent>::StaticClass;
}
if constexpr (_ReflCheck_Metas<T>) {
vtable.GetMeta = &MetaImpl<T>::MyMetas::GetMeta;
}
vtable.GetFields = &UClass_Meta::GetFields;
vtable.CtorObject = &UClass::CtorObject<T>;
}
const FieldPtr* GetField(int index) const {
return &Fields[index];
}
const sarray<const FieldPtr> GetFields(EFieldFind find, const Name& name) const {
constexpr int length = std::tuple_size<FieldsType>::value;
constexpr int MemberCount = MyMeta::MyStatic::MemberCount();
constexpr int CtorCount = MyMeta::MyStatic::CtorCount();
switch (find) {
case EFieldFind::FIND_ALL_FIELD:
return sarray<const FieldPtr>(&Fields[0], length);
case EFieldFind::FIND_ALL_MEMBER:
return sarray<const FieldPtr>(&Fields[0], MemberCount);
case EFieldFind::FIND_ALL_METHOD:
return sarray<const FieldPtr>(&Fields[MemberCount + CtorCount], length - MemberCount - CtorCount);
case EFieldFind::FIND_CTOR:
return sarray<const FieldPtr>(&Fields[MemberCount], CtorCount);
case EFieldFind::FIND_FIELD:
for (int i = 0; i < length; i++) {
if (name == Fields[i].name) {
return sarray<const FieldPtr>(&Fields[i], 1);
}
}
return {};
case EFieldFind::FIND_MEMBER:
for (int i = 0; i < MemberCount; i++) {
if (name == Fields[i].name) {
return sarray<const FieldPtr>(&Fields[i], 1);
}
}
return {};
case EFieldFind::FIND_METHOD:
for (int i = MemberCount + CtorCount; i < length; i++) {
if (name == Fields[i].name) {
return sarray<const FieldPtr>(&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<const FieldPtr>(&Fields[first], count);
}
}
return {};
}
default:
return {};
}
}
static const sarray<const FieldPtr> GetFields(const UClass* _cls, EFieldFind find, const Name& name) {
auto cls = static_cast<const UClass_Meta*>(_cls);
return cls->GetFields(find, name);
}
};
template<>
struct TypeInfoImpl<void> {
inline constexpr static UClass StaticClass = { type_name<void>().View(), 0 };
};
template<_ReflCheck_UClass T>
struct TypeInfoImpl<T> {
using MyUClass = UClass_Meta<T, typename MetaImpl<T>::MyMeta>;
inline static MyUClass StaticClass = MyUClass();
};
// 函数指针类型的偏特化
template<typename R, typename... Args>
struct TypeInfoImpl<R(*)(Args...)> {
using UClass = UMethod_Auto<R, Args...>;
inline constexpr static UClass StaticClass = UClass::BuildClass();
};
template<typename T, int N>
struct TypeInfoImpl<T[N]> {
using UClass = UClass_Array<T,N>;
inline constexpr static UClass StaticClass = UClass::BuildClass();
};
//基础类型的偏特化
template<_ReflCheck_Ctor_NoUClass T>
struct TypeInfoImpl<T> {
using UClass = UClass_Auto<T>;
inline constexpr static UClass StaticClass = UClass::BuildClass();
};
}