c++if-statementx-macros

Macro to generate chained else ifs


Using an X Macro to keep a couple of different things in sync using an out of module provided list.

Part of this involves creating an else/if chain to validate a string.

I am currently doing this:

if (0) {
   // this will never run, and be compiled out
}
#define X(name) else if (some_thing == #name) { // do thing based on name... }
   MY_LIST
#undef X
else {
   // Report unrecognized string...
}

but it feels a little bit ugly to me (I am not a big fan of the un-executable if(0) {}).

I have thought about doing this using a switch statement...

constexpr hash(const char* const str, size_t len, uint64_t init_value)
   // implementation left to imagination of the reader)...

//...

switch(hash(some_thing, len(some_thing))) {
#define X(name) case hash(#name, const_len(#name)): { break; }
   MY_LIST
#undef X
   default: 
   {
      good_thing = false;
      break;
   }
}
// Now that it has been validated as a good string... save it etc.

But I worry about collisions (as unlikely as a collision is).

Is there a way to do the if/else chain without starting with an if(0)?

I am stuck with std::14 if it helps (I know it doesn't).


Solution

  • You can set a flag in each string match - then you don't need else:

    bool found = false;
    #define X(name) if (some_thing == #name) { found = true; /* do thing based on name here ...*/ }
       MY_LIST
    #undef X
    if (!found) {
       // Report unrecognized string...
    }
    

    Or, if it is important to avoid comparisons after a string is matched, you can do it like this (but it is harder to understand in my opinion):

    #define X(name) if (some_thing == #name) { /* do thing based on name... */ } else 
       MY_LIST
    #undef X
    {
       // Report unrecognized string...
    }