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).
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...
}