refl try support vector, map

This commit is contained in:
ouczbs 2024-06-22 10:02:48 +08:00
parent d1311b829d
commit 74ccd12aa4
5 changed files with 191 additions and 134 deletions

View File

@ -12,20 +12,46 @@ namespace refl_impl {
template<typename T, typename M> template<typename T, typename M>
struct _Meta; struct _Meta;
template<typename T>
struct _ContainerMeta;
} }
namespace refl { namespace refl {
using refl_impl::MetaImpl; // 定义一个模板结构体用于检测是否为 数组
template<typename T>
struct is_array : std::false_type {};
template <class MyMeta> template<typename T, size_t N>
concept _ReflCheck_Parent = requires { typename MyMeta::Parent;} && std::is_same_v<typename MyMeta::Parent, void>; struct is_array<T[N]> : std::true_type {
using type = T;
consteval static size_t Size() {
return N;
}
};
template <class T> // 定义一个模板结构体用于检测是否为 std::pair
concept _ReflCheck_Ctor = requires { T(); }; template<typename T>
template <class T> struct is_pair : std::false_type {};
concept _ReflCheck_UClass = requires { typename MetaImpl<T>::MyMeta; };
template <class T>
concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor<T> && !_ReflCheck_UClass<T>;
template<typename T1, typename T2>
struct is_pair<std::pair<T1, T2>> : std::true_type {};
template<typename T>
concept is_pair_v = is_pair<T>::value;
template<typename T>
concept is_container_v = requires(T a) {
{ a.begin() } -> std::input_iterator;
{ a.end() } -> std::input_iterator;
};
template<typename T>
concept is_map_v = is_pair_v<typename T::value_type> && is_container_v<T>;
template<typename T>
concept is_sequence_v = !is_pair_v<typename T::value_type> && is_container_v<T>;
};
namespace refl {
template<typename T> template<typename T>
struct real_type { struct real_type {
using type = std::remove_cv_t<T>; using type = std::remove_cv_t<T>;
@ -57,6 +83,19 @@ namespace refl {
}; };
template<typename T> template<typename T>
using args_type_t = args_type<std::remove_cv_t<T>>::type; using args_type_t = args_type<std::remove_cv_t<T>>::type;
};
namespace refl {
using refl_impl::MetaImpl;
template <class MyMeta>
concept _ReflCheck_Parent = requires { typename MyMeta::Parent;} && std::is_same_v<typename MyMeta::Parent, void>;
template <class T>
concept _ReflCheck_Ctor = requires { T(); };
template <class T>
concept _ReflCheck_UClass = requires { typename MetaImpl<T>::MyMeta; };
template <class T>
concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor<T> && !_ReflCheck_UClass<T>;
//类型接口 //类型接口
template<typename T> template<typename T>

View File

@ -14,12 +14,20 @@ namespace refl {
consteval static MyUClass BuildClass() { consteval static MyUClass BuildClass() {
MyUClass cls(type_name<T>().View(), sizeof(T)); MyUClass cls(type_name<T>().View(), sizeof(T));
if constexpr (std::is_pointer_v<T>){ if constexpr (std::is_pointer_v<T>){
using RawT = std::remove_pointer_t<T>; using RT = std::remove_pointer_t<T>;
cls.flag = CLASS_POINTER_FLAG; cls.flag = CLASS_POINTER_FLAG;
if constexpr (!std::is_same_v<RawT, void>) { if constexpr (!std::is_same_v<RT, void>) {
cls.parent = &TypeInfo<RawT>::StaticClass; cls.parent = &TypeInfo<RT>::StaticClass;
} }
} }
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;
}
else { else {
cls.vtable.CtorObject = &MyUClass::CtorObject<T>; cls.vtable.CtorObject = &MyUClass::CtorObject<T>;
} }
@ -35,23 +43,6 @@ namespace refl {
return *(T*)ptr; return *(T*)ptr;
} }
}; };
template<_ReflCheck_Ctor T, int N>
class UClass_Array : public UClass {
public:
using UClass::UClass;
using MyUClass = UClass_Array<T, N>;
public:
consteval static MyUClass BuildClass() {
MyUClass cls(type_name<T[N]>().View(), sizeof(T) * N, &TypeInfo<T>::StaticClass);
if constexpr (std::is_pointer_v<T>) {
cls.flag = CLASS_POINTER_FLAG | CLASS_ARRAY_FLAG;
}
else {
cls.flag = CLASS_ARRAY_FLAG;
}
return cls;
}
};
/* /*
* 模板优化 * 模板优化
* 成员参数转化为const void* * 成员参数转化为const void*
@ -115,6 +106,17 @@ namespace refl {
return cls; return cls;
} }
}; };
template<is_container_v T, typename value_type>
class UClass_Container : public UClass {
using MyUClass = UClass_Container<T, value_type>;
using MyMeta = refl_impl::_ContainerMeta<T>;
using FieldsType = decltype(MyMeta::__MakeFields());
FieldsType Fields{ MyMeta::__MakeFields() };
public:
consteval static MyUClass BuildClass() {
return MyMeta::__BuildClass();
}
};
template<typename T, typename MyMeta> template<typename T, typename MyMeta>
class UClass_Meta : public UClass { class UClass_Meta : public UClass {
public: public:
@ -211,9 +213,9 @@ namespace refl {
using UClass = UMethod_Auto<R, Args...>; using UClass = UMethod_Auto<R, Args...>;
inline constexpr static UClass StaticClass = UClass::BuildClass(); inline constexpr static UClass StaticClass = UClass::BuildClass();
}; };
template<typename T, int N> template<is_container_v T>
struct TypeInfoImpl<T[N]> { struct TypeInfoImpl<T> {
using UClass = UClass_Array<T,N>; using UClass = UClass_Container<T, typename T::value_type>;
inline constexpr static UClass StaticClass = UClass::BuildClass(); inline constexpr static UClass StaticClass = UClass::BuildClass();
}; };
//基础类型的偏特化 //基础类型的偏特化

View File

@ -0,0 +1,15 @@
#pragma once
#include "refl/detail/uclass.h"
namespace refl::impl {
template<typename T>
struct _ContainerMeta {
auto __MakeFields() {
return std::array{
};
}
auto __BuildClass() {
return cls;
}
};
}

View File

@ -4,84 +4,87 @@
#include <vector> #include <vector>
using std::string; using std::string;
using std::vector; using std::vector;
struct Guid
using std::string_view; {
namespace test { using MyMeta = class Guid_Meta;
struct Guid UPROPERTY({})
unsigned int Data1;
UPROPERTY({})
unsigned short Data2;
UPROPERTY({})
unsigned short Data3;
UPROPERTY({})
unsigned char Data4[8];
constexpr Guid() noexcept
: Data1{ 0 }, Data2{ 0 }, Data3{ 0 }, Data4{ 0,0,0,0,0,0,0,0 }
{}
Guid(const std::string_view& str) noexcept
: Guid{}
{ {
UPROPERTY({}) sscanf_s(str.data(),
unsigned int Data1; "%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
UPROPERTY({}) &Data1, &Data2, &Data3,
unsigned short Data2; &Data4[0], &Data4[1], &Data4[2], &Data4[3],
UPROPERTY({}) &Data4[4], &Data4[5], &Data4[6], &Data4[7]);
unsigned short Data3;
UPROPERTY({})
unsigned char Data4[8];
constexpr Guid() noexcept
: Data1{ 0 }, Data2{ 0 }, Data3{ 0 }, Data4{ 0,0,0,0,0,0,0,0 }
{}
USING_OVERLOAD_CTOR(Guid, const string_view&)
UFUNCTION({}, ref = USING_CTOR_NAME)
Guid(const std::string_view& str) noexcept
: Guid{}
{
sscanf_s(str.data(),
"%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
&Data1, &Data2, &Data3,
&Data4[0], &Data4[1], &Data4[2], &Data4[3],
&Data4[4], &Data4[5], &Data4[6], &Data4[7]);
}
constexpr Guid(unsigned int a, unsigned short b, unsigned short c, unsigned long long d)
: Data1{ a }
, Data2{ b }
, Data3{ c }
, Data4{
(unsigned char)(d >> 56 & 0xFF)
, (unsigned char)(d >> 48 & 0xFF)
, (unsigned char)(d >> 40 & 0xFF)
, (unsigned char)(d >> 32 & 0xFF)
, (unsigned char)(d >> 24 & 0xFF)
, (unsigned char)(d >> 16 & 0xFF)
, (unsigned char)(d >> 8 & 0xFF)
, (unsigned char)(d >> 0 & 0xFF)
} }
constexpr Guid(unsigned int a, unsigned short b, unsigned short c, unsigned long long d) {};
: Data1{ a } auto operator<=>(const Guid&) const noexcept = default;
, Data2{ b } operator bool() const noexcept
, Data3{ c } {
, Data4{ return *reinterpret_cast<const GUID*>(this) != GUID_NULL;
(unsigned char)(d >> 56 & 0xFF) }
, (unsigned char)(d >> 48 & 0xFF) operator std::string() const
, (unsigned char)(d >> 40 & 0xFF) {
, (unsigned char)(d >> 32 & 0xFF) char guid_cstr[39];
, (unsigned char)(d >> 24 & 0xFF) snprintf(guid_cstr, sizeof(guid_cstr),
, (unsigned char)(d >> 16 & 0xFF) "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
, (unsigned char)(d >> 8 & 0xFF) Data1, Data2, Data3,
, (unsigned char)(d >> 0 & 0xFF) Data4[0], Data4[1], Data4[2], Data4[3],
} Data4[4], Data4[5], Data4[6], Data4[7]);
{}; return std::string{ guid_cstr };
auto operator<=>(const Guid&) const noexcept = default; }
operator bool() const noexcept UFUNCTION({})
{ bool test(int a, float* b, char** c){}
return *reinterpret_cast<const GUID*>(this) != GUID_NULL; static Guid Make()
} {
Guid guid;
const auto res = CoCreateGuid((GUID*)&guid);
return guid;
}
};
struct SerializedMeta
{
UPROPERTY({})
Guid guid;
UPROPERTY({})
string name;
UPROPERTY({})
string t_hash{};
UPROPERTY({})
string metadata;
};
struct ResourceBundle;
USING_OVERLOAD_CLASS_FUNC(void, Guid, int) struct MetaBundle
UFUNCTION({}, ref = USING_FUNC_NAME) {
void test(int x) { UPROPERTY({})
vector<SerializedMeta> metadatas;
}
USING_OVERLOAD_CLASS_FUNC(void, Guid, float)
UFUNCTION({}, ref = USING_FUNC_NAME)
void test(float x) {
}
operator std::string() const
{
char guid_cstr[39];
snprintf(guid_cstr, sizeof(guid_cstr),
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
Data1, Data2, Data3,
Data4[0], Data4[1], Data4[2], Data4[3],
Data4[4], Data4[5], Data4[6], Data4[7]);
return std::string{ guid_cstr };
}
static Guid Make()
{
Guid guid;
const auto res = CoCreateGuid((GUID*)&guid);
return guid;
}
};
}
MetaBundle() = default;
};
#include "guid_gen.inl" #include "guid_gen.inl"

View File

@ -4,34 +4,32 @@
#include <cassert> #include <cassert>
using namespace refl; using namespace refl;
using namespace std; using namespace std;
using namespace test; void testGuid() {
int main() { Guid guid = Guid::Make();
using T = test::Guid;
auto cls = &TypeInfo<T>::StaticClass;
int x = 123;
Guid g1 = Guid::Make();
YAML::TextArchive::Register<Guid>(); YAML::TextArchive::Register<Guid>();
string rx = YAML::Text_Serialize(x); string text = YAML::Text_Serialize(guid);
string rg1 = YAML::Text_Serialize(g1); auto res = YAML::Text_Unserialize<Guid>(text);
YAML::Node rg2 = YAML::Load(rg1); Guid guid2 = res.value();
auto res1 = YAML::Text_Unserialize<Guid>(rg1); assert(guid == guid2);
Guid g2 = res1.value(); std::cout << guid << std::endl;
assert(g1 == g2); }
//auto res2 = YAML::Text_Unserialize<MetaBundle>(rg1); void testMeta() {
//if (res2) { MetaBundle mb1;
//MetaBundle aa = res2.value(); mb1.metadatas.push_back({ Guid::Make() , "hello1" });
//} mb1.metadatas.push_back({ Guid::Make() , "hello2" });
std::cout << rg1 << std::endl; mb1.metadatas.push_back({ Guid::Make() , "hello3" });
YAML::Node primes = YAML::Load("[2, 3, 5, 7, 11]"); mb1.metadatas.push_back({ Guid::Make() , "hello4" });
for (std::size_t i = 0; i < primes.size(); i++) { string rmb1 = YAML::Text_Serialize(mb1);
std::cout << primes[i].as<int>() << "\n"; auto rmb2 = YAML::Text_Unserialize<MetaBundle>(rmb1);
if (rmb2) {
MetaBundle aa = rmb2.value();
} }
// or: }
for (YAML::const_iterator it = primes.begin(); it != primes.end(); ++it) { int main() {
std::cout << it->as<int>() << "\n"; constexpr bool m1 = refl::is_map_v<std::vector<int>>;
} constexpr bool m2 = refl::is_sequence_v<std::map<int, float>>;
auto cls = &TypeInfo<Guid>::StaticClass;
primes.push_back(13); testGuid();
assert(primes.size() == 6); testMeta();
return 0; return 0;
} }