Search code examples
c++boostboost-preprocessor

Remove spaces from symbol


I'm using Boost preprocessor sequences to generate enums, 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?


Solution

  • 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)
    };