#pragma once #include #include "uclass.h" namespace refl { template<_ReflCheck_Ctor T> class UClass_Auto : public UClass { public: using UClass::UClass; using MyUClass = UClass_Auto; 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){ 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; } 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; 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) { cls.flag = CLASS_POINTER_FLAG | CLASS_ARRAY_FLAG; } else { cls.flag = CLASS_TRIVIAL_FLAG | CLASS_ARRAY_FLAG; } return cls; } }; /* * 模板优化 * 成员参数转化为const void* * 引用参数转化为指针 * 返回引用转化为指针 */ template class UMethod_Auto : public UClass { using UClass::UClass; using MethodType = R(*)(Args...); using MyUClass = UMethod_Auto; public: std::array UList{}; consteval sarray GetParams()const { return sarray(&UList.front(), UList.size()); } static sarray GetParams(const UClass* cls) { auto& UList = static_cast(cls)->UList; return sarray(&UList.front(),UList.size()); } //这里顺序似乎是不确定的,但是我实际运用是对的 //如果使用make_index_sequence,会多一次函数调用 //为什么包裹一层迭代器,就不会出现警告了 static void Call(const FieldPtr* field, const sarray& ArgsList) { assert(sizeof...(Args) <= ArgsList.size()); if constexpr (std::is_same_v) { MethodType fptr = (MethodType)field->data.method.fptr; auto param = ArgsList.end(); fptr((param--->CastTo())...); } else { MethodType fptr = (MethodType)field->data.method.fptr; auto param = ArgsList.end(); auto ret = ArgsList.front(); if (ret->cls == &TypeInfo::StaticClass) { *(R*)ret->ptr = fptr((param--->CastTo())...); } else { fptr((param--->CastTo())...); } } } protected: consteval void BuildUList() { if constexpr (!std::is_same_v) { UList[0] = &TypeInfo::StaticClass; } if constexpr (sizeof...(Args) > 0) { auto ptr = &UList[1]; (..., (*ptr = &TypeInfo*>::StaticClass, ptr++)); } } public: //为了简化判断,cls 对象 统统指向 T* consteval static MyUClass BuildClass() { MyUClass cls(type_name().View(), sizeof(MethodType)); cls.vtable.GetParams = &MyUClass::GetParams; cls.vtable.Call = &MyUClass::Call; cls.flag = CLASS_TRIVIAL_FLAG; cls.BuildUList(); return cls; } }; template class UClass_Meta : public UClass { public: using FieldsType = decltype(T::MyMeta::__MakeFields()); FieldsType Fields{ T::MyMeta::__MakeFields() }; UClass_Meta() : UClass(type_name().View(), sizeof(T)){ if constexpr (std::is_trivially_copyable_v) { flag = CLASS_TRIVIAL_FLAG; } 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::__GetMeta(name); }) { vtable.GetMeta = &T::__GetMeta; } vtable.GetField = &UClass_Meta::GetField; } 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; 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; } } return nullptr; } }; //基础类型的偏特化 template<_ReflCheck_Ctor_NoUClass T> struct TypeInfoImpl { using UClass = UClass_Auto; inline constexpr static UClass StaticClass = UClass::BuildClass(); }; // 函数指针类型的偏特化 template struct TypeInfoImpl { using UClass = UMethod_Auto; inline constexpr static UClass StaticClass = UClass::BuildClass(); }; template<_ReflCheck_UClass T> struct TypeInfoImpl { using MyUClass = typename T::MyMeta::MyUClass; inline static MyUClass StaticClass = MyUClass(); }; template struct TypeInfoImpl { using UClass = UClass_Array; inline constexpr static UClass StaticClass = UClass::BuildClass(); }; }