Skip to content

Instantly share code, notes, and snippets.

@irondoge
Last active March 8, 2018 15:59
Show Gist options
  • Save irondoge/4ea63936db67233578f9564b42563d01 to your computer and use it in GitHub Desktop.
Save irondoge/4ea63936db67233578f9564b42563d01 to your computer and use it in GitHub Desktop.
#pragma once
#ifndef _EXPAND_MACRO_H_
# define _EXPAND_MACRO_H_
# define __DONOTHING(...)
# define __EXPAND(...) __VA_ARGS__
# define __COMMA(A) A,
# define __CAT(A, B) A ## B
# define CAT(A, B) __CAT(A, B)
# define __SELECT( \
_0, _1, _2, _3, _4, _5, _6, _7, \
_8, _9, _10, _11, _12, _13, _14, _15, \
_16, _17, _18, _19, _20, _21, _22, _23, \
_24, _25, _26, _27, _28, _29, _30, _31, _32, \
N, ...) N
/* __COUNT() with no arguments only works with GNU extensions */
# define __COUNT(...) __SELECT(, ## __VA_ARGS__, \
32, 31, 30, 29, 28, 27, 26, 25, 24, 23, \
22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \
12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
# define __ITER_IF_0 __ITER_IF_1
# define __ITER_IF_1(MACRO1, MACRO2, ARG2, ARG1, ARG3) MACRO1(ARG1) MACRO2(ARG2) MACRO1(ARG3)
# define __ITER_IF_2(MACRO1, MACRO2, ARG2, ARG1, ARG3, ARG4) MACRO1(ARG1) MACRO2(ARG2) MACRO1(ARG3) MACRO2(ARG2) MACRO1(ARG4)
# define __ITER_IF(A) CAT(__ITER_IF_, A)
# define __ITER_2(MACRO1, MACRO2, ARG2, ARG1, ...) __ITER_IF(__COUNT(__VA_ARGS__))(MACRO1, MACRO2, ARG2, ARG1, __VA_ARGS__)
# define __ITER_3(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_2(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_4(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_3(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_5(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_4(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_6(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_5(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_7(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_6(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_8(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_7(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_9(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_8(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_10(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_9(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_11(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_10(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_12(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_11(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_13(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_12(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_14(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_13(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_15(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_14(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_16(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_15(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_17(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_16(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_18(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_17(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_19(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_18(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_20(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_19(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_21(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_20(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_22(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_21(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_23(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_22(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_24(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_23(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_25(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_24(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_26(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_25(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_27(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_26(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_28(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_27(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_29(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_28(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_30(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_29(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_31(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_30(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define __ITER_32(MACRO1, MACRO2, ARG2, ARG1, ...) MACRO1(ARG1) MACRO2(ARG2) __ITER_31(MACRO1, MACRO2, ARG2, __VA_ARGS__)
# define MACRO_EXPAND(MACRO, SEP, ...) CAT(__ITER_, __COUNT(__VA_ARGS__))(MACRO, __EXPAND, SEP, __VA_ARGS__)
# define COMMA_MACRO_EXPAND(MACRO, A, ...) CAT(__ITER_, __COUNT(__VA_ARGS__))(MACRO, __COMMA, /**/, A, __VA_ARGS__)
# define ITEM_EXPAND(SEP, ...) MACRO_EXPAND(__EXPAND, SEP, __VA_ARGS__)
# define REPEAT(N, ITEM) CAT(__ITER_, N)(__DONOTHING, __EXPAND, ITEM,) ITEM
# define COMMA_REPEAT(N, ITEM) CAT(__ITER_, N)(__DONOTHING, __COMMA, ITEM,) ITEM
#endif /* !_EXPAND_MACRO_H_ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment