zengine/engine/modules/engine/zlib/include/refl/detail/uclass.inl

57 lines
1.6 KiB
C++

#include "uclass.h"
#include "name.h"
#include "type.h"
namespace refl{
template <class T>
concept is_metas_v = requires(const Name & name) { Meta<T>::GetMeta(name); };
template<typename T>
class UClass_Auto : public UClass {
public:
UClass_Auto() : UClass(type_name<T>().View(), sizeof(T)) {
if constexpr (std::is_pointer_v<T>) {
using RT = std::remove_pointer_t<T>;
flag |= CLASS_POINTER_FLAG;
if constexpr (!std::is_same_v<RT, void>) {
parent = &TypeInfo<RT>::StaticClass;
}
}
else if constexpr (is_array_v<T>) {
using RT = is_array_t<T>;
flag = CLASS_ARRAY_FLAG;
if constexpr (std::is_pointer_v<RT>) {
flag |= CLASS_POINTER_FLAG;
}
parent = &TypeInfo<RT>::StaticClass;
}
else {
vtable.Add(string_hash("Construct"), (void*) &UClass::Construct<T>);
vtable.Add(string_hash("Destruct"), (void*) &UClass::Destruct<T>);
}
}
};
template<typename T, typename MetaImpl>
class UClass_Meta : public UClass {
using FieldsType = decltype(MetaImpl::MakeFields());
FieldsType Fields{ MetaImpl::MakeFields() };
UClass_Meta() : UClass(type_name<T>().View(), sizeof(T)) {
if constexpr (has_parent_v<T>) {
parent = &TypeInfo<parent_t<T>>::StaticClass;
}
}
};
template<typename T>
struct TypeInfoImpl {
using MyUClass = UClass_Auto<T>;
const inline static MyUClass StaticClass{};
};
template<>
struct TypeInfoImpl<void> {
const inline static UClass StaticClass{ type_name<void>().View(), 0 };
};
template<is_meta_v T>
struct TypeInfoImpl<T> {
using MyUClass = UClass_Meta<T, meta_t<T>>;
const inline static MyUClass StaticClass{};
};
}