#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;
});
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2019-07-27 [算法]二叉查找
2019-07-27 [Wpf]在C#中添加 collectionViewSource
2019-07-27 [wpf] collectionViewsource 排序 和分组