refl support tuple pair

This commit is contained in:
ouczbs 2024-06-24 22:26:09 +08:00
parent ead02af962
commit dd880d4972
4 changed files with 99 additions and 68 deletions

View File

@ -26,20 +26,22 @@ namespace refl {
return cls->vsize(ptr); return cls->vsize(ptr);
} }
auto begin() { auto begin() {
auto it = cls->vbegin(ptr); Container::iterator it(cls);
return iterator(it, cls); cls->vbegin(it, ptr);
return it;
} }
auto end() { auto end() {
auto it = cls->vend(ptr); Container::iterator it(cls);
return iterator(it, cls); cls->vend(it, ptr);
return it;
} }
// Iterator class // Iterator class
class iterator : public UClass_Container::iterator{ class iterator : public UClass_Container::iterator{
private: private:
const UClass_Container* cls; const UClass_Container* cls;
public: public:
iterator(UClass_Container::iterator it,const UClass_Container* cls) iterator(const UClass_Container* cls)
: UClass_Container::iterator(it), cls(cls) {} : cls(cls) {}
iterator& operator++() noexcept { iterator& operator++() noexcept {
cls->viterator_add(this); cls->viterator_add(this);
return *this; return *this;

View File

@ -107,16 +107,16 @@ namespace refl {
return cls; return cls;
} }
}; };
constexpr static std::array<std::string_view, 16> IndexNames = {
"1", "2", "3", "4", "5", "6", "7", "8",
"9", "10", "11", "12", "13", "14", "15", "16"
};
template<typename... Types> template<typename... Types>
class UClass_Tuple : public UClass { class UClass_Tuple : public UClass {
using UClass::UClass; using UClass::UClass;
using MyUClass = UClass_Tuple<Types...>; using MyUClass = UClass_Tuple<Types...>;
using MyTuple = std::tuple<Types...>; using MyTuple = std::tuple<Types...>;
public: public:
constexpr static std::array<std::string_view, 16> IndexNames = {
"1", "2", "3", "4", "5", "6", "7", "8",
"9", "10", "11", "12", "13", "14", "15", "16"
};
std::array<FieldPtr, sizeof...(Types)> Fields; std::array<FieldPtr, sizeof...(Types)> Fields;
static bool construct(void* ptr, const UClass* cls, const sarray<Any>& ArgsList) { static bool construct(void* ptr, const UClass* cls, const sarray<Any>& ArgsList) {
new(ptr)MyTuple(); new(ptr)MyTuple();
@ -125,11 +125,27 @@ namespace refl {
static void destruct(void* ptr) { static void destruct(void* ptr) {
((MyTuple*)ptr)->~MyTuple(); ((MyTuple*)ptr)->~MyTuple();
} }
template <typename T> template <typename T, std::size_t Index>
static FieldPtr field_in_tuple() { static FieldPtr field_in_tuple() {
MemberData member;
constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG; constexpr uint32_t flag = FIELD_MEMBER_FLAG | FIELD_ATTRIBUTE_FLAG;
return { FName(""), &TypeInfo<T>::StaticClass, member, flag}; const MyTuple* tuple_ptr = nullptr;
const auto& element = std::get<Index>(*tuple_ptr);
const std::ptrdiff_t offset = reinterpret_cast<const char*>(&element) - reinterpret_cast<const char*>(tuple_ptr);
MemberData member;
member.offset = offset;
return { IndexNames[Index], &TypeInfo<T>::StaticClass, member, flag};
}
template <std::size_t... Is>
void BuildFields(std::index_sequence<Is...>) {
auto ptr = &Fields[0];
(..., (*ptr = field_in_tuple<Types, Is>(), ptr++));
}
UClass_Tuple():UClass(type_name<MyTuple>().View(), sizeof(MyTuple)) {
assert(sizeof...(Types) < IndexNames.size());
BuildFields(std::index_sequence_for<Types...>{});
vtable.Construct = &MyUClass::construct;
vtable.Destruct = &MyUClass::destruct;
vtable.GetFields = &MyUClass::GetFields;
} }
const sarray<const FieldPtr> GetFields(EFieldFind find, const Name& name) const { const sarray<const FieldPtr> GetFields(EFieldFind find, const Name& name) const {
return sarray<const FieldPtr>(&Fields[0], sizeof...(Types)); return sarray<const FieldPtr>(&Fields[0], sizeof...(Types));
@ -138,20 +154,51 @@ namespace refl {
auto cls = static_cast<const MyUClass*>(_cls); auto cls = static_cast<const MyUClass*>(_cls);
return cls->GetFields(find, name); return cls->GetFields(find, name);
} }
UClass_Tuple():UClass(type_name<MyTuple>().View(), sizeof(MyTuple)) { };
template<typename First,typename Second>
class UClass_Pair : public UClass {
using UClass::UClass;
using MyUClass = UClass_Tuple<First, Second>;
using MyPair = std::pair<First, Second>;
public:
std::array<FieldPtr, 2> Fields;
static bool construct(void* ptr, const UClass* cls, const sarray<Any>& ArgsList) {
new(ptr)MyPair();
return true;
}
static void destruct(void* ptr) {
((MyPair*)ptr)->~MyPair();
}
template<typename T, int Index>
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<const char*>(&first) - reinterpret_cast<const char*>(pair_ptr);
member.offset = offset;
}
else {
const auto& second = pair_ptr->second;
const std::ptrdiff_t offset = reinterpret_cast<const char*>(&second) - reinterpret_cast<const char*>(pair_ptr);
member.offset = offset;
}
return { IndexNames[Index], &TypeInfo<T>::StaticClass, member, flag };
}
UClass_Pair() :UClass(type_name<MyPair>().View(), sizeof(MyPair)) {
Fields[0] = field_in_pair<First, 0>();
Fields[1] = field_in_pair<Second, 1>();
vtable.Construct = &MyUClass::construct; vtable.Construct = &MyUClass::construct;
vtable.Destruct = &MyUClass::destruct; vtable.Destruct = &MyUClass::destruct;
vtable.GetFields = &MyUClass::GetFields; vtable.GetFields = &MyUClass::GetFields;
auto ptr = &Fields[0]; }
(..., (*ptr = field_in_tuple<Types>(), ptr++)); const sarray<const FieldPtr> GetFields(EFieldFind find, const Name& name) const {
Offset offset = 0; return sarray<const FieldPtr>(&Fields[0], 2);
constexpr int N = sizeof...(Types); }
assert(N < IndexNames.size()); static const sarray<const FieldPtr> GetFields(const UClass* _cls, EFieldFind find, const Name& name) {
for (int i = 0; i < N; i++) { auto cls = static_cast<const MyUClass*>(_cls);
Fields[i].name = IndexNames[i]; return cls->GetFields(find, name);
Fields[i].data.member.offset = offset;
offset += Fields[i].type->size;
}
} }
}; };
class UClass_Container : public UClass { class UClass_Container : public UClass {
@ -163,10 +210,10 @@ namespace refl {
}; };
//container //container
using size_impl = size_t(*)(const void*); using size_impl = size_t(*)(const void*);
using to_iterator_impl = iterator(*)(const void*); using to_iterator_impl = void(*)(iterator& ,const void*);
using insert_impl = void (*)(const void*, const void*); using insert_impl = void (*)(const void*, const void*);
//iterator //iterator
using iterator_impl = void* (*)(const void*); using iterator_impl = void (*)(iterator*);
public: public:
size_impl vsize; size_impl vsize;
to_iterator_impl vbegin; to_iterator_impl vbegin;
@ -189,8 +236,6 @@ namespace refl {
class UClass_Container_impl : public UClass_Container { class UClass_Container_impl : public UClass_Container {
using UClass_Container::UClass_Container; using UClass_Container::UClass_Container;
using MyUClass = UClass_Container_impl<T, value_type>; using MyUClass = UClass_Container_impl<T, value_type>;
using ToIteratorFunc = T::iterator(T::*)();
using IteratorFunc = T::iterator& (T::iterator::*)();
public: public:
static bool construct(void* ptr, const UClass* cls, const sarray<Any>& ArgsList) { static bool construct(void* ptr, const UClass* cls, const sarray<Any>& ArgsList) {
new(ptr)T(); new(ptr)T();
@ -199,13 +244,25 @@ namespace refl {
static void destruct(void* ptr) { static void destruct(void* ptr) {
((T*)ptr)->~T(); ((T*)ptr)->~T();
} }
static iterator begin(const void* ptr) { static void begin(iterator& pit,const void* ptr) {
auto it = ((T*)ptr)->begin(); auto it = ((T*)ptr)->begin();
return iterator{ *(void**)&it, &*it}; memcpy(&pit, &it, sizeof(it));
pit.val = &*it;
} }
static iterator end(const void* ptr) { static void end(iterator& pit, const void* ptr) {
auto it = ((T*)ptr)->end(); auto it = ((T*)ptr)->end();
return iterator{ *(void**)&it, &*it }; 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<T>().View(), sizeof(T)) { UClass_Container_impl() : UClass_Container(type_name<T>().View(), sizeof(T)) {
parent = &TypeInfo<value_type>::StaticClass; parent = &TypeInfo<value_type>::StaticClass;
@ -225,10 +282,8 @@ namespace refl {
vend = &MyUClass::end; vend = &MyUClass::end;
vinsert = &MyUClass::insert<T>; vinsert = &MyUClass::insert<T>;
IteratorFunc __it_add = &T::iterator::operator++; viterator_add = &MyUClass::add;
viterator_add = *(iterator_impl*)&__it_add; viterator_sub = &MyUClass::sub;
IteratorFunc __it_sub = &T::iterator::operator++;
viterator_sub = *(iterator_impl*)&__it_sub;
}; };
}; };
template<typename T, typename MyMeta> template<typename T, typename MyMeta>
@ -330,9 +385,9 @@ namespace refl {
using MyUClass = UClass_Tuple<Types...>; using MyUClass = UClass_Tuple<Types...>;
inline static MyUClass StaticClass = MyUClass(); inline static MyUClass StaticClass = MyUClass();
}; };
template<typename... Types> template<typename First, typename Second>
struct TypeInfoImpl<std::pair<Types...>> { struct TypeInfoImpl<std::pair<First, Second>> {
using MyUClass = UClass_Tuple<Types...>; using MyUClass = UClass_Pair<First, Second>;
inline static MyUClass StaticClass = MyUClass(); inline static MyUClass StaticClass = MyUClass();
}; };
template<is_container_v T> template<is_container_v T>

View File

@ -1,4 +1,5 @@
#ifdef RegisterAny #ifdef RegisterAny
RegisterAny(string);
RegisterAny(int); RegisterAny(int);
RegisterAny(unsigned int); RegisterAny(unsigned int);
RegisterAny(short); RegisterAny(short);

View File

@ -32,21 +32,6 @@ void testTuple() {
table.insert(std::make_pair(111,"hello")); table.insert(std::make_pair(111,"hello"));
table.insert(std::make_pair(222, "world")); table.insert(std::make_pair(222, "world"));
using T = std::map<int, string>; using T = std::map<int, string>;
using to_iterator_func = T::iterator(T::*)();
struct myiterator {
void* ptr;
};
using to_iterator_impl1 = myiterator*(*)(void *);
using to_iterator_impl2 = myiterator(*)(void*);
using to_iterator_impl3 = void*(*)(void*);
using to_iterator_impl4 = T::iterator(*)(T*);
auto it = table.begin();
auto t = &*it;
to_iterator_func func = &T::begin;
to_iterator_impl1 impl1 = *(to_iterator_impl1*) & func;
to_iterator_impl2 impl2 = *(to_iterator_impl2*)&func;
to_iterator_impl3 impl3 = *(to_iterator_impl3*)&func;
to_iterator_impl4 impl4 = *(to_iterator_impl4*)&func;
string rtable = YAML::Text_Serialize(table); string rtable = YAML::Text_Serialize(table);
std::cout << rtable << std::endl; std::cout << rtable << std::endl;
auto table2 = YAML::Text_Unserialize<std::map<int, string>>(rtable); auto table2 = YAML::Text_Unserialize<std::map<int, string>>(rtable);
@ -60,20 +45,8 @@ int main() {
constexpr bool m1 = refl::is_map_v<std::vector<int>>; constexpr bool m1 = refl::is_map_v<std::vector<int>>;
constexpr bool m2 = refl::is_sequence_v<std::map<int, float>>; constexpr bool m2 = refl::is_sequence_v<std::map<int, float>>;
auto cls = &TypeInfo<Guid>::StaticClass; auto cls = &TypeInfo<Guid>::StaticClass;
std::vector<int> vi; testGuid();
using T = std::vector<int>; testMeta();
using iterator = T::iterator;
struct myiterator {
void* ptr;
};
using to_iterator_impl_func = myiterator*(*)(const void*);
using to_iterator_func = void(T::*)(T::value_type&&);
to_iterator_func to_iterator = &T::push_back;
to_iterator_impl_func to_iterator_impl = * (to_iterator_impl_func*) &to_iterator;
iterator it = vi.begin();
void* pptr = it._Ptr;
//testGuid();
//testMeta();
testTuple(); testTuple();
return 0; return 0;
} }