In order to make my code shorter and easier to change I want to replace something like
enum{ E_AAA, E_BBB, E_CCC };
static const char *strings{\"AAA\", \"BBB
Here is my solution:
#define FRUITS(fruit) \
fruit(Apple) \
fruit(Orange) \
fruit(Banana)
#define CREATE_ENUM(name) \
F_##name,
#define CREATE_STRINGS(name) \
#name,
The trick is that 'fruit' is an argument of the macro 'FRUITS' and will be replaced by what ever you pass to. For example:
FRUITS(CREATE_ENUM)
will expand to this:
F_Apple, F_Orange, F_Banana,
Lets create the enum and the string array:
enum fruit {
FRUITS(CREATE_ENUM)
};
const char* fruit_names[] = {
FRUITS(CREATE_STRINGS)
};
Here a solution I learned a few days ago. The simplified version that attends your question is:
#define ENUM_MACRO(name, v1, v2, v3, v4, v5, v6, v7)\
enum name { v1, v2, v3, v4, v5, v6, v7};\
const char *name##Strings[] = { #v1, #v2, #v3, #v4, #v5, #v6, #v7};
ENUM_MACRO(Week, Sun, Mon, Tue, Wed, Thu, Fri, Sat);
But you can have an improved version, with a function call, like this:
#define ENUM_MACRO(name, v1, v2, v3, v4, v5, v6, v7)\
enum name { v1, v2, v3, v4, v5, v6, v7};\
const char *name##Strings[] = { #v1, #v2, #v3, #v4, #v5, #v6, #v7};\
const char *name##ToString(value) { return name##Strings[value]; }
ENUM_MACRO(Week, Sun, Mon, Tue, Wed, Thu, Fri, Sat);
This will grow to be:
enum Week { Sun, Mon, Tue, Wed, Thu, Fri, Sat};
const char *WeekStrings[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
const char *WeekToString(value) { return WeekStrings[value]; };
You can even use an offset for the first element, like this one:
#define ENUM_MACRO(name, offset, v1, v2, v3, v4, v5, v6, v7)\
enum name { v1 = offset, v2, v3, v4, v5, v6, v7};\
const char *name##Strings[] = { #v1, #v2, #v3, #v4, #v5, #v6, #v7};\
const char *name##ToString(value) { return name##Strings[value - offset ]; }
ENUM_MACRO(Week, 1, Sun, Mon, Tue, Wed, Thu, Fri, Sat);
I hope this helps.
Take care, Beco
Reference:
Print the month question, by Kush, answer by Danny Varod