1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| #pragma once
#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.find("::"); 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); }
}
|