refl rebuild

This commit is contained in:
ouczbs 2024-04-25 21:45:41 +08:00
parent 27648e1b41
commit 0828271799
18 changed files with 267 additions and 214 deletions

View File

@ -8,7 +8,9 @@ namespace refl {
public:
const void* ptr;
const UClass* cls;
constexpr Any(const void* ptr,const UClass* cls) : ptr(ptr), cls(cls) {}
constexpr Any(const void* ptr, const UClass* cls) : ptr(ptr), cls(cls) {
//assert(cls->flag & CLASS_POINTER_FLAG);
}
constexpr Any() : ptr(nullptr), cls(nullptr) {}
//右值=>右值压入栈caller入栈地址
//左值=>caller变量地址
@ -27,7 +29,7 @@ namespace refl {
}
}
template<typename T>//参数 T* => T*
constexpr inline T cast_to() const {
constexpr inline T CastTo() const {
if constexpr (std::is_pointer_v<T>) {
return (T)ptr;
}
@ -39,22 +41,14 @@ namespace refl {
return *(T*)ptr;
}
}
template<typename T>
T cast_ret() const {
if constexpr (std::is_pointer_v<T>) {
return *(T*)ptr;
}
else if constexpr (std::is_reference_v<T>) {
using RT = std::remove_reference_t<T>;
return **(RT**)ptr;
}
else {
return *(T*)ptr;
}
}
Any* ConvertTo(const UClass* toClass);
bool Check(const UClass* toClass)const;
constexpr bool IsValid() const{
return cls != nullptr && ptr != nullptr;
}
constexpr int Size()const;
constexpr const UClass* Parent()const;
constexpr Any Change(const void* ptr)const {
return {ptr, cls};
}
};
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "any.h"
#include <map>
namespace refl {
using ConvertFunc = bool (*)(Any&, const Any&);
using ConvertMap = std::map<const UClass*, ConvertFunc>;
class Convert {
protected:
static ConvertMap BuildClassMap();
public:
static bool ToString(Any& dst,const Any& src);
static bool Construct(Any& dst, const Any& src);
inline static ConvertMap ClassMap = BuildClassMap();
};
}

View File

@ -0,0 +1,32 @@
#pragma once
#include <string>
#include "convert.h"
namespace refl {
bool Convert::ToString(Any& dst, const Any& src)
{
if (src.Parent() == &TypeInfo<char>::StaticClass) {
std::construct_at(dst.CastTo<std::string*>(), src.CastTo<const char*>());
return true;
}
return false;
}
inline bool Convert::Construct(Any& dst, const Any& src)
{
if (dst.Check(src.cls)) {
dst.cls->InitObject((void*)dst.ptr);
dst.cls->CopyObject((void*)dst.ptr, src.ptr);
return true;
}
auto it = ClassMap.find(dst.cls);
if (it == ClassMap.end()) {
return false;
}
return it->second(dst, src);
}
ConvertMap Convert::BuildClassMap()
{
ConvertMap classMap;
classMap.emplace(&TypeInfo<std::string*>::StaticClass, &ToString);
return classMap;
}
}

View File

