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

400 lines
13 KiB
Plaintext
Raw Normal View History

2024-04-08 21:01:50 +08:00
#pragma once
2024-04-11 10:13:15 +08:00
#include <array>
2024-04-08 21:01:50 +08:00
#include "uclass.h"
2024-06-24 00:26:52 +08:00
#include <iostream>
2024-04-08 21:01:50 +08:00
namespace refl {
2024-06-21 22:21:32 +08:00
template <class T>
concept _ReflCheck_Metas = requires(const Name & name) { MetaImpl<T>::MyMetas::GetMeta(name); };
2024-06-24 00:26:52 +08:00
template<typename T>
2024-04-08 21:01:50 +08:00
class UClass_Auto : public UClass {
public:
using UClass::UClass;
2024-04-09 16:31:09 +08:00
using MyUClass = UClass_Auto<T>;
2024-04-08 21:01:50 +08:00
public:
2024-04-13 17:47:44 +08:00
consteval static MyUClass BuildClass() {
2024-04-09 16:31:09 +08:00
MyUClass cls(type_name<T>().View(), sizeof(T));
2024-06-12 22:07:45 +08:00
if constexpr (std::is_pointer_v<T>){
2024-06-22 10:02:48 +08:00
using RT = std::remove_pointer_t<T>;
2024-04-25 21:45:41 +08:00
cls.flag = CLASS_POINTER_FLAG;
2024-06-22 10:02:48 +08:00
if constexpr (!std::is_same_v<RT, void>) {
cls.parent = &TypeInfo<RT>::StaticClass;
2024-04-25 21:45:41 +08:00
}
}
2024-06-22 10:02:48 +08:00
else if constexpr (is_array<T>::value) {
using RT = typename is_array<T>::type;
cls.flag = CLASS_ARRAY_FLAG;
if constexpr (std::is_pointer_v<RT>) {
cls.flag |= CLASS_POINTER_FLAG;
}
cls.parent = &TypeInfo<RT>::StaticClass;
}
2024-06-14 22:24:52 +08:00
else {
2024-06-24 00:26:52 +08:00
cls.vtable.Construct = &MyUClass::Construct<T>;
2024-06-14 22:24:52 +08:00
}
2024-06-21 22:21:32 +08:00
if constexpr (_ReflCheck_Metas<T>) {
cls.vtable.GetMeta = &MetaImpl<T>::MyMetas::GetMeta;
2024-04-29 15:00:09 +08:00
}
2024-04-08 21:01:50 +08:00
return cls;
}
2024-04-13 17:47:44 +08:00
void Set(void* ptr,const T& t) {
*(T*)ptr = t;
}
T& Get(void* ptr) {
return *(T*)ptr;
}
2024-04-08 21:01:50 +08:00
};
/*
* 模板优化
* 成员参数转化为const void*
* 引用参数转化为指针
2024-04-09 22:26:33 +08:00
* 返回引用转化为指针
2024-04-08 21:01:50 +08:00
*/
template<typename R, typename... Args>
class UMethod_Auto : public UClass {
using UClass::UClass;
using MethodType = R(*)(Args...);
2024-04-09 16:31:09 +08:00
using MyUClass = UMethod_Auto<R, Args...>;
2024-04-08 21:01:50 +08:00
public:
std::array<const UClass*, sizeof...(Args) + 1> UList{};
2024-04-25 21:45:41 +08:00
consteval sarray<const UClass*> GetParams()const {
return sarray<const UClass*>(&UList.front(), UList.size());
}
2024-04-16 16:17:13 +08:00
static sarray<const UClass*> GetParams(const UClass* cls) {
2024-04-09 16:31:09 +08:00
auto& UList = static_cast<const MyUClass*>(cls)->UList;
2024-04-16 16:17:13 +08:00
return sarray<const UClass*>(&UList.front(),UList.size());
2024-04-08 21:01:50 +08:00
}
2024-04-15 19:53:39 +08:00
//这里顺序似乎是不确定的,但是我实际运用是对的
//如果使用make_index_sequence,会多一次函数调用
//为什么包裹一层迭代器,就不会出现警告了
2024-04-19 22:02:27 +08:00
static void Call(const FieldPtr* field, const sarray<Any>& ArgsList) {
2024-04-15 19:53:39 +08:00
assert(sizeof...(Args) <= ArgsList.size());
2024-04-08 21:01:50 +08:00
if constexpr (std::is_same_v<R, void>) {
2024-04-19 22:02:27 +08:00
MethodType fptr = (MethodType)field->data.method.fptr;
2024-04-15 19:53:39 +08:00
auto param = ArgsList.end();
2024-04-25 21:45:41 +08:00
fptr((param--->CastTo<Args>())...);
2024-04-08 21:01:50 +08:00
}
else {
2024-04-19 22:02:27 +08:00
MethodType fptr = (MethodType)field->data.method.fptr;
2024-04-15 19:53:39 +08:00
auto param = ArgsList.end();
2024-04-16 16:17:13 +08:00
auto ret = ArgsList.front();
2024-06-14 22:24:52 +08:00
if (ret->cls == &TypeInfo<R>::StaticClass) {
2024-04-25 21:45:41 +08:00
*(R*)ret->ptr = fptr((param--->CastTo<Args>())...);
2024-04-08 21:01:50 +08:00
}
else {
2024-04-25 21:45:41 +08:00
fptr((param--->CastTo<Args>())...);
2024-04-08 21:01:50 +08:00
}
}
}
protected:
2024-04-13 17:47:44 +08:00
consteval void BuildUList() {
2024-04-08 21:01:50 +08:00
if constexpr (!std::is_same_v<R, void>) {
2024-06-14 22:24:52 +08:00
UList[0] = &TypeInfo<R>::StaticClass;
2024-04-08 21:01:50 +08:00
}
if constexpr (sizeof...(Args) > 0) {
auto ptr = &UList[1];
2024-06-25 20:26:46 +08:00
(..., (*ptr = &TypeInfo<Args>::StaticClass, ptr++));
2024-04-08 21:01:50 +08:00
}
}
public:
//为了简化判断cls 对象 统统指向 T*
2024-04-13 17:47:44 +08:00
consteval static MyUClass BuildClass() {
2024-04-09 16:31:09 +08:00
MyUClass cls(type_name<MethodType>().View(), sizeof(MethodType));
cls.vtable.GetParams = &MyUClass::GetParams;
cls.vtable.Call = &MyUClass::Call;
2024-04-15 19:53:39 +08:00
cls.flag = CLASS_TRIVIAL_FLAG;
2024-04-08 21:01:50 +08:00
cls.BuildUList();
return cls;
}
};
2024-06-24 00:26:52 +08:00
template<typename... Types>
class UClass_Tuple : public UClass {
using UClass::UClass;
using MyUClass = UClass_Tuple<Types...>;
using MyTuple = std::tuple<Types...>;
public:
std::array<FieldPtr, sizeof...(Types)> Fields;
static bool construct(void* ptr, const UClass* cls, const sarray<Any>& ArgsList) {
new(ptr)MyTuple();
return true;
}
static void destruct(void* ptr) {
((MyTuple*)ptr)->~MyTuple();
}
2024-06-24 22:26:09 +08:00
template <typename T, std::size_t Index>
2024-06-24 00:26:52 +08:00
static FieldPtr field_in_tuple() {
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
2024-06-24 22:26:09 +08:00
const MyTuple* tuple_ptr = nullptr;
const auto& element = std::get<Index>(*tuple_ptr);
const std::ptrdiff_t offset = reinterpret_cast<const char*>(&element) - reinterpret_cast<const char*>(tuple_ptr);
MemberData member;
member.offset = offset;
return { IndexNames[Index], &TypeInfo<T>::StaticClass, member, flag};
}
template <std::size_t... Is>
void BuildFields(std::index_sequence<Is...>) {
auto ptr = &Fields[0];
(..., (*ptr = field_in_tuple<Types, Is>(), ptr++));
}
UClass_Tuple():UClass(type_name<MyTuple>().View(), sizeof(MyTuple)) {
assert(sizeof...(Types) < IndexNames.size());
BuildFields(std::index_sequence_for<Types...>{});
vtable.Construct = &MyUClass::construct;
vtable.Destruct = &MyUClass::destruct;
vtable.GetFields = &MyUClass::GetFields;
2024-06-24 00:26:52 +08:00
}
const sarray<const FieldPtr> GetFields(EFieldFind find, const Name& name) const {
return sarray<const FieldPtr>(&Fields[0], sizeof...(Types));
}
static const sarray<const FieldPtr> GetFields(const UClass* _cls, EFieldFind find, const Name& name) {
auto cls = static_cast<const MyUClass*>(_cls);
return cls->GetFields(find, name);
}
2024-06-24 22:26:09 +08:00
};
template<typename First,typename Second>
class UClass_Pair : public UClass {
using UClass::UClass;
using MyUClass = UClass_Tuple<First, Second>;
using MyPair = std::pair<First, Second>;
public:
std::array<FieldPtr, 2> Fields;
static bool construct(void* ptr, const UClass* cls, const sarray<Any>& ArgsList) {
new(ptr)MyPair();
return true;
}
static void destruct(void* ptr) {
((MyPair*)ptr)->~MyPair();
}
template<typename T, int Index>
static FieldPtr field_in_pair() {
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
const MyPair* pair_ptr = nullptr;
MemberData member;
if constexpr (Index == 0) {
const auto& first = pair_ptr->first;
const std::ptrdiff_t offset = reinterpret_cast<const char*>(&first) - reinterpret_cast<const char*>(pair_ptr);
member.offset = offset;
}
else {
const auto& second = pair_ptr->second;
const std::ptrdiff_t offset = reinterpret_cast<const char*>(&second) - reinterpret_cast<const char*>(pair_ptr);
member.offset = offset;
}
return { IndexNames[Index], &TypeInfo<T>::StaticClass, member, flag };
}
UClass_Pair() :UClass(type_name<MyPair>().View(), sizeof(MyPair)) {
Fields[0] = field_in_pair<First, 0>();
Fields[1] = field_in_pair<Second, 1>();
2024-06-24 00:26:52 +08:00
vtable.Construct = &MyUClass::construct;
vtable.Destruct = &MyUClass::destruct;
vtable.GetFields = &MyUClass::GetFields;
2024-06-24 22:26:09 +08:00
}
const sarray<const FieldPtr> GetFields(EFieldFind find, const Name& name) const {
return sarray<const FieldPtr>(&Fields[0], 2);
}
static const sarray<const FieldPtr> GetFields(const UClass* _cls, EFieldFind find, const Name& name) {
auto cls = static_cast<const MyUClass*>(_cls);
return cls->GetFields(find, name);
2024-06-24 00:26:52 +08:00
}
};
2024-06-22 10:02:48 +08:00
class UClass_Container : public UClass {
public:
2024-06-24 00:26:52 +08:00
using UClass::UClass;
struct iterator {
void* ptr;
void* val;
};
//container
using size_impl = size_t(*)(const void*);
2024-06-24 22:26:09 +08:00
using to_iterator_impl = void(*)(iterator& ,const void*);
2024-06-24 00:26:52 +08:00
using insert_impl = void (*)(const void*, const void*);
//iterator
2024-06-24 22:26:09 +08:00
using iterator_impl = void (*)(iterator*);
2024-06-24 00:26:52 +08:00
public:
size_impl vsize;
to_iterator_impl vbegin;
to_iterator_impl vend;
insert_impl vinsert;
iterator_impl viterator_add;
iterator_impl viterator_sub;
template<typename T>
static void insert(const void* ptr, const void* obj) {
using value_type = typename T::value_type;
if constexpr (is_sequence_v<T>) {
((T*)ptr)->push_back(*(value_type*)obj);
}
else if constexpr (is_map_v<T>) {
((T*)ptr)->insert(*(value_type*)obj);
}
}
};
template<is_container_v T, typename value_type>
class UClass_Container_impl : public UClass_Container {
using UClass_Container::UClass_Container;
using MyUClass = UClass_Container_impl<T, value_type>;
public:
static bool construct(void* ptr, const UClass* cls, const sarray<Any>& ArgsList) {
new(ptr)T();
return true;
}
static void destruct(void* ptr) {
((T*)ptr)->~T();
2024-06-22 10:02:48 +08:00
}
2024-06-24 22:26:09 +08:00
static void begin(iterator& pit,const void* ptr) {
2024-06-24 00:26:52 +08:00
auto it = ((T*)ptr)->begin();
2024-06-24 22:26:09 +08:00
memcpy(&pit, &it, sizeof(it));
pit.val = &*it;
2024-06-24 00:26:52 +08:00
}
2024-06-24 22:26:09 +08:00
static void end(iterator& pit, const void* ptr) {
2024-06-24 00:26:52 +08:00
auto it = ((T*)ptr)->end();
2024-06-24 22:26:09 +08:00
memcpy(&pit, &it, sizeof(it));
pit.val = &*it;
}
static void add(iterator* pit) {
2024-06-25 20:26:46 +08:00
auto it = ++(*(typename T::iterator*)pit);
2024-06-24 22:26:09 +08:00
memcpy(pit, &it, sizeof(it));
pit->val = &*it;
}
static void sub(iterator* pit) {
2024-06-25 20:26:46 +08:00
auto it = --(*(typename T::iterator*)pit);
2024-06-24 22:26:09 +08:00
memcpy(pit, &it, sizeof(it));
pit->val = &*it;
2024-06-24 00:26:52 +08:00
}
UClass_Container_impl() : UClass_Container(type_name<T>().View(), sizeof(T)) {
parent = &TypeInfo<value_type>::StaticClass;
flag = CLASS_CONTAINER_FLAG;
vtable.Construct = &MyUClass::construct;
vtable.Destruct = &MyUClass::destruct;
if constexpr (is_sequence_v<T>) {
flag |= CLASS_SEQUENCE_FLAG;
}
else if constexpr (is_map_v<T>)
{
flag |= CLASS_MAP_FLAG;
}
auto __size = &T::size;
vsize = *(size_impl*)&__size;
vbegin = &MyUClass::begin;
vend = &MyUClass::end;
vinsert = &MyUClass::insert<T>;
2024-06-24 22:26:09 +08:00
viterator_add = &MyUClass::add;
viterator_sub = &MyUClass::sub;
2024-06-24 00:26:52 +08:00
};
2024-06-22 10:02:48 +08:00
};
2024-06-21 22:21:32 +08:00
template<typename T, typename MyMeta>
2024-04-13 17:47:44 +08:00
class UClass_Meta : public UClass {
public:
2024-04-29 15:00:09 +08:00
using FieldsType = decltype(MyMeta::__MakeFields());
FieldsType Fields{ MyMeta::__MakeFields() };
2024-04-14 22:45:08 +08:00
UClass_Meta() : UClass(type_name<T>().View(), sizeof(T)){
2024-04-15 19:53:39 +08:00
if constexpr (std::is_trivially_copyable_v<T>) {
flag = CLASS_TRIVIAL_FLAG;
}
2024-06-21 22:21:32 +08:00
if constexpr (_ReflCheck_Parent<MyMeta>) {
parent = &TypeInfo<typename MyMeta::Parent>::StaticClass;
2024-04-13 17:47:44 +08:00
}
2024-06-21 22:21:32 +08:00
if constexpr (_ReflCheck_Metas<T>) {
vtable.GetMeta = &MetaImpl<T>::MyMetas::GetMeta;
2024-04-28 00:23:35 +08:00
}
2024-06-12 22:07:45 +08:00
vtable.GetFields = &UClass_Meta::GetFields;
2024-06-24 00:26:52 +08:00
vtable.Construct = &UClass::Construct<T>;
2024-04-13 17:47:44 +08:00
}
2024-04-14 22:45:08 +08:00
const FieldPtr* GetField(int index) const {
return &Fields[index];
}
2024-06-12 22:07:45 +08:00
const sarray<const FieldPtr> GetFields(EFieldFind find, const Name& name) const {
2024-04-14 22:45:08 +08:00
constexpr int length = std::tuple_size<FieldsType>::value;
2024-06-12 22:07:45 +08:00
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);
}
2024-04-14 22:45:08 +08:00
}
2024-06-12 22:07:45 +08:00
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 {};
2024-04-14 22:45:08 +08:00
}
2024-06-12 22:07:45 +08:00
}
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);
}
2024-04-08 21:01:50 +08:00
};
2024-06-24 00:26:52 +08:00
template<typename T>
struct TypeInfoImpl {
using MyUClass = UClass_Auto<T>;
inline constexpr static MyUClass StaticClass = MyUClass::BuildClass();
};
2024-06-14 22:24:52 +08:00
template<>
struct TypeInfoImpl<void> {
inline constexpr static UClass StaticClass = { type_name<void>().View(), 0 };
};
template<_ReflCheck_UClass T>
2024-04-08 21:01:50 +08:00
struct TypeInfoImpl<T> {
2024-06-21 22:21:32 +08:00
using MyUClass = UClass_Meta<T, typename MetaImpl<T>::MyMeta>;
2024-06-14 22:24:52 +08:00
inline static MyUClass StaticClass = MyUClass();
2024-04-08 21:01:50 +08:00
};
2024-06-24 00:26:52 +08:00
template<typename... Types>
struct TypeInfoImpl<std::tuple<Types...>> {
using MyUClass = UClass_Tuple<Types...>;
inline static MyUClass StaticClass = MyUClass();
};
2024-06-24 22:26:09 +08:00
template<typename First, typename Second>
struct TypeInfoImpl<std::pair<First, Second>> {
using MyUClass = UClass_Pair<First, Second>;
2024-06-24 00:26:52 +08:00
inline static MyUClass StaticClass = MyUClass();
2024-04-08 21:01:50 +08:00
};
2024-06-22 10:02:48 +08:00
template<is_container_v T>
struct TypeInfoImpl<T> {
2024-06-24 00:26:52 +08:00
using MyUClass = UClass_Container_impl<T, typename T::value_type>;
inline static MyUClass StaticClass = MyUClass();
2024-04-25 21:45:41 +08:00
};
2024-06-24 00:26:52 +08:00
// 函数指针类型的偏特化
template<typename R, typename... Args>
struct TypeInfoImpl<R(*)(Args...)> {
using MyUClass = UMethod_Auto<R, Args...>;
inline constexpr static MyUClass StaticClass = MyUClass::BuildClass();
2024-06-14 22:24:52 +08:00
};
2024-04-08 21:01:50 +08:00
}