Imagine I have an X Macro for a list of items defined something like this:
#define X_MACRO(FN) \
  FN(foo) \
  FN(bar) \
  FN(zip)
This works great and I can call it to generate the same code templatized for each element, like:
#define xstr(s) str(s)
#define str(s) #s
#define PRINT_X(E) void print_ ## E () { std::cout << str(E); }; 
X_MACRO(PRINT_X)
This generates functions like void print_foo() { std::cout << "foo"; }; for each of the X_MACRO elements. So far, so good.
Now, however, I want the list of X Macro elements to be conditional on a pre-processor macro. For example the zip element should only be included in the X Macro if USE_ZIP is defined. Of course, I can't put an #ifdef inside the X Macro, like:
#define X_MACRO(FN) \
  FN(foo) \
  FN(bar) \
#ifdef USE_ZIP
  FN(zip)
#endif
I could instead write the list twice, once with zip and once without, based on the USE_ZIP like so:
#ifdef USE_ZIP
#define X_MACRO(FN) \
  FN(foo) \
  FN(bar) \
  FN(zip)
#else
#define X_MACRO(FN) \
  FN(foo) \
  FN(bar)
#endif
... but this violates DRY and more importantly it rapidly spirals out of control if you need to conditionally include other elements, which would require a list for each possible combination of USE_* macros.
How can I do this in a reasonable way?
 
     
     
    