Search code examples
c++enum-class

meaning of code snippet involving enum class and macro expansion


I encounter the following code in C++. I am new to the language and am not familiar with the syntax.

I understand the basic of macro expansion and enum class. I learn that the macro etokenize with argument x1,x2,...,xn will be replaced by #x1,#x2,...#xn. The function s_tolower change every charater in a std::string to lower case.

#define DECL_ENUM_FUNCS(e)        inline const char* enum2str(e e1){ return e##__str__[static_cast<int>(e1)]; } \
                                inline bool str2enum(const std::string& s,e& e1){for(int i=0;i<static_cast<int>(e::End);i++){ if( s==e##__str__[i] ){e1=static_cast<e>(i);return true;} } e1=e::End; return false; } \
                                inline bool str2enumI(const std::string& s,e& e1){for(int i=0;i<static_cast<int>(e::End);i++){ if( s_tolower(s)==s_tolower(e##__str__[i]) ){e1=static_cast<e>(i);return true;} } e1=e::End; return false; } \
                                inline std::ostream& operator<<(std::ostream& o, e const & in_) { o << e##__str__[static_cast<int>(in_)]; return o; }

#define DECL_ENUM(e,x1,...) enum class e : int { x1=0, __VA_ARGS__, End }; const char e##__str__[][256] = {#x1, etokenize(__VA_ARGS__), "Invalid"}; DECL_ENUM_FUNCS(e)

My question is on the general syntax, not the detail of functions involved. For instance, Why are there 4 inline functions in the replacement list? And what is the last line doing? I apologize if my question is poorly written since I am still a beginner.

I am guessing that

DECL_ENUM(type, a,b,c) 

will be the same as

enum class type { a, b, c};

Am I correct?


Solution

  • No, for the enum class part, you miss 2 things:

    • The type is set to int.
    • And End value is added to the end.

    Then it define utility functions that:

    • Convert an enum value to its string representation: type::a --> 'a'
    • Find the enum value that correspond to a string: 'a' --> type::a
    • Idem by ignoring case: 'A' --> type::a
    • Print the text representation to a std::ostream: std::cout << type::a