#pragma once #include #include "uclass.h" #include namespace refl { template concept _ReflCheck_Metas = requires(const Name & name) { MetaImpl::MyMetas::GetMeta(name); }; template 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 RT = std::remove_pointer_t; cls.flag = CLASS_POINTER_FLAG; if constexpr (!std::is_same_v) { cls.parent = &TypeInfo::StaticClass; } } else if constexpr (is_array::value) { using RT = typename is_array::type; cls.flag = CLASS_ARRAY_FLAG; if constexpr (std::is_pointer_v) { cls.flag |= CLASS_POINTER_FLAG; } cls.parent = &TypeInfo::StaticClass; } else { cls.vtable.Construct = &MyUClass::Construct; } 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; } }; /* * 模板优化 * 成员参数转化为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; } }; constexpr static std::array IndexNames = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16" }; template class UClass_Tuple : public UClass { using UClass::UClass; using MyUClass = UClass_Tuple; using MyTuple = std::tuple; public: std::array Fields; static bool construct(void* ptr, const UClass* cls, const sarray& ArgsList) { new(ptr)MyTuple(); return true; } static void destruct(void* ptr) { ((MyTuple*)ptr)->~MyTuple(); } template static FieldPtr field_in_tuple() { constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG; const MyTuple* tuple_ptr = nullptr; const auto& element = std::get(*tuple_ptr); const std::ptrdiff_t offset = reinterpret_cast(&element) - reinterpret_cast(tuple_ptr); MemberData member; member.offset = offset; return { IndexNames[Index], &TypeInfo::StaticClass, member, flag}; } template void BuildFields(std::index_sequence) { auto ptr = &Fields[0]; (..., (*ptr = field_in_tuple(), ptr++)); } UClass_Tuple():UClass(type_name().View(), sizeof(MyTuple)) { assert(sizeof...(Types) < IndexNames.size()); BuildFields(std::index_sequence_for{}); vtable.Construct = &MyUClass::construct; vtable.Destruct = &MyUClass::destruct; vtable.GetFields = &MyUClass::GetFields; } const sarray GetFields(EFieldFind find, const Name& name) const { return sarray(&Fields[0], sizeof...(Types)); } static const sarray GetFields(const UClass* _cls, EFieldFind find, const Name& name) { auto cls = static_cast(_cls); return cls->GetFields(find, name); } }; template class UClass_Pair : public UClass { using UClass::UClass; using MyUClass = UClass_Tuple; using MyPair = std::pair; public: std::array Fields; static bool construct(void* ptr, const UClass* cls, const sarray& ArgsList) { new(ptr)MyPair(); return true; } static void destruct(void* ptr) { ((MyPair*)ptr)->~MyPair(); } template 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(&first) - reinterpret_cast(pair_ptr); member.offset = offset; } else { const auto& second = pair_ptr->second; const std::ptrdiff_t offset = reinterpret_cast(&second) - reinterpret_cast(pair_ptr); member.offset = offset; } return { IndexNames[Index], &TypeInfo::StaticClass, member, flag }; } UClass_Pair() :UClass(type_name().View(), sizeof(MyPair)) { Fields[0] = field_in_pair(); Fields[1] = field_in_pair(); vtable.Construct = &MyUClass::construct; vtable.Destruct = &MyUClass::destruct; vtable.GetFields = &MyUClass::GetFields; } const sarray GetFields(EFieldFind find, const Name& name) const { return sarray(&Fields[0], 2); } static const sarray GetFields(const UClass* _cls, EFieldFind find, const Name& name) { auto cls = static_cast(_cls); return cls->GetFields(find, name); } }; class UClass_Container : public UClass { public: using UClass::UClass; struct iterator { void* ptr; void* val; }; //container using size_impl = size_t(*)(const void*); using to_iterator_impl = void(*)(iterator& ,const void*); using insert_impl = void (*)(const void*, const void*); //iterator using iterator_impl = void (*)(iterator*); public: size_impl vsize; to_iterator_impl vbegin; to_iterator_impl vend; insert_impl vinsert; iterator_impl viterator_add; iterator_impl viterator_sub; template static void insert(const void* ptr, const void* obj) { using value_type = typename T::value_type; if constexpr (is_sequence_v) { ((T*)ptr)->push_back(*(value_type*)obj); } else if constexpr (is_map_v) { ((T*)ptr)->insert(*(value_type*)obj); } } }; template class UClass_Container_impl : public UClass_Container { using UClass_Container::UClass_Container; using MyUClass = UClass_Container_impl; public: static bool construct(void* ptr, const UClass* cls, const sarray& ArgsList) { new(ptr)T(); return true; } static void destruct(void* ptr) { ((T*)ptr)->~T(); } static void begin(iterator& pit,const void* ptr) { auto it = ((T*)ptr)->begin(); memcpy(&pit, &it, sizeof(it)); pit.val = &*it; } static void end(iterator& pit, const void* ptr) { auto it = ((T*)ptr)->end(); memcpy(&pit, &it, sizeof(it)); pit.val = &*it; } static void add(iterator* pit) { auto it = ++(*(T::iterator*)pit); memcpy(pit, &it, sizeof(it)); pit->val = &*it; } static void sub(iterator* pit) { auto it = --(*(T::iterator*)pit); memcpy(pit, &it, sizeof(it)); pit->val = &*it; } UClass_Container_impl() : UClass_Container(type_name().View(), sizeof(T)) { parent = &TypeInfo::StaticClass; flag = CLASS_CONTAINER_FLAG; vtable.Construct = &MyUClass::construct; vtable.Destruct = &MyUClass::destruct; if constexpr (is_sequence_v) { flag |= CLASS_SEQUENCE_FLAG; } else if constexpr (is_map_v) { flag |= CLASS_MAP_FLAG; } auto __size = &T::size; vsize = *(size_impl*)&__size; vbegin = &MyUClass::begin; vend = &MyUClass::end; vinsert = &MyUClass::insert; viterator_add = &MyUClass::add; viterator_sub = &MyUClass::sub; }; }; 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.Construct = &UClass::Construct; } 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 { using MyUClass = UClass_Auto; inline constexpr static MyUClass StaticClass = MyUClass::BuildClass(); }; 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 MyUClass = UClass_Tuple; inline static MyUClass StaticClass = MyUClass(); }; template struct TypeInfoImpl> { using MyUClass = UClass_Pair; inline static MyUClass StaticClass = MyUClass(); }; template struct TypeInfoImpl { using MyUClass = UClass_Container_impl; inline static MyUClass StaticClass = MyUClass(); }; // 函数指针类型的偏特化 template struct TypeInfoImpl { using MyUClass = UMethod_Auto; inline constexpr static MyUClass StaticClass = MyUClass::BuildClass(); }; }