#include <iostream>
#include <cstring>
#include <string>
using namespace std;
//预置
constexpr static inline unsigned const_hash(char const* input)
{
return *input ? static_cast<unsigned int>(*input) + 33 * const_hash(input + 1) : 5381;
}
template<int BUSI=0,auto P>
constexpr inline bool field_ignore() { return false;}
template<auto P>
constexpr inline const char* field_name = nullptr;
template<auto P,auto...Ps>
struct field_do1
{
template <int BUSI=0,class T,class L>
static constexpr inline void run(T& obj,const char* fname,L&& lam)
{
if constexpr(!field_ignore<BUSI,P>())
if (const_hash(field_name<P>)== const_hash(fname))
lam(obj.*P);
if constexpr(sizeof...(Ps))
field_do1<Ps...>::template run<BUSI>(obj,fname,std::move(lam));
}
};
template<auto...Ps>
struct field_do0
{
template <int BUSI=0,class T,class L>
static constexpr inline void run(T& obj,const char* fname, L&& lam)
{
field_do1<Ps...>::template run<BUSI>(obj,fname,std::move(lam));
}
};
template<auto P,auto...Ps>
struct for_each1
{
template <int BUSI=0,class T,class L>
static constexpr inline void run(T& obj,L&& lam)
{
if constexpr(!field_ignore<BUSI,P>())
lam(field_name<P>,obj.*P);
if constexpr(sizeof...(Ps) )
for_each1<Ps...>::template run<BUSI>(obj,std::move(lam));
}
};
template<auto...Ps>
struct for_each0
{
template <int BUSI=0,class T,class L>
constexpr static inline void run(T& obj, L&& lam)
{
for_each1<Ps...>::template run<BUSI>(obj,std::move(lam));
}
};
template<auto ... Ps>
struct fields_iterator
{
template<int BUSI=0,class T,class L>
constexpr static inline void field_do(T& obj ,const char* fname,L&& lam)
{
field_do0<Ps...>::template run<BUSI>(obj,fname,std::move(lam));
}
template<int BUSI=0,class T,class L>
constexpr static inline void foreach_do(T& obj ,L&& lam)
{
for_each0<Ps...>::template run<BUSI>(obj,std::move(lam));
}
};
struct st {
int f1 = 1;
float f2 = 2.33;
double f3 = 33.33;
};
//生成
template<> constexpr inline const char* field_name<&st::f1> = "f1";
template<> constexpr inline const char* field_name<&st::f2> = "f2";
template<> constexpr inline const char* field_name<&st::f3> = "f3";
using st_fields_iterator = fields_iterator<&st::f1,&st::f2,&st::f3>;
template<> constexpr inline bool field_ignore<1,&st::f1>() { return true;}
//调用生成
int main() {
st obj;
std::string strf = "f";
st_fields_iterator::field_do<1>(obj,(strf+"1").c_str(),[](auto&& value){
value = 11113;
});
st_fields_iterator::field_do<1>(obj,(strf+"2").c_str(),[](auto&& value){
value = 4.1456f ;
});
st_fields_iterator::field_do<1>(obj,(strf+"3").c_str(),[](auto&& value){
value = 5.1456f ;
});
st_fields_iterator::foreach_do<1>(obj,[](const char* fname,auto&&value){
std::cout << fname << " : " << value << std::endl;
});
}
写了一个模板可变参数递归展开的反射,应该有性能问题,先记录下来放着
发布时间 2023-07-27 10:42:58作者: 马肯尼煤牙巴骨