写了一个模板可变参数递归展开的反射,应该有性能问题,先记录下来放着

#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;
    });

}

posted @   马肯尼煤牙巴骨  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!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 排序 和分组
点击右上角即可分享
微信分享提示