Skip to content

Instantly share code, notes, and snippets.

@XDracam
Last active November 4, 2019 10:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save XDracam/c382c5d68ffcefee17c614d1ae7286ff to your computer and use it in GitHub Desktop.
Save XDracam/c382c5d68ffcefee17c614d1ae7286ff to your computer and use it in GitHub Desktop.
C++ zero-cost varargs foreach - reduce code duplication while keeping the code expressive
// Written by Cameron Reuschel (XDracam), 2019
//
// Does not work on MSVC, since they use a different preprocessor algorithm than clang and gcc.
// Use like this:
// foreach(const &, myFoo1, myFoo2, myFoo3, _.foo());
// foreach(&&, a, b, c, sum += _);
#define _GET_FOR_EACH_MACRO(_0, _1, _2, _3, _4, _5, _6, NAME, ...) \
NAME
#define _FOR_EACH1(refMod, _1, expr) \
{ auto refMod _ = _1; (expr); };
#define _FOR_EACH2(refMod, _1, _2, expr) \
{ auto refMod _ = _1; (expr); }; \
_FOR_EACH1(refMod, _2, expr)
#define _FOR_EACH3(refMod, _1, _2, _3, expr) \
{ auto refMod _ = _1; (expr); }; \
_FOR_EACH2(refMod, _2, _3, expr)
#define _FOR_EACH4(refMod, _1, _2, _3, _4, expr) \
{ auto refMod _ = _1; (expr); }; \
_FOR_EACH3(refMod, _2, _3, _4, expr)
#define _FOR_EACH5(refMod, _1, _2, _3, _4, _5, expr) \
{ auto refMod _ = _1; (expr); }; \
_FOR_EACH4(refMod, _2, _3, _4, _5, expr)
#define foreach(...) _GET_FOR_EACH_MACRO(__VA_ARGS__, _FOR_EACH5, _FOR_EACH4, _FOR_EACH3, _FOR_EACH2, _FOR_EACH1)(__VA_ARGS__)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment