It looks for what you need. Sometimes it is necessary to generate enum 's or functions from such constants. Then boost.preprocessor will help. An example from a recent project:
#define SB_PROP_TYPES \ /* type name, type, is pointer, is native, array length */ \ /* note: all non-pointer types should be listed */ \ /* in `sb_config_entry`. */ \ /* here, `$` is a valid pointer to `sb_config_entry`, */ \ /* `$$` is a `v_ptr` casted into a proper type. */ \ ((SB_STRING, char, 1, 1, (strlen($$) + 1) )) \ ((SB_LITERAL, char, 1, 1, (strlen($$) + 1) )) \ ((SB_INT, int, 0, 1, )) \ ((SB_BOOL, bool, 0, 1, )) \ ((SB_CHAR_PAIR_ARR, sb_prop_char_pair_array, 1, 0, (1) )) \ ((__SB_UNKNOWN, int, 0, 1, )) // ... enum sb_prop_types { #define __SB_OP(r, data, elem) (BOOST_PP_TUPLE_ELEM(5, 0, elem)) BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(__SB_OP, , SB_PROP_TYPES)) #undef __SB_OP };
Such a thing will unfold in
enum sb_prop_types { SB_STRING, SB_LITERAL, SB_INT, SB_BOOL, SB_CHAR_PAIR_ARR, __SB_UNKNOWN };
Further, there is such an example - it plays the role of your switch (working with strings, so many ifas are used, but generally you can switch ):
static inline enum sb_prop_types prop_to_type(const char *__name) { #define __SB_OP(r, data, elem) \ if (strcasecmp(BOOST_PP_TUPLE_ELEM(3, 0, elem), __name) == 0) \ return BOOST_PP_TUPLE_ELEM(3, 2, elem); BOOST_PP_SEQ_FOR_EACH(__SB_OP, _, SB_PROPS) #undef __SB_OP return __SB_UNKNOWN; }
Accordingly, it will unfold in a large number of Iphah.