template constexpr Enum get_enum_max() { //static_assert(false, "missing get_enum_max implementation"); return ~0; } template const char *get_enum_member_name(Enum val); // { // return nullptr; // } #define DECL_ENUM_CLASS_ENUM_MEMBER(enum_name, member_name) member_name, #define DECL_ENUM_CLASS_MAX_ENUM_MEMBER(enum_name, member_name) case enum_name::member_name: val = enum_name::member_name; #define DECL_ENUM_CLASS(enum_decl_macro, enum_name)\ enum class enum_name \ {\ enum_decl_macro(DECL_ENUM_CLASS_ENUM_MEMBER, enum_name)\ };\ template<>\ constexpr enum_name get_enum_max()\ {\ enum_name val{};\ switch (val)\ {\ enum_decl_macro(DECL_ENUM_CLASS_MAX_ENUM_MEMBER, enum_name)\ }\ return val;\ }\ \ template<>\ const char *get_enum_member_name(enum_name val) #define DEF_ENUM_CLASS_STRING(enum_name, member_name) case enum_name::member_name: return #member_name; #define DEF_ENUM_CLASS(enum_decl_macro, enum_name)\ template<>\ const char *get_enum_member_name(enum_name val)\ {\ switch (val) {\ enum_decl_macro(DECL_ENUM_CLASS_MAX_ENUM_MEMBER, enum_name)\ }\ return "UNKNOWN";\ }\ template<>\ const char *get_enum_member_name(enum_name val) #define ENUMCLASS_E(x, enum_name) \ x(enum_name, A)\ x(enum_name, B)\ x(enum_name, C)\ x(enum_name, D) DECL_ENUM_CLASS(ENUMCLASS_E, E); DEF_ENUM_CLASS(ENUMCLASS_E, E); int main() { constexpr auto i = int(get_enum_max()); return i; }