2

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?

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56
Ryan
  • 219
  • 2
  • 11

1 Answers1

3

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
Phil1970
  • 2,605
  • 2
  • 14
  • 15
  • It only specifies the backing store for the enum, it doesn't change its type. `int` is the default, so a bit enthusiastic. A "last" enum member is very common, helps to implement value checking. – Hans Passant Sep 05 '19 at 23:47
  • By the way, ‘ e__str__[i] ‘ looks to be a none-standard compiler-specific extension. Out of curiosity, what is your tool-chain? – Red.Wave Sep 06 '19 at 11:24
  • `e__str__` is a multi dimensional array as `int a[][2] = {{1,2},{3,4},{5,6}};` would be. Nothing compiler specific. – Phil1970 Sep 06 '19 at 12:10