fork download
  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <stdint.h>
  5.  
  6. typedef struct {
  7. uint32_t x, y;
  8. } struct_t;
  9.  
  10. inline char * struct_to_string(char * str, struct_t s) {
  11. return str + sprintf(str, "{x: %u, y: %u}", s.x, s.y);
  12. }
  13.  
  14. inline char * int_to_string(char * str, int i) {
  15. return str + sprintf(str, "%i", i);
  16. }
  17.  
  18. inline char * string_to_string(char * str, char * s) {
  19. uint64_t len = strlen(s);
  20. return memcpy(str, s, len) + len;
  21. }
  22.  
  23. #define to(type, x) ({__auto_type ret = x; *(type *)((void *) &ret);})
  24.  
  25. #define to_string(str, x) _Generic((x),\
  26.   int : int_to_string(str, to(int, x)),\
  27.   char * : string_to_string(str, to(char *, x)),\
  28.   struct_t : struct_to_string(str, to(struct_t, x))\
  29. )
  30.  
  31. #define FIRST(a, ...) a
  32. #define SECOND(a, b, ...) b
  33.  
  34. #define EMPTY()
  35.  
  36. #define EVAL(...) EVAL32(__VA_ARGS__)
  37. #define EVAL32(...) EVAL16(EVAL16(__VA_ARGS__))
  38. #define EVAL16(...) EVAL8(EVAL8(__VA_ARGS__))
  39. #define EVAL8(...) EVAL4(EVAL4(__VA_ARGS__))
  40. #define EVAL4(...) EVAL2(EVAL2(__VA_ARGS__))
  41. #define EVAL2(...) EVAL1(EVAL1(__VA_ARGS__))
  42. #define EVAL1(...) __VA_ARGS__
  43.  
  44. #define DEFER1(m) m EMPTY()
  45. #define DEFER2(m) m EMPTY EMPTY()()
  46. #define DEFER3(m) m EMPTY EMPTY EMPTY()()()
  47. #define DEFER4(m) m EMPTY EMPTY EMPTY EMPTY()()()()
  48.  
  49. #define IS_PROBE(...) SECOND(__VA_ARGS__, 0)
  50. #define PROBE() ~, 1
  51.  
  52. #define CAT(a,b) a ## b
  53.  
  54. #define NOT(x) IS_PROBE(CAT(_NOT_, x))
  55. #define _NOT_0 PROBE()
  56.  
  57. #define BOOL(x) NOT(NOT(x))
  58.  
  59. #define IF_ELSE(condition) _IF_ELSE(BOOL(condition))
  60. #define _IF_ELSE(condition) CAT(_IF_, condition)
  61.  
  62. #define _IF_1(...) __VA_ARGS__ _IF_1_ELSE
  63. #define _IF_0(...) _IF_0_ELSE
  64.  
  65. #define _IF_1_ELSE(...)
  66. #define _IF_0_ELSE(...) __VA_ARGS__
  67.  
  68. #define HAS_ARGS(...) BOOL(FIRST(_END_OF_ARGUMENTS_ __VA_ARGS__)())
  69. #define _END_OF_ARGUMENTS_() 0
  70.  
  71. #define MAP(m, first, ...) \
  72.   m(first) \
  73.   IF_ELSE(HAS_ARGS(__VA_ARGS__))( \
  74.   DEFER2(_MAP)()(m, __VA_ARGS__) \
  75.   )( \
  76.   /* Do nothing, just terminate */ \
  77.   )
  78. #define _MAP() MAP
  79.  
  80. #define op(x) str = to_string(str, x);
  81.  
  82. #define fprintf_proturbo(file, ...) ({\
  83.   char * str = malloc(1000500), * s = str;\
  84.   EVAL(MAP(op, __VA_ARGS__));\
  85.   *str = 0;\
  86.   int i = fprintf(file, "%s", s);\
  87.   free(s);\
  88.   i;\
  89. })
  90.  
  91.  
  92. int main(void) {
  93. struct_t st = {10, 23};
  94. fprintf_proturbo(stderr, 234235, " ", 523523, "\n", st, " ", 423523, "\n");
  95. }
Success #stdin #stdout #stderr 0s 2152KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
234235 523523
{x: 10, y: 23} 423523