Skip to content

Commit

Permalink
realsupportcpp98
Browse files Browse the repository at this point in the history
  • Loading branch information
archibate committed Jul 31, 2022
1 parent 35b0dea commit 9fbe58c
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 22 deletions.
2 changes: 1 addition & 1 deletion specmacro/a.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "scienum.h"

enum Color {
RED = 1, GREEN = 2, BLUE = 3, YELLOW = 4,
RED, GREEN, BLUE, YELLOW,
};

int main() {
Expand Down
60 changes: 39 additions & 21 deletions specmacro/scienum.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,56 +21,74 @@ struct my_enable_if {

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

template <int Beg, int End, class F, typename my_enable_if<Beg == End>::type = 0>
void static_for(F const &func) {
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 = 0>
void static_for(F const &func) {
struct int_constant {
enum { value = Beg };
};
func(int_constant());
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 <int Beg = 0, int End = 256, class T>
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>([&] (auto i) {
if (n == (T)i.value) s = details::get_enum_name_static<T, (T)i.value>();
});
details::static_for<Beg, End + 1>(get_enum_name_functor<T>(n, s));
if (s.empty())
return std::to_string((int)n);
return "";
#if defined(_MSC_VER)
auto pos = s.find(',');
size_t pos = s.find(',');
pos += 1;
auto pos2 = s.find('>', pos);
size_t pos2 = s.find('>', pos);
#else
auto pos = s.find("N = ");
size_t pos = s.find("N = ");
pos += 4;
auto pos2 = s.find_first_of(";]", pos);
size_t pos2 = s.find_first_of(";]", pos);
#endif
s = s.substr(pos, pos2 - pos);
auto pos3 = s.find("::");
size_t pos3 = s.find("::");
if (pos3 != s.npos)
s = s.substr(pos3 + 2);
return s;
}

template <class T, int Beg = 0, int End = 256>
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 = Beg; i < End; i++) {
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);
}

}

0 comments on commit 9fbe58c

Please sign in to comment.