Is there a simple way to convert C++ enum to string?

后端 未结 30 2252
我在风中等你
我在风中等你 2020-11-22 10:37

Suppose we have some named enums:

enum MyEnum {
      FOO,
      BAR = 0x50
};

What I googled for is a script (any language) that scans all

30条回答
  •  情歌与酒
    2020-11-22 11:03

    Here is an attempt to get << and >> stream operators on enum automatically with an one line macro command only...

    Definitions:

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define MAKE_STRING(str, ...) #str, MAKE_STRING1_(__VA_ARGS__)
    #define MAKE_STRING1_(str, ...) #str, MAKE_STRING2_(__VA_ARGS__)
    #define MAKE_STRING2_(str, ...) #str, MAKE_STRING3_(__VA_ARGS__)
    #define MAKE_STRING3_(str, ...) #str, MAKE_STRING4_(__VA_ARGS__)
    #define MAKE_STRING4_(str, ...) #str, MAKE_STRING5_(__VA_ARGS__)
    #define MAKE_STRING5_(str, ...) #str, MAKE_STRING6_(__VA_ARGS__)
    #define MAKE_STRING6_(str, ...) #str, MAKE_STRING7_(__VA_ARGS__)
    #define MAKE_STRING7_(str, ...) #str, MAKE_STRING8_(__VA_ARGS__)
    #define MAKE_STRING8_(str, ...) #str, MAKE_STRING9_(__VA_ARGS__)
    #define MAKE_STRING9_(str, ...) #str, MAKE_STRING10_(__VA_ARGS__)
    #define MAKE_STRING10_(str) #str
    
    #define MAKE_ENUM(name, ...) MAKE_ENUM_(, name, __VA_ARGS__)
    #define MAKE_CLASS_ENUM(name, ...) MAKE_ENUM_(friend, name, __VA_ARGS__)
    
    #define MAKE_ENUM_(attribute, name, ...) name { __VA_ARGS__ }; \
        attribute std::istream& operator>>(std::istream& is, name& e) { \
            const char* name##Str[] = { MAKE_STRING(__VA_ARGS__) }; \
            std::string str; \
            std::istream& r = is >> str; \
            const size_t len = sizeof(name##Str)/sizeof(name##Str[0]); \
            const std::vector enumStr(name##Str, name##Str + len); \
            const std::vector::const_iterator it = std::find(enumStr.begin(), enumStr.end(), str); \
            if (it != enumStr.end())\
                e = name(it - enumStr.begin()); \
            else \
                throw std::runtime_error("Value \"" + str + "\" is not part of enum "#name); \
            return r; \
        }; \
        attribute std::ostream& operator<<(std::ostream& os, const name& e) { \
            const char* name##Str[] = { MAKE_STRING(__VA_ARGS__) }; \
            return (os << name##Str[e]); \
        }
    

    Usage:

    // Declare global enum
    enum MAKE_ENUM(Test3, Item13, Item23, Item33, Itdsdgem43);
    
    class Essai {
    public:
        // Declare enum inside class
        enum MAKE_CLASS_ENUM(Test, Item1, Item2, Item3, Itdsdgem4);
    
    };
    
    int main() {
        std::cout << Essai::Item1 << std::endl;
    
        Essai::Test ffffd = Essai::Item1;
        std::cout << ffffd << std::endl;
    
        std::istringstream strm("Item2");
        strm >> ffffd;
    
        std::cout << (int) ffffd << std::endl;
        std::cout << ffffd << std::endl;
    }
    

    Not sure about the limitations of this scheme though... comments are welcome!

提交回复
热议问题