#pragma once #include #include "uclass.h" namespace refl { template concept _ReflCheck_Metas = requires(const Name & name) { MetaImpl::MyMetas::GetMeta(name); }; 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_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.vtable.CtorObject = &MyUClass::CtorObject; } if constexpr (_ReflCheck_Metas) { cls.vtable.GetMeta = &MetaImpl::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; public: consteval static MyUClass BuildClass() { MyUClass cls(type_name().View(), sizeof(T) * N, &TypeInfo::StaticClass); if constexpr (std::is_pointer_v) { cls.flag = CLASS_POINTER_FLAG | CLASS_ARRAY_FLAG; } else { cls.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(MyMeta::__MakeFields()); FieldsType Fields{ MyMeta::__MakeFields() }; UClass_Meta() : UClass(type_name().View(), sizeof(T)){ if constexpr (std::is_trivially_copyable_v) { flag = CLASS_TRIVIAL_FLAG; } if constexpr (_ReflCheck_Parent) { parent = &TypeInfo::StaticClass; } if constexpr (_ReflCheck_Metas) { vtable.GetMeta = &MetaImpl::MyMetas::GetMeta; } vtable.GetFields = &UClass_Meta::GetFields; vtable.CtorObject = &UClass::CtorObject; } const FieldPtr* GetField(int index) const { return &Fields[index]; } const sarray GetFields(EFieldFind find, const Name& name) const { constexpr int length = std::tuple_size::value; 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 {}; } default: return {}; } } static const sarray GetFields(const UClass* _cls, EFieldFind find, const Name& name) { auto cls = static_cast(_cls); return cls->GetFields(find, name); } }; template<> struct TypeInfoImpl { inline constexpr static UClass StaticClass = { type_name().View(), 0 }; }; template<_ReflCheck_UClass T> struct TypeInfoImpl { using MyUClass = UClass_Meta::MyMeta>; inline static MyUClass StaticClass = MyUClass(); }; // 函数指针类型的偏特化 template struct TypeInfoImpl { using UClass = UMethod_Auto; inline constexpr static UClass StaticClass = UClass::BuildClass(); }; template struct TypeInfoImpl { using UClass = UClass_Array; inline constexpr static UClass StaticClass = UClass::BuildClass(); }; //基础类型的偏特化 template<_ReflCheck_Ctor_NoUClass T> struct TypeInfoImpl { using UClass = UClass_Auto; inline constexpr static UClass StaticClass = UClass::BuildClass(); }; }