@ -13,17 +13,19 @@ namespace refl {
using Offset = uint32_t;
using Method = void*;
struct MemberData {
Offset offset;
Offset offset{0};
Any value;
Any meta;
constexpr MemberData() :offset(0), value(), meta() {}
constexpr MemberData() :value(), meta() {}
constexpr MemberData(const Any& value, const Any& meta = {}) : value(value), meta(meta) {}
constexpr MemberData(Offset offset,const Any& value,const Any& meta) : offset(offset), value(value), meta(meta) {}
};
struct MethodData {
Method fptr;
Method fptr{nullptr};
sarray<Any> value;
Any meta;
constexpr MethodData() :fptr(nullptr), value(), meta() {}
constexpr MethodData() :value(), meta() {}
constexpr MethodData(const sarray<Any>& value, const Any& meta = {}) : value(value), meta(meta) {}
constexpr MethodData(Method fptr,const sarray<Any>& value, const Any& meta) : fptr(fptr), value(value), meta(meta) {}
};
enum FieldFlag:uint32_t {

View File

@ -36,7 +36,7 @@ namespace refl {
Any* a = ArgsList.front();
auto p = params.front();
for (auto e = params.back(); p < e; ++p, ++a) {
if (a->cls != *p && !a->ConvertTo(*p)) {
if (a->cls != *p && !a->Check(*p)) {
return false;
}
}

View File

@ -26,20 +26,18 @@ namespace refl {
META_UI_FLAG = 1 << 0,
};
class UClass;
class MemberDataValue;
class MethodDataValue;
class Meta {
public:
UClass* cls;
uint32_t flag{ 0 };
template<typename T, typename Obj>
static FieldPtr MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberDataValue& data = {});
static FieldPtr MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberData& data = {});
template<typename R, typename ...Args>
static FieldPtr MethodField(R(*ptr)(Args...), const Name& name,char*& memory, const MethodDataValue& data = {});
static FieldPtr MethodField(R(*ptr)(Args...), const Name& name,char*& memory, const MethodData& data = {});
template<typename T,typename R, typename ...Args>
static FieldPtr MethodField(R(T::*ptr)(Args...), const Name& name,char*& memory, const MethodDataValue& data = {});
static FieldPtr MethodField(R(T::*ptr)(Args...), const Name& name,char*& memory, const MethodData& data = {});
};
}

View File

@ -1,68 +1,64 @@
#pragma once
#include "meta.h"
#include "uclass.h"
#include "convert.h"
namespace refl {
template<typename T, typename Obj>
inline FieldPtr Meta::MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberDataValue& data)
inline FieldPtr Meta::MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberData& data)
{
MemberData member;
auto cls = &TypeInfo<T*>::StaticClass;
member.offset = reinterpret_cast<std::size_t>(&(reinterpret_cast<const Obj*>(0)->*ptr));
if (AnyValue arg = data.value; arg.IsValid()) {
arg.type->InitObject(memory);
arg.type->CopyObject(memory, arg.ptr);
member.value = Any(memory, arg.cls).ConvertTo(&TypeInfo<real_type_t<T>*>::StaticClass);
memory += arg.type->size;
if (data.value.IsValid()) {
member.value = Any(memory, cls);
assert(Convert::Construct(member.value, data.value));
memory += member.value.Size();
}
if (AnyValue arg = data.meta; arg.IsValid()) {
arg.type->InitObject(memory);
arg.type->CopyObject(memory, arg.ptr);
member.meta = Any(memory, arg.cls);
memory += arg.type->size;
if (data.meta.IsValid()) {
member.meta = data.meta.Change(memory);
Convert::Construct(member.meta, data.meta);
memory += data.meta.Size();
}
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
return { name, &TypeInfo<T>::StaticClass, member,flag};
return { name, cls, member,flag};
}
template<typename R, typename ...Args>
inline FieldPtr Meta::MethodField(R(*ptr)(Args...), const Name& name, char*& memory, const MethodDataValue& data)
inline FieldPtr Meta::MethodField(R(*ptr)(Args...), const Name& name, char*& memory, const MethodData& data)
{
MethodData method;
uint32_t flag = FIELD_METHOD_FLAG;
auto cls = &TypeInfo<real_type_t<R>(*)(real_type_t<Args>...)>::StaticClass;
if (auto& args = data.value; !args.empty()) {
constexpr auto cls = &TypeInfo<real_type_t<R>(*)(real_type_t<Args>...)>::StaticClass;
if (data.value.IsValid()) {
flag |= FIELD_METHOD_VALUE_FLAG;
AnyValueList argsValue(args, memory);
argsValue.ConvertArgs(cls->vtable.GetParams(cls));
method.value = argsValue.ToSArray();
memory += AnyValueList::GetArgsSize(args);
AnyArgs args(data.value, cls->GetParams(), memory);
method.value = args.ToSArray();
memory += args.Size();
}
if (AnyValue arg = data.meta; arg.IsValid()) {
arg.type->InitObject(memory);
arg.type->CopyObject(memory, arg.ptr);
method.meta = Any(memory, arg.cls);
memory += arg.type->size;
if (data.meta.IsValid()) {
method.meta = data.meta.Change(memory);
Convert::Construct(method.meta, data.meta);
memory += data.meta.Size();
}
method.fptr = { *(Method*)&ptr };
return { name, cls, method,flag };
}
template<typename T, typename R, typename ...Args>
inline FieldPtr Meta::MethodField(R(T::*ptr)(Args...),const Name& name, char*& memory, const MethodDataValue& data)
inline FieldPtr Meta::MethodField(R(T::*ptr)(Args...),const Name& name, char*& memory, const MethodData& data)
{
MethodData method;
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
auto cls = &TypeInfo<real_type_t<R>(*)(const void*, real_type_t<Args>...)>::StaticClass;
if (auto& args = data.value; !args.empty()) {
constexpr auto cls = &TypeInfo<real_type_t<R>(*)(const void*, real_type_t<Args>...)>::StaticClass;
if (data.value.IsValid()) {
flag |= FIELD_METHOD_VALUE_FLAG;
AnyValueList argsValue(args, memory);
argsValue.ConvertArgs(cls->vtable.GetParams(cls));
method.value = argsValue.ToSArray();
memory += AnyValueList::GetArgsSize(args);
AnyArgs args(data.value, cls->GetParams(), memory);
method.value = args.ToSArray();
memory += args.Size();
}
if (AnyValue arg = data.meta; arg.IsValid()) {
arg.type->InitObject(memory);
arg.type->CopyObject(memory, arg.ptr);
method.meta = Any(memory, arg.cls);
memory += arg.type->size;
if (data.meta.IsValid()) {
method.meta = data.meta.Change(memory);
Convert::Construct(method.meta, data.meta);
memory += data.meta.Size();
}
method.fptr = { *(Method*)&ptr };
return { name, cls, method,flag };

View File

@ -6,6 +6,8 @@ namespace refl {
enum ClassFlag :uint32_t {
CLASS_NONE_FLAG = 0,
CLASS_TRIVIAL_FLAG = 1 << 0,
CLASS_POINTER_FLAG = 1 << 1,
CLASS_ARRAY_FLAG = 1 << 2,
};
using enum ClassFlag;
struct vtable_uclass
@ -63,18 +65,7 @@ namespace refl {
}
template<typename T>
bool IsChildOf(bool bthis = false) const {
constexpr UClass* cls = &TypeInfo<T>::StaticClass;
if (bthis) {
return cls == this;
}
const UClass* _parent = this;
while (_parent != nullptr) {
if (_parent == cls) {
return true;
}
_parent = _parent->parent;
}
return false;
return IsChildOf(&TypeInfo<T>::StaticClass);
}
public:
const FieldPtr* GetField(const Name& name, int index)const {
@ -114,5 +105,21 @@ namespace refl {
static void CopyObject(void* dst, const void* src) {
*(T*)dst = *(T*)src;
}
template<_ReflCheck_Ctor T, int N>
static void InitObject(void* ptr) {
T* tptr = (T*)ptr;
T obj{};
for (int i = 0; i < N; i++) {
std::construct_at(tptr++, obj);
}
}
template<typename T, int N>
static void CopyObject(void* dst, const void* src) {
T* tdst = (T*)dst;
const T* tsrc = (const T*)src;
for (int i = 0; i < N; i++) {
*tdst++ = *tsrc++;
}
}
};
}

View File

@ -14,6 +14,13 @@ namespace refl {
cls.vtable.InitObject = &MyUClass::InitObject<T>;
cls.vtable.CopyObject = &MyUClass::CopyObject<T>;
}
else if constexpr (std::is_pointer_v<T>){
using RawT = std::remove_pointer_t<T>;
cls.flag = CLASS_POINTER_FLAG;
if constexpr (!std::is_same_v<RawT, void>) {
cls.parent = &TypeInfo<RawT>::StaticClass;
}
}
else {
cls.flag = CLASS_TRIVIAL_FLAG;
}
@ -26,7 +33,27 @@ namespace refl {
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_trivially_copyable_v<T>) {
cls.vtable.InitObject = &MyUClass::InitObject<T, N>;
cls.vtable.CopyObject = &MyUClass::CopyObject<T, N>;
}
else if constexpr (std::is_pointer_v<T>) {
cls.flag = CLASS_POINTER_FLAG | CLASS_ARRAY_FLAG;
}
else {
cls.flag = CLASS_TRIVIAL_FLAG | CLASS_ARRAY_FLAG;
}
return cls;
}
};
/*
* 模板优化
* 成员参数转化为const void*
@ -40,7 +67,9 @@ namespace refl {
using MyUClass = UMethod_Auto<R, Args...>;
public:
std::array<const UClass*, sizeof...(Args) + 1> UList{};
consteval sarray<const UClass*> GetParams()const {
return sarray<const UClass*>(&UList.front(), UList.size());
}
static sarray<const UClass*> GetParams(const UClass* cls) {
auto& UList = static_cast<const MyUClass*>(cls)->UList;
return sarray<const UClass*>(&UList.front(),UList.size());
@ -53,17 +82,17 @@ namespace refl {
if constexpr (std::is_same_v<R, void>) {
MethodType fptr = (MethodType)field->data.method.fptr;
auto param = ArgsList.end();
fptr((param--->cast_to<Args>())...);
fptr((param--->CastTo<Args>())...);
}
else {
MethodType fptr = (MethodType)field->data.method.fptr;
auto param = ArgsList.end();
auto ret = ArgsList.front();
if (ret->cls == &TypeInfo<R*>::StaticClass) {
*(R*)ret->ptr = fptr((param--->cast_to<Args>())...);
*(R*)ret->ptr = fptr((param--->CastTo<Args>())...);
}
else {
fptr((param--->cast_to<Args>())...);
fptr((param--->CastTo<Args>())...);
}
}
}
@ -74,7 +103,7 @@ namespace refl {
}
if constexpr (sizeof...(Args) > 0) {
auto ptr = &UList[1];
(..., (*ptr = &TypeInfo<std::remove_cv_t<std::remove_pointer_t<Args>>*>::StaticClass, ptr++));
(..., (*ptr = &TypeInfo<args_type_t<Args>*>::StaticClass, ptr++));
}
}
public:
@ -143,4 +172,9 @@ namespace refl {
using MyUClass = typename T::MyMeta::MyUClass;
inline static MyUClass StaticClass = MyUClass();
};
template<typename T, int N>
struct TypeInfoImpl<T[N]> {
using UClass = UClass_Array<T,N>;
inline constexpr static UClass StaticClass = UClass::BuildClass();
};
}

View File

@ -2,36 +2,16 @@
#include <string>
#include "field.h"
namespace refl {
//存入的是真实的数据类型,type用于拷贝数据
struct AnyValue : public Any {
const UClass* type;
constexpr AnyValue() :Any(), type(nullptr) {}
template<typename T>
constexpr AnyValue(T&& t) : Any(t), type(&TypeInfo<args_type_t<T>>::StaticClass){}
};
struct MemberDataValue {
Offset offset{0};
AnyValue value;
AnyValue meta;
constexpr MemberDataValue() :value(), meta() {}
constexpr MemberDataValue(const AnyValue& value, const AnyValue& meta = {}) : value(value), meta(meta) {}
};
struct MethodDataValue {
Method fptr{nullptr};
sarray<AnyValue> value;
AnyValue meta;
constexpr MethodDataValue() :value(), meta() {}
constexpr MethodDataValue(const sarray<AnyValue>& value, const AnyValue& meta = {}) : value(value), meta(meta) {}
};
struct AnyValueList{
struct AnyArgs {
void* data;
int num;
int size;
bool isMemoryOwner{false};
AnyValueList(const sarray<AnyValue>& args,void* memory = nullptr);
~AnyValueList();
void ConvertArgs(sarray<const UClass*> params);
AnyArgs(const sarray<Any>& args,const sarray<const UClass*>& params,void* memory = nullptr);
~AnyArgs();
int Size();
const sarray<Any> ToSArray();
constexpr static int GetArgsSize(const sarray<AnyValue>& args);
constexpr static Offset GetArgsSize(const sarray<Any>& args, const sarray<const UClass*>& params);
};
class AnyView : public Any{
public:

View File

@ -1,90 +1,96 @@
#pragma once
#include "uclass.h"
#include "view.h"
#include "convert.h"
namespace refl {
/*平凡对象的转化要支持吗
* 比如同大小的安全转化
* 对象从小到大
* 对象从大到小
*/
using enum ClassFlag;
Any* Any::ConvertTo(const UClass* toClass) {
bool Any::Check(const UClass* toClass) const{
if (cls == toClass) {
return this;
return true;
}
auto p1 = cls->parent;
auto p2 = toClass->parent;
assert(p1 && p2);
//子类转父类
if (cls->IsChildOf(toClass)) {
cls = toClass;
return this;
if (p1->IsChildOf(p2)) {
return true;
}
if (cls->flag & CLASS_TRIVIAL_FLAG && toClass->flag & CLASS_TRIVIAL_FLAG) {
cls = toClass;
return this;
if (p1->flag & CLASS_TRIVIAL_FLAG && p2->flag & CLASS_TRIVIAL_FLAG && p1->size >= p2->size) {
return true;
}
return nullptr;
return false;
}
AnyValueList::AnyValueList(const sarray<AnyValue>& args, void* memory)
: data(memory), num(args.size())
inline constexpr int Any::Size()const
{
return cls->parent->size;
}
inline constexpr const UClass* Any::Parent()const
{
return cls->parent;
}
AnyArgs::AnyArgs(const sarray<Any>& args, const sarray<const UClass*>& params, void* memory)
: data(memory), num(args.size()), size(GetArgsSize(args, params))
{
assert(size > 0);
if (!memory) {
isMemoryOwner = true;
data = malloc(GetArgsSize(args));
data = malloc(size);
}
Any* any = (Any*)data;
assert(any != nullptr);
char* pData = ((char*)data) + num * sizeof(Any);
auto uptr = params.at(params.size() - args.size());
for (auto& arg : args) {
arg.type->InitObject(pData);
arg.type->CopyObject(pData, arg.ptr);
any->cls = *uptr;
any->ptr = pData;
any->cls = arg.cls;
assert(Convert::Construct(*any, arg));
any++;
pData += arg.type->size;
pData += (*uptr)->parent->size;
}
}
inline AnyValueList::~AnyValueList()
inline AnyArgs::~AnyArgs()
{
if (num == 0 || !data) {
return;
}
Any* ptr = (Any*)data;
for (int i = 0; i < num; i++) {
ptr->cls->DestObject((void*)ptr->ptr);
ptr++;
}
if (isMemoryOwner) {
Any* any = (Any*)data;
for (int i = 0; i < num; i++) {
any->cls->DestObject((void*)any->ptr);
any++;
}
free(data);
}
num = 0;
data = nullptr;
}
inline void AnyValueList::ConvertArgs(sarray<const UClass*> params)
inline int AnyArgs::Size()
{
Any* ptr = (Any*)data;
int first = params.size() - num;
for (int i = 0; i < num; i++, ptr++) {
ptr->ConvertTo(*params.at(first + i));
}
return size;
}
inline const sarray<Any> AnyValueList::ToSArray()
inline const sarray<Any> AnyArgs::ToSArray()
{
return sarray<Any>((Any*)data, num);
}
inline constexpr int AnyValueList::GetArgsSize(const sarray<AnyValue>& args)
{
int size = args.size() * sizeof(Any);
for (auto& arg : args) {
size += arg.type->size;
inline constexpr Offset AnyArgs::GetArgsSize(const sarray<Any>& args,const sarray<const UClass*>& params)
{ //这里空间换时间Any多占用了一个数据指针
if (args.size() == 0 || params.size() < args.size() + 1) {
return 0;
}
return size;
Offset offset = args.size() * sizeof(Any);
auto uptr = params.at(params.size() - args.size());
for (auto uend = params.back(); uptr < uend; uptr++) {
offset += (*uptr)->parent->size;//数据大小
}
return offset;
}
template<typename T>
inline bool AnyView::Get(const Name& name, T& t)
{
if (cache && cache->name == name) {
_cache_get: bool isChild = cache->type->IsChildOf<T>(true);
_cache_get: bool isChild = cache->type->IsChildOf<T>();
if (isChild) {
t = *(T*)((const char*)ptr + cache->data.offset);
t = *(T*)((const char*)ptr + cache->data.member.offset);
}
return isChild;
}
@ -102,9 +108,9 @@ namespace refl {
inline bool AnyView::Set(const Name& name, const T& t)
{
if (cache && cache->name == name) {
_cache_set: bool isChild = cache->type->IsChildOf<T>(true);
_cache_set: bool isChild = cache->type->IsChildOf<T>();
if (isChild) {
*(T*)((const char*)ptr + cache->data.offset) = t;
*(T*)((const char*)ptr + cache->data.member.offset) = t;
}
return isChild;
}

View File

@ -2,39 +2,42 @@
#include "detail/uclass.inl"
#include "detail/view.inl"
#include "detail/field.inl"
#include "detail/convert.inl"
#include "detail/meta.inl"
#include "std/sarray.h"
#include "macro.h"
namespace refl {
template<typename T, typename Obj>
consteval FieldPtr StaticMemberField(T Obj::* ptr, const Name& name, const MemberDataValue& data = {}) {
consteval FieldPtr StaticMemberField(T Obj::* ptr, const Name& name, const MemberData& data = {}) {
Offset offset = data.value.IsValid() ? sizeof(T) : 0;
if (data.meta.IsValid()) {
offset += data.meta.type->size;
offset += data.meta.Size();
}
FieldPtr::Data member(offset);
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
return { name,&TypeInfo<T>::StaticClass, member,flag};
}
template<typename R, typename ...Args>
consteval FieldPtr StaticMethodField(R(*ptr)(Args...), const Name& name, const MethodDataValue& data = {}) {
consteval FieldPtr StaticMethodField(R(*ptr)(Args...), const Name& name, const MethodData& data = {}) {
uint32_t flag = FIELD_METHOD_FLAG;
Offset offset = AnyValueList::GetArgsSize(data.value);
auto cls = &TypeInfo<real_type_t<R>(*)(real_type_t<Args>...)>::StaticClass;
Offset offset = AnyArgs::GetArgsSize(data.value, cls->GetParams());
if (data.meta.IsValid()) {
offset += data.meta.type->size;
offset += data.meta.Size();
}
FieldPtr::Data method(offset);
return { name,&TypeInfo<real_type_t<R>(*)(real_type_t<Args>...)>::StaticClass,method, flag };
return { name,cls,method, flag };
}
template<typename T, typename R, typename ...Args>
consteval FieldPtr StaticMethodField(R(T::* ptr)(Args...), const Name& name, const MethodDataValue& data = {}) {
consteval FieldPtr StaticMethodField(R(T::* ptr)(Args...), const Name& name, const MethodData& data = {}) {
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
Offset offset = AnyValueList::GetArgsSize(data.value);
auto cls = &TypeInfo<real_type_t<R>(*)(const void*, real_type_t<Args>...)>::StaticClass;
Offset offset = AnyArgs::GetArgsSize(data.value, cls->GetParams());
if (data.meta.IsValid()) {
offset += data.meta.type->size;
offset += data.meta.Size();
}
FieldPtr::Data method(offset);
return { name, &TypeInfo<real_type_t<R>(*)(const void*,real_type_t<Args>...)>::StaticClass,method,flag };
return { name, cls,method,flag };
}
//用处不大---------------begin
template<_ReflCheck_Meta T>

View File

@ -12,18 +12,21 @@ namespace refl {
constexpr sarray(const svector<T>& vec) : m_ptr(vec.front()), m_count(vec.size()) {}
constexpr sarray() :m_ptr(nullptr), m_count(0) {}
constexpr sarray(std::initializer_list<T> list) : m_ptr(list.begin()), m_count(list.size()) {}
const T* front() const noexcept {
constexpr const T* front() const noexcept {
return m_ptr;
}
const T* back()const noexcept {
constexpr const T* back()const noexcept {
return m_ptr + m_count;
}
const T* at(int i) const noexcept {
constexpr const T* at(int i) const noexcept {
if (i < m_count) {
return m_ptr + i;
}
return nullptr;
}
constexpr bool IsValid() const noexcept {
return m_count > 0;
}
constexpr bool empty() const noexcept {
return m_count == 0;
}

View File

@ -11,18 +11,21 @@ namespace refl {
public:
constexpr svector() :m_ptr(nullptr), m_count(0), m_capicty(0){}
constexpr svector(T* ptr, int size, int count) : m_ptr(ptr), m_capicty(size), m_count(count){}
T* front()const noexcept {
constexpr T* front()const noexcept {
return m_ptr;
}
T* back()const noexcept {
constexpr T* back()const noexcept {
return m_ptr + m_count;
}
void push_back(const T& t) {
constexpr void push_back(const T& t) {
if (m_count < m_capicty) {
*(m_ptr + m_count) = t;
m_count++;
}
}
constexpr bool IsValid() const noexcept {
return m_count > 0;
}
constexpr bool empty() const noexcept {
return m_count == 0;
}

View File

@ -21,7 +21,8 @@ struct vec3 : public vec3_parent {
float y = 2;
__cppast(Meta = { 0.f})
float z = 3;
string name{ "hello" };
__cppast(Meta = { "hello meta"})
string name = "???";
__cppast(Meta = { {3,4} })
int norm(int x1, int& x2)override {
int tmp = x1 * 2 + 1;
@ -30,6 +31,7 @@ struct vec3 : public vec3_parent {
return x2;
//cout << x2 << "vec3::norm" << endl;
}
__cppast(Meta = {})
virtual float norm1(int& x1) {
x1 = x1 * x * y * z;
x = x1;
@ -38,47 +40,15 @@ struct vec3 : public vec3_parent {
//cout << x1 << "::norm1" << endl;
return x1;
}
__cppast(Meta = {})
static void norm2(int x1 = 10) {
cout << x1 << "::norm2" << endl;
}
__cppast(Meta = {})
static void norm3(int x1 = 10) {
x1 = x1 * 10;
cout << x1 << "::norm3" << endl;
}
};
struct vec3_Static_Meta {
//这里好像不需要
consteval static auto __StaticFields() {
return std::make_tuple(&vec3::x, &vec3::y, &vec3::z, &vec3::norm, &vec3::norm1, &vec3::norm2);
};
consteval static auto __MakeStaticFields() {
return std::array{
StaticMemberField(&vec3::x, FName("x"), {0.f,vec4{}}),
StaticMemberField(&vec3::y, FName("y"), {0.f,{}}),
StaticMemberField(&vec3::z, FName("z"), {0.f,{}}),
StaticMethodField(&vec3::norm, FName("norm"), {{10,9},{}}),
StaticMethodField(&vec3::norm1, FName("norm1"), {{10},{}}),
StaticMethodField(&vec3::norm2, FName("norm2"), {{10},{}}),
};
}
consteval static int Size() {
return fetch_meta_size<vec3_Static_Meta>();
}
};
struct vec3_Meta : public Meta{
using MyStatic = vec3_Static_Meta;
using MyUClass = UClass_Meta<vec3, vec3_parent>;
inline static char s_data[MyStatic::Size()]{};
static auto __MakeFields() {
char* memory = &s_data[0];
return std::array{
MemberField(&vec3::x, FName("x"),memory, {0.f,vec4{}}),
MemberField(&vec3::y, FName("y"),memory, {0.f,{}}),
MemberField(&vec3::z, FName("z"),memory, {0.f,{}}),
MethodField(&vec3::norm, FName("norm"), memory, {{10,9},{}}),
MethodField(&vec3::norm1, FName("norm1"),memory, {{10},{}}),
MethodField(&vec3::norm2, FName("norm2"),memory, {{10},{}}),
};
};
};
#include "meta_vertex.inl"
#include "meta_vertex_gen.inl"

View File

@ -5,9 +5,15 @@ vec3 v;
constexpr int smeta = sizeof(vec3_Meta);
constexpr int scls = sizeof(decltype(*cls));
auto ov = cls->New((void*)&v);
constexpr Name func = FName("norm");
void TestRefl1(benchmark::State& state) {
int x = 1, y = 2;
auto rx = &vec3_Meta::s_data[0];
auto f = cls->GetField(GetStaticFieldID<vec3_Meta>(FName("name")));
string hello;
ov.Get(FName("name"), hello);
hello = *f->data.member.value.CastTo<string*>();
ov.Set(FName("name"), hello);
constexpr auto r = StaticMemberField(&vec3::name, FName("name"), { ("hello meta")});
for (auto _ : state) {
std::array<Any, 4> arr{&x, ov.ptr};
svector<Any> svec(&arr.front(), arr.size(), 2);

View File

@ -1,20 +1,21 @@
import("core.project.depend")
function cmd_compile(genfile, sourcefile)
function cmd_compile(genfile, sourcefile, template)
print(os.programdir())
import("find_sdk")
local meta = find_sdk.find_my_program("refl")
argv = {"build", sourcefile, "--output=" .. genfile}
print("cmd_compile", genfile)
os.execv(meta.program, argv, {envs = {PATH = meta.sdkdir}})
template = template or path.join(meta.sdkdir, "template/refl.liquid")
argv = {"build", sourcefile, "-o", genfile, "-t", template}
print("cmd_meta_compile", genfile)
os.runv(meta.program, argv)
return argv
end
function _listen_gen_file(target, batch)
function _listen_gen_file(target, batch, template)
genfile, sourcefile = batch[1], batch[2]
local dependfile = target:dependfile(genfile)
depend.on_changed(
function()
cmd_compile(genfile, sourcefile)
cmd_compile(batch[1], batch[2], template)
end,
{dependfile = dependfile, files = sourcefile}
)
@ -24,20 +25,24 @@ function gen(target)
if not gen_batch then
return
end
local template = target:extraconf("rules", "c++.codegen", "template")
for _, batch in ipairs(gen_batch) do
if batch[2] then
_listen_gen_file(target, batch)
_listen_gen_file(target, batch, template)
end
end
end
function main(target, headerfiles)
local sourcedir = path.join(target:autogendir({root = true}), target:plat(), "inl")
if not os.isdir(sourcedir) then
os.mkdir(sourcedir)
end
target:add("includedirs", sourcedir, {public = true})
local gen_batch = {}
for idx, headerfile in pairs(headerfiles) do
-- batch
sourcefile = path.join(sourcedir, "meta_" .. path.basename(headerfile) .. ".inl")
sourcefile = path.join(sourcedir, path.basename(headerfile) .. "_gen.inl")
table.insert(gen_batch, {sourcefile, headerfile})
end
-- save unit batch

View File

@ -13,6 +13,5 @@ rule("c++.codegen")
meta_refl(target, headerfiles)
end)
on_config(function (target)
print("c++.codegen on_config")
import("meta_refl").gen(target)
end)