C++轻量级枚举反射

#pragma once
#include <iostream>
#include <string>

namespace scienum {

    namespace details {

        template <class T, T N>
        const char* get_enum_name_static() {
#if defined(_MSC_VER)
            return __FUNCSIG__;
#else
            return __PRETTY_FUNCTION__;
#endif
        }

        template <bool Cond>
        struct my_enable_if {
        };

        template <>
        struct my_enable_if<true> {
            typedef void type;
        };

        template <int Beg, int End, class F>
        typename my_enable_if<Beg == End>::type static_for(F const& func) {
        }

        template <int Beg, int End, class F>
        typename my_enable_if<Beg != End>::type static_for(F const& func) {
            func.template call<Beg>();
            static_for<Beg + 1, End>(func);
        }

        template <class T>
        struct get_enum_name_functor {
            int n;
            std::string& s;

            get_enum_name_functor(int n, std::string& s) : n(n), s(s) {}

            template <int I>
            void call() const {
                if (n == I) s = details::get_enum_name_static<T, (T)I>();
            }
        };

    }

    template <class T, T Beg, T End>
    std::string get_enum_name(T n) {
        std::string s;
        details::static_for<Beg, End + 1>(details::get_enum_name_functor<T>(n, s));
        if (s.empty())
            return "";
#if defined(_MSC_VER)
        size_t pos = s.find(',');
        pos += 1;
        size_t pos2 = s.find('>', pos);
#else
        size_t pos = s.find("N = ");
        pos += 4;
        size_t pos2 = s.find_first_of(";]", pos);
#endif
        s = s.substr(pos, pos2 - pos);
        size_t pos3 = s.rfind("::");
        if (pos3 != s.npos)
            s = s.substr(pos3 + 2);
        return s;
    }

    template <class T>
    std::string get_enum_name(T n) {
        return get_enum_name<T, (T)0, (T)256>(n);
    }

    template <class T, T Beg, T End>
    T enum_from_name(std::string const& s) {
        for (int i = (int)Beg; i < (int)End; i++) {
            if (s == get_enum_name((T)i)) {
                return (T)i;
            }
        }
        throw;
    }

    template <class T>
    T enum_from_name(std::string const& s) {
        return enum_from_name<T, (T)0, (T)256>(s);
    }

}

enum Color {
    RED, GREEN, BLUE, YELLOW,
};

int test() {
    std::cout << scienum::get_enum_name(YELLOW) << std::endl;
    std::cout << scienum::enum_from_name<Color>("YELLOW") << std::endl;
    return 0;
}

输出

YELLOW
3


创作不易,小小的支持一下吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码力码力我爱你

创作不易,小小的支持一下吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值