2

I've been using @WilliamSwanson MAP() macro suggestion which "applies" another macro, or function, to all other macro arguments, e.g.

MAP(foo, x, y, z)

expands to

foo(x) foo(y) foo(z) 

Here's the code for what I have now:

#define EVAL0(...) __VA_ARGS__
#define EVAL1(...) EVAL0 (EVAL0 (EVAL0 (__VA_ARGS__)))
#define EVAL2(...) EVAL1 (EVAL1 (EVAL1 (__VA_ARGS__)))
#define EVAL3(...) EVAL2 (EVAL2 (EVAL2 (__VA_ARGS__)))
#define EVAL4(...) EVAL3 (EVAL3 (EVAL3 (__VA_ARGS__)))
#define EVAL(...)  EVAL4 (EVAL4 (EVAL4 (__VA_ARGS__)))

#define MAP_END(...)
#define MAP_OUT

#define MAP_GET_END() 0, MAP_END
#define MAP_NEXT0(test, next, ...) next MAP_OUT
#define MAP_NEXT1(test, next) MAP_NEXT0 (test, next, 0)
#define MAP_NEXT(test, next)  MAP_NEXT1 (MAP_GET_END test, next)

#define MAP0(f, x, peek, ...) f(x) MAP_NEXT (peek, MAP1) (f, peek, __VA_ARGS__)
#define MAP1(f, x, peek, ...) f(x) MAP_NEXT (peek, MAP0) (f, peek, __VA_ARGS__)
#define MAP(f, ...) EVAL (MAP1 (f, __VA_ARGS__, (), 0))

... and it works well for me. However, I want to add some separator macro between every such application, i.e. get

foo(x) bar foo(y) bar foo(z) 

in the example above. How would I alter the macro to do what I want? I'm guessing it must be some replacement of the end test with a one-more-till-the-end test, but I can't quite get it right. If you have your own implementation of this functionality, I suppose that would work as well (although I kind of like this one, it's relatively short and neat).

Note: This is essentially equivalent to asking how to get MAP() to do something arbitrarily different with last element as opposed to all the rest.

Community
  • 1
  • 1
einpoklum
  • 118,144
  • 57
  • 340
  • 684

0 Answers0