rebuild refl01
This commit is contained in:
parent
a79b76c8f4
commit
7e6c362024
66
engine/3rdparty/zlib/include/refl/detail/field.h
vendored
66
engine/3rdparty/zlib/include/refl/detail/field.h
vendored
@ -9,7 +9,7 @@ namespace refl {
|
|||||||
class ArgsView;
|
class ArgsView;
|
||||||
|
|
||||||
using Offset = uint32_t;
|
using Offset = uint32_t;
|
||||||
using Method = void(*)(...);
|
using Method = void*;
|
||||||
|
|
||||||
using DefaultMember = const ArgsView (*)();
|
using DefaultMember = const ArgsView (*)();
|
||||||
using DefaultMethod = std::pair<ArgsView*, int>(*)();
|
using DefaultMethod = std::pair<ArgsView*, int>(*)();
|
||||||
@ -26,22 +26,23 @@ namespace refl {
|
|||||||
{
|
{
|
||||||
Offset offset;
|
Offset offset;
|
||||||
Method method;
|
Method method;
|
||||||
Data() : method(nullptr) {}
|
constexpr Data() : method(nullptr) {}
|
||||||
Data(Offset& offset) : offset(offset) {}
|
constexpr Data(Offset& offset) : offset(offset) {}
|
||||||
Data(Method& method) : method(method) {}
|
constexpr Data(Method& method) : method(method) {}
|
||||||
|
constexpr Data(const Method& method) : method(method) {}
|
||||||
};
|
};
|
||||||
union Default {
|
union Default {
|
||||||
DefaultMember member;
|
DefaultMember member;
|
||||||
DefaultMethod method;
|
DefaultMethod method;
|
||||||
Default(): method(nullptr) {}
|
constexpr Default(): method(nullptr) {}
|
||||||
Default(DefaultMember& member) : member(member) {}
|
constexpr Default(DefaultMember& member) : member(member) {}
|
||||||
Default(DefaultMethod& method) : method(method) {}
|
constexpr Default(DefaultMethod& method) : method(method) {}
|
||||||
};
|
};
|
||||||
Name name;
|
Name name;
|
||||||
const UClass* type;
|
const UClass* type{};
|
||||||
Data data;
|
Data data{};
|
||||||
Default value;
|
Default value{};
|
||||||
uint32_t flag;
|
uint32_t flag{};
|
||||||
|
|
||||||
//safe
|
//safe
|
||||||
bool Invoke(std::vector<ArgsView>& ArgsList)const;
|
bool Invoke(std::vector<ArgsView>& ArgsList)const;
|
||||||
@ -50,5 +51,48 @@ namespace refl {
|
|||||||
|
|
||||||
std::vector<const UClass*> GetParams() const;
|
std::vector<const UClass*> GetParams() const;
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
|
template<typename T, typename V>
|
||||||
|
consteval V* fetch_member_v(V T::*) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
template<typename R, typename T, typename ...Args>
|
||||||
|
consteval auto fetch_method_v(R (T::* ptr)(Args...)) {
|
||||||
|
using MethodType = R(*)(T*, Args...);
|
||||||
|
return MethodType{nullptr};
|
||||||
|
}
|
||||||
|
template<typename R, typename ...Args>
|
||||||
|
consteval auto fetch_method_v(R(*ptr)(Args...)) {
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
template<typename... Args>
|
||||||
|
consteval auto FetchMembers(const std::tuple<Args...>&) {
|
||||||
|
return std::make_tuple(fetch_member_v(Args{nullptr})...);
|
||||||
|
}
|
||||||
|
template<typename... Args>
|
||||||
|
consteval auto FetchMethods(const std::tuple<Args...>&) {
|
||||||
|
return std::make_tuple(fetch_method_v(Args{ nullptr })...);
|
||||||
|
}
|
||||||
|
template<typename ...Args>
|
||||||
|
class FieldMembers{
|
||||||
|
public:
|
||||||
|
constexpr FieldMembers() {}
|
||||||
|
FieldMembers(const std::tuple<Args*...>&) {
|
||||||
|
|
||||||
|
}
|
||||||
|
constexpr static int GetSize() {
|
||||||
|
return sizeof...(Args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename ...Args>
|
||||||
|
class FieldMethods{
|
||||||
|
public:
|
||||||
|
constexpr FieldMethods() {}
|
||||||
|
FieldMethods(const std::tuple<Args*...>&) {
|
||||||
|
|
||||||
|
}
|
||||||
|
constexpr static int GetSize() {
|
||||||
|
return sizeof...(Args);
|
||||||
|
}
|
||||||
|
};*/
|
||||||
}
|
}
|
||||||
@ -1,10 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#define REGISTER_CLASS_META(T, P) using MyUClass = UClass_Meta<T, P>;
|
||||||
|
#define REGISTER_MEMBER(Ptr, Name) MakeStaticField(Ptr, Name),
|
||||||
|
#define BUILD_FELDS() constexpr static auto __BuildFields() {\
|
||||||
|
return std::array{\
|
||||||
|
REGISTER_FIELDS(REGISTER_MEMBER, REGISTER_MEMBER)\
|
||||||
|
};\
|
||||||
|
};
|
||||||
namespace refl {
|
namespace refl {
|
||||||
template <class T>
|
template <class T>
|
||||||
concept _ReflCheck_Ctor = requires { T(); };
|
concept _ReflCheck_Ctor = requires { T(); };
|
||||||
template <class T>
|
template <class T>
|
||||||
concept _ReflCheck_UClass = requires(typename T::MyUClass& cls) { T::BuildClass(cls); } ;
|
concept _ReflCheck_UClass = requires { !std::is_void_v<decltype(T::__BuildFields())>; };
|
||||||
template <class T>
|
template <class T>
|
||||||
concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor<T> && !_ReflCheck_UClass<T>;
|
concept _ReflCheck_Ctor_NoUClass = _ReflCheck_Ctor<T> && !_ReflCheck_UClass<T>;
|
||||||
//类型接口
|
//类型接口
|
||||||
|
|||||||
@ -8,7 +8,7 @@ namespace refl {
|
|||||||
using UClass::UClass;
|
using UClass::UClass;
|
||||||
using MyUClass = UClass_Auto<T>;
|
using MyUClass = UClass_Auto<T>;
|
||||||
public:
|
public:
|
||||||
constexpr 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_trivially_copyable_v<T>) {
|
if constexpr (!std::is_trivially_copyable_v<T>) {
|
||||||
cls.vtable.InitObject = &MyUClass::InitObject<T>;
|
cls.vtable.InitObject = &MyUClass::InitObject<T>;
|
||||||
@ -16,6 +16,12 @@ namespace refl {
|
|||||||
}
|
}
|
||||||
return cls;
|
return cls;
|
||||||
}
|
}
|
||||||
|
void Set(void* ptr,const T& t) {
|
||||||
|
*(T*)ptr = t;
|
||||||
|
}
|
||||||
|
T& Get(void* ptr) {
|
||||||
|
return *(T*)ptr;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -36,6 +42,15 @@ namespace refl {
|
|||||||
auto& UList = static_cast<const MyUClass*>(cls)->UList;
|
auto& UList = static_cast<const MyUClass*>(cls)->UList;
|
||||||
return { UList.data(), UList.data() + UList.size() };
|
return { UList.data(), UList.data() + UList.size() };
|
||||||
}
|
}
|
||||||
|
static R Call(const FieldPtr* field, Args... args) {
|
||||||
|
MethodType fptr = (MethodType)field->data.method;
|
||||||
|
if constexpr (std::is_same_v<R, void>) {
|
||||||
|
fptr(args...);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return fptr(args...);
|
||||||
|
}
|
||||||
|
}
|
||||||
static void Call(const FieldPtr* field, const std::vector<ArgsView>& ArgsList) {
|
static void Call(const FieldPtr* field, const std::vector<ArgsView>& ArgsList) {
|
||||||
if constexpr (std::is_same_v<R, void>) {
|
if constexpr (std::is_same_v<R, void>) {
|
||||||
MethodType fptr = (MethodType)field->data.method;
|
MethodType fptr = (MethodType)field->data.method;
|
||||||
@ -55,7 +70,7 @@ namespace refl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
constexpr void BuildUList() {
|
consteval void BuildUList() {
|
||||||
if constexpr (!std::is_same_v<R, void>) {
|
if constexpr (!std::is_same_v<R, void>) {
|
||||||
UList[0] = &TypeInfo<R*>::StaticClass;
|
UList[0] = &TypeInfo<R*>::StaticClass;
|
||||||
}
|
}
|
||||||
@ -66,7 +81,7 @@ namespace refl {
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
//为了简化判断,cls 对象 统统指向 T*
|
//为了简化判断,cls 对象 统统指向 T*
|
||||||
constexpr static MyUClass BuildClass() {
|
consteval static MyUClass BuildClass() {
|
||||||
MyUClass cls(type_name<MethodType>().View(), sizeof(MethodType));
|
MyUClass cls(type_name<MethodType>().View(), sizeof(MethodType));
|
||||||
cls.vtable.GetParams = &MyUClass::GetParams;
|
cls.vtable.GetParams = &MyUClass::GetParams;
|
||||||
cls.vtable.Call = &MyUClass::Call;
|
cls.vtable.Call = &MyUClass::Call;
|
||||||
@ -74,6 +89,7 @@ namespace refl {
|
|||||||
return cls;
|
return cls;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
class UClass_Custom : public UClass {
|
class UClass_Custom : public UClass {
|
||||||
public:
|
public:
|
||||||
using UClass::UClass;
|
using UClass::UClass;
|
||||||
@ -96,13 +112,27 @@ namespace refl {
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void BuildClass() {
|
void BuildClass() {
|
||||||
FList.shrink_to_fit();//缩减容量,FList大小不再改变了
|
FList.shrink_to_fit();//缩减容量,FList大小不再改变了
|
||||||
vtable.GetField = &UClass_Custom::GetField;
|
vtable.GetField = &UClass_Custom::GetField;
|
||||||
}
|
}
|
||||||
*/
|
};*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T, typename P = void>
|
||||||
|
class UClass_Meta : public UClass {
|
||||||
|
public:
|
||||||
|
using FieldsType = decltype(T::__BuildFields());
|
||||||
|
FieldsType Fields{ T::__BuildFields() };
|
||||||
|
consteval UClass_Meta() : UClass(type_name<T>().View(), sizeof(T)){
|
||||||
|
if constexpr (!std::is_same_v<P, void>) {
|
||||||
|
parent = &TypeInfo<P>::StaticClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//基础类型的偏特化
|
//基础类型的偏特化
|
||||||
template<_ReflCheck_Ctor_NoUClass T>
|
template<_ReflCheck_Ctor_NoUClass T>
|
||||||
struct TypeInfoImpl<T> {
|
struct TypeInfoImpl<T> {
|
||||||
@ -116,28 +146,10 @@ 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<_ReflCheck_UClass T>
|
template<_ReflCheck_UClass T>
|
||||||
struct TypeInfoImpl<T> {
|
struct TypeInfoImpl<T> {
|
||||||
using MyUClass = typename T::MyUClass;
|
using MyUClass = typename T::MyUClass;
|
||||||
inline static MyUClass StaticClass = []()->MyUClass {
|
//这里如何改成 constexpr
|
||||||
MyUClass cls(type_name<T>().View(), sizeof(T));
|
inline constexpr static MyUClass StaticClass = MyUClass();
|
||||||
T::BuildClass(cls);
|
|
||||||
auto& vtable = cls.vtable;
|
|
||||||
if (!vtable.GetField) {
|
|
||||||
vtable.GetField = &MyUClass::GetField;
|
|
||||||
}
|
|
||||||
if constexpr (!std::is_trivially_copyable_v<T>) {
|
|
||||||
if (!vtable.InitObject) {
|
|
||||||
//这里一定会创建一个InitObject<T> 模板函数,如何优化
|
|
||||||
vtable.InitObject = &UClass::InitObject<T>;
|
|
||||||
}
|
|
||||||
if (!vtable.CopyObject) {
|
|
||||||
//这里一定会创建一个CopyObject<T> 模板函数,如何优化
|
|
||||||
vtable.CopyObject = &UClass::CopyObject<T>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cls;
|
|
||||||
}();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
38
engine/3rdparty/zlib/include/refl/refl.h
vendored
38
engine/3rdparty/zlib/include/refl/refl.h
vendored
@ -4,39 +4,55 @@
|
|||||||
namespace refl {
|
namespace refl {
|
||||||
/* 成员变量需要定义默认值吗?那为什么不在initObjec里初始化?*/
|
/* 成员变量需要定义默认值吗?那为什么不在initObjec里初始化?*/
|
||||||
template<typename T, typename Obj>
|
template<typename T, typename Obj>
|
||||||
static FieldPtr MakeMemberField(T Obj::* ptr, Name name) {
|
consteval FieldPtr MakeStaticField(T Obj::* ptr, Name name) {
|
||||||
FieldPtr::Default value;
|
FieldPtr::Default value;
|
||||||
Offset offset = reinterpret_cast<std::size_t>(&(reinterpret_cast<const Obj*>(0)->*ptr));
|
FieldPtr::Data member = { nullptr };
|
||||||
FieldPtr::Data member = { offset };
|
|
||||||
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
|
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
|
||||||
return { name, &TypeInfo<T>::StaticClass, member, value, flag };
|
return { name, &TypeInfo<T>::StaticClass, member, value, flag };
|
||||||
}
|
}
|
||||||
template<typename R, typename ...Args>
|
template<typename R, typename ...Args>
|
||||||
static FieldPtr MakeMethodField(R(*ptr)(Args...), Name name, const std::vector<ArgsValue>& args = {}) {
|
consteval FieldPtr MakeStaticField(R(*ptr)(Args...), Name name/*, const std::vector<ArgsValue>& args = {}*/) {
|
||||||
uint32_t flag = FIELD_METHOD_FLAG;
|
uint32_t flag = FIELD_METHOD_FLAG;
|
||||||
FieldPtr::Default value;
|
FieldPtr::Default value;
|
||||||
if (args.size() > 0) {
|
/*if (args.size() > 0) {
|
||||||
flag |= FIELD_METHOD_VALUE_FLAG;
|
flag |= FIELD_METHOD_VALUE_FLAG;
|
||||||
static const ArgsValueList argsValue(args);
|
static const ArgsValueList argsValue(args);
|
||||||
value.method = []() ->std::pair<ArgsView*, int> {
|
value.method = []() ->std::pair<ArgsView*, int> {
|
||||||
return { argsValue.ptr , argsValue.num };
|
return { argsValue.ptr , argsValue.num };
|
||||||
};
|
};
|
||||||
}
|
}*/
|
||||||
FieldPtr::Data method = { *(Method*)&ptr };
|
FieldPtr::Data method = { nullptr };
|
||||||
return { name, &TypeInfo<real_type_t<R>(*)(real_type_t<Args>...)>::StaticClass, method, value, flag };
|
return { name, &TypeInfo<real_type_t<R>(*)(real_type_t<Args>...)>::StaticClass, method, value, flag };
|
||||||
}
|
}
|
||||||
template<typename T, typename R, typename ...Args>
|
template<typename T, typename R, typename ...Args>
|
||||||
static FieldPtr MakeMethodField(R(T::* ptr)(Args...), Name name, const std::vector<ArgsValue>& args = {}) {
|
consteval FieldPtr MakeStaticField(R(T::* ptr)(Args...), Name name/*, const std::vector<ArgsValue>& args = {}*/) {
|
||||||
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
|
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
|
||||||
FieldPtr::Default value;
|
FieldPtr::Default value;
|
||||||
if (args.size() > 0) {
|
/*if (args.size() > 0) {
|
||||||
flag |= FIELD_METHOD_VALUE_FLAG;
|
flag |= FIELD_METHOD_VALUE_FLAG;
|
||||||
static const ArgsValueList argsValue(args);
|
static const ArgsValueList argsValue(args);
|
||||||
value.method = []() ->std::pair<ArgsView*, int> {
|
value.method = []() ->std::pair<ArgsView*, int> {
|
||||||
return { argsValue.ptr , argsValue.num };
|
return { argsValue.ptr , argsValue.num };
|
||||||
};
|
};
|
||||||
}
|
}*/
|
||||||
FieldPtr::Data method = { *(Method*)&ptr };
|
//Method fptr = nullptr;
|
||||||
|
FieldPtr::Data method = { nullptr };
|
||||||
return { name, &TypeInfo<real_type_t<R>(*)(const void*,real_type_t<Args>...)>::StaticClass, method, value,flag };
|
return { name, &TypeInfo<real_type_t<R>(*)(const void*,real_type_t<Args>...)>::StaticClass, method, value,flag };
|
||||||
}
|
}
|
||||||
|
template<typename ...Args>
|
||||||
|
consteval auto MakeTuple(Args&&... args) {
|
||||||
|
return std::make_tuple(args...);
|
||||||
|
}
|
||||||
|
template<typename ...Args>
|
||||||
|
auto MakeStaticFields(const std::tuple<Args...>& args) {
|
||||||
|
constexpr std::size_t N = sizeof...(Args);
|
||||||
|
std::array<FieldPtr, N> fields{};
|
||||||
|
for (std::size_t i = 0; i < N; ++i) {
|
||||||
|
auto& arg = std::get<0>(args);
|
||||||
|
auto a1 = std::get<0>(arg);
|
||||||
|
auto a2 = std::get<1>(arg);
|
||||||
|
//fields[i] = MakeStaticField(std::get<0>(arg), std::get<1>(arg));
|
||||||
|
}
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
33
engine/3rdparty/zlib/test/refl/vertex.h
vendored
33
engine/3rdparty/zlib/test/refl/vertex.h
vendored
@ -32,16 +32,27 @@ struct vec3 : public vec3_parent {
|
|||||||
x1 = x1 * 10;
|
x1 = x1 * 10;
|
||||||
//cout << x1 << "::norm3" << endl;
|
//cout << x1 << "::norm3" << endl;
|
||||||
}
|
}
|
||||||
using MyUClass = UClass_Custom;
|
constexpr static auto __GetFields() {
|
||||||
static void BuildClass(MyUClass& cls) {
|
return std::tuple{
|
||||||
cls.parent = &TypeInfo<vec3_parent>::StaticClass;
|
MakeTuple(&vec3::x, "x"),
|
||||||
cls.AttrNum = 3;
|
MakeTuple(&vec3::y, "y"),
|
||||||
cls.FList = {
|
MakeTuple(&vec3::z, "z"),
|
||||||
MakeMemberField(&vec3::x, "x"),
|
MakeTuple(&vec3::norm, "norm"),
|
||||||
MakeMemberField(&vec3::y, "y"),
|
MakeTuple(&vec3::norm1, "norm1"),
|
||||||
MakeMemberField(&vec3::z, "z"),
|
MakeTuple(&vec3::norm2, "norm2")
|
||||||
MakeMethodField(&vec3::norm, "norm", {8, 9}),
|
|
||||||
MakeMethodField(&vec3::norm1, "norm1",{(float)2.0})
|
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
|
#define REGISTER_FIELDS(MemberFunc, MethodFunc)\
|
||||||
|
MemberFunc(&vec3::x, "x")\
|
||||||
|
MemberFunc(&vec3::y, "y")\
|
||||||
|
MemberFunc(&vec3::z, "z")\
|
||||||
|
MethodFunc(&vec3::norm,"norm",{})\
|
||||||
|
MethodFunc(&vec3::norm1,"norm1",{})\
|
||||||
|
MethodFunc(&vec3::norm2,"norm2",{})
|
||||||
|
REGISTER_CLASS_META(vec3, vec3_parent)
|
||||||
|
BUILD_FELDS()
|
||||||
|
|
||||||
|
|
||||||
|
#undef REGISTER_FIELDS
|
||||||
};
|
};
|
||||||
64
engine/3rdparty/zlib/test/refl_01.cpp
vendored
64
engine/3rdparty/zlib/test/refl_01.cpp
vendored
@ -1,40 +1,28 @@
|
|||||||
#include "refl/vertex.h"
|
#include "refl/vertex.h"
|
||||||
#include <benchmark/benchmark.h>
|
union MemberMethod {
|
||||||
void TestRefl1(benchmark::State& state) {
|
using F1 = int(*)(int);
|
||||||
auto cls = &TypeInfo<vec3>::StaticClass;
|
using F2 = void(*)();
|
||||||
vec3 v;
|
F1 f1;
|
||||||
auto ptr = (void*)&v;
|
F2 f2;
|
||||||
auto ov = cls->New(ptr);
|
constexpr MemberMethod(F1 f):f1(f) {
|
||||||
int x = 1, y = 2;
|
|
||||||
for (auto _ : state) {
|
|
||||||
ov.Invoke("norm", { {},ptr, x, y});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BENCHMARK(TestRefl1);
|
|
||||||
void TestRefl2(benchmark::State& state) {
|
|
||||||
auto cls = &TypeInfo<vec3>::StaticClass;
|
|
||||||
vec3 v;
|
|
||||||
auto ptr = (void*)&v;
|
|
||||||
auto ov = cls->New(ptr);
|
|
||||||
int x = 1, y = 2;
|
|
||||||
std::vector<ArgsView> ArgsList;
|
|
||||||
ArgsList.emplace_back();
|
|
||||||
ArgsList.emplace_back(ptr);
|
|
||||||
ArgsList.emplace_back(x);
|
|
||||||
ArgsList.emplace_back(y);
|
|
||||||
auto field = cls->GetField(cls, "norm", true);
|
|
||||||
for (auto _ : state) {
|
|
||||||
field->Invoke(ArgsList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BENCHMARK(TestRefl2);
|
|
||||||
void TestCPlusPlus(benchmark::State& state) {
|
|
||||||
vec3 v;
|
|
||||||
int x = 1, y = 2;
|
|
||||||
for (auto _ : state) {
|
|
||||||
v.norm(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BENCHMARK(TestCPlusPlus);
|
|
||||||
|
|
||||||
BENCHMARK_MAIN();
|
}
|
||||||
|
constexpr MemberMethod(F2 f) :f2(f) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
void test() {
|
||||||
|
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
void print(T* t) {
|
||||||
|
|
||||||
|
}
|
||||||
|
int main() {
|
||||||
|
//auto& cls = TypeInfo<vec3>::StaticClass;
|
||||||
|
//int FList[3]{};
|
||||||
|
//auto norm = MakeMethodField(&vec3::norm,"norm");
|
||||||
|
MakeStaticFields(vec3::__GetFields());
|
||||||
|
std::cout << "hello world\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user