fork download
  1. #include <stdio.h>
  2.  
  3. #define CAT_(a, ...) a ## __VA_ARGS__
  4. #define CAT(...) CAT_(__VA_ARGS__)
  5.  
  6. #define EAT(...)
  7. #define EXPAND(...) __VA_ARGS__
  8. #define IIF(c) CAT(IIF_, c)
  9. #define IIF_1(...) __VA_ARGS__ EAT
  10. #define IIF_0(...) EXPAND
  11.  
  12. #define COMPL(x) CAT(COMPL_, x)
  13. #define COMPL_1 0
  14. #define COMPL_0 1
  15.  
  16. #define CHECK_N(x, n, ...) n
  17. #define CHECK(...) CHECK_(__VA_ARGS__)
  18. #define CHECK_(...) CHECK_N(__VA_ARGS__, 0)
  19. #define PROBE(x) x, 1
  20.  
  21. #define IS_EMPTY(x) BOOL(CHECK(CAT(IS_EMPTY_, x)()))
  22. #define IS_EMPTY_() PROBE(~)
  23.  
  24. #define NOT(x) CHECK(CAT(NOT_, x))
  25. #define NOT_0 PROBE(~)
  26. #define BOOL(x) COMPL(NOT(x))
  27.  
  28. #define IF(c) IIF(BOOL(c))
  29. #define UNLESS(c) IF(c)()
  30.  
  31. #define EMPTY()
  32. #define DEFER(id) id EMPTY()
  33. #define OBSTRUCT(id) id DEFER(EMPTY)()
  34.  
  35. #define EVAL(...) EVAL1(EVAL1(EVAL1(EVAL1(__VA_ARGS__))))
  36. #define EVAL1(...) EVAL2(EVAL2(EVAL2(EVAL2(__VA_ARGS__))))
  37. #define EVAL2(...) EVAL3(EVAL3(EVAL3(EVAL3(__VA_ARGS__))))
  38. #define EVAL3(...) EVAL4(EVAL4(EVAL4(EVAL4(__VA_ARGS__))))
  39. #define EVAL4(...) EVAL5(EVAL5(EVAL5(EVAL5(__VA_ARGS__))))
  40. #define EVAL5(...) __VA_ARGS__
  41.  
  42. #define FOREACH(macro, x, ...) \
  43.   UNLESS(IS_EMPTY(x))( \
  44.   macro(x) \
  45.   OBSTRUCT(FOREACH_INDIRECT)()(macro, __VA_ARGS__) \
  46.   )
  47.  
  48. #define FOREACH_INDIRECT(...) FOREACH
  49.  
  50. #define QUOTE(...) QUOTE_(__VA_ARGS__)
  51. #define QUOTE_(...) #__VA_ARGS__
  52.  
  53. #define ENUM_ARR_ELEM(x) , QUOTE(x)
  54. #define ENUM(tag, first, ...) \
  55.   enum tag {first, __VA_ARGS__}; \
  56.   char *CAT(tag, _names)[] = {QUOTE(first)EVAL(FOREACH(ENUM_ARR_ELEM, __VA_ARGS__))}; \
  57.   static char *CAT(tag, _to_str) (int x) \
  58.   { \
  59.   return x > sizeof(CAT(tag, _names)) / sizeof(char*) ? QUOTE(!!!UNKNOWN tag!!!) : CAT(tag, _names)[x]; \
  60.   }
  61.  
  62. ENUM(crap,
  63. shit,
  64. fuck,
  65. dick,
  66. ass,
  67. turd,
  68. fart
  69. )
  70.  
  71. int main()
  72. {
  73. puts(crap_to_str(shit));
  74. puts(crap_to_str(666));
  75. return 0;
  76. }
Success #stdin #stdout 0s 9424KB
stdin
Standard input is empty
stdout
shit
!!!UNKNOWN crap!!!