I'm using Boost preprocessor sequences to generate enum
s, so for example I have a definition like
#define DESERTS (Cheesecake)(Apple Pie)(Merengue)
Now what I want to do is to generate both a sensible enum class
as well as stream output operations. The latter are OK, but the former are not because I do not know how to change, say (Apple Pie)
to an enum member that does not have the space, i.e., ApplePie
. Is this possible to do with Boost preprocessor magic?
Not with exactly this input, but there are workarounds. The most sensible I can think of is to change the input data so that the words of a multi-word identifier can be handled separately:
#define DESSERTS ((Cheesecake))((Apple)(Pie))((Merengue))
Since the identifier parts now come as parts of a sequence, you can generate the enum class and associated names with BOOST_PP_SEQ_FOLD_LEFT
this way:
#define DUMP_NORMAL(d, state, x) state x
#define DUMP_CONCAT(d, state, x) BOOST_PP_CAT(state, x)
#define MAKE_STRING(r, data, seq) BOOST_PP_STRINGIZE(BOOST_PP_SEQ_FOLD_LEFT(DUMP_NORMAL, , seq)),
#define MAKE_IDENTIFIER(r, data, seq) BOOST_PP_SEQ_FOLD_LEFT(DUMP_CONCAT, , seq),
enum class Desserts {
BOOST_PP_SEQ_FOR_EACH(MAKE_IDENTIFIER, _, DESSERTS)
};
char const *const DessertNames[] = {
BOOST_PP_SEQ_FOR_EACH(MAKE_STRING, _, DESSERTS)
};