Last active
August 11, 2025 08:31
-
-
Save r-lyeh/fc51881d47c5cdac23ca914c79c6d7ff to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// [src] https://www.scs.stanford.edu/~dm/blog/va-opt.html | |
// | |
// gcc enum.c | |
// clang enum.c | |
// cl enum.c /Zc:preprocessor | |
#define PARENS () | |
// Rescan macro tokens 256 times | |
#define EXPAND(arg) EXPAND1(EXPAND1(EXPAND1(EXPAND1(arg)))) | |
#define EXPAND1(arg) EXPAND2(EXPAND2(EXPAND2(EXPAND2(arg)))) | |
#define EXPAND2(arg) EXPAND3(EXPAND3(EXPAND3(EXPAND3(arg)))) | |
#define EXPAND3(arg) EXPAND4(EXPAND4(EXPAND4(EXPAND4(arg)))) | |
#define EXPAND4(arg) arg | |
#define FOR_EACH(macro, ...) \ | |
__VA_OPT__(EXPAND(FOR_EACH_HELPER(macro, __VA_ARGS__))) | |
#define FOR_EACH_HELPER(macro, a1, ...) \ | |
macro(a1) \ | |
__VA_OPT__(FOR_EACH_AGAIN PARENS (macro, __VA_ARGS__)) | |
#define FOR_EACH_AGAIN() FOR_EACH_HELPER | |
#define ENUM_CASE(name) case name: return #name; | |
#define MAKE_ENUM(type, typestr, ...) \ | |
typedef enum type { __VA_ARGS__ } type; \ | |
const char *typestr(type _e) { \ | |
switch (_e) { default: return ""; \ | |
FOR_EACH(ENUM_CASE, __VA_ARGS__) }} | |
MAKE_ENUM(MyType, MyTypeStr, ZERO, ONE, TWO, THREE); | |
#include <stdio.h> | |
void test(MyType e) { | |
printf("%s=%d\n", MyTypeStr(e), e); | |
} | |
int main() { | |
test(ZERO); | |
test(ONE); | |
test(TWO); | |
test(THREE); | |
} | |
/* | |
ZERO=0 | |
ONE=1 | |
TWO=2 | |
THREE=3 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment