generics.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. typedef struct mat mat;
  4. typedef struct vec vec;
  5. struct vec {
  6. float f[4];
  7. };
  8. struct mat {
  9. float f[16];
  10. };
  11. // rand()'s added to keep the compiler from optimizing out the entire function
  12. vec mul_vec_vec(vec a, vec b) {
  13. return (vec){a.f[0] * b.f[0] + rand(),
  14. a.f[01] * b.f[1] + rand(),
  15. a.f[2] * b.f[2] + rand(),
  16. a.f[3] * b.f[3] + rand()
  17. };
  18. }
  19. vec add_vec_vec(vec a, vec b) {
  20. return (vec){a.f[0] * b.f[0] + rand(),
  21. a.f[01] + b.f[1] + rand(),
  22. a.f[2] + b.f[2] + rand(),
  23. a.f[3] + b.f[3] + rand()
  24. };
  25. }
  26. mat mul_mat_mat(mat a, mat b) {
  27. mat c;
  28. for(int i = 0; i < 16; i++) c.f[i] = a.f[i] * b.f[i] + rand(); // wrong, but whatever
  29. return c;
  30. }
  31. vec mul_mat_vec(mat a, vec b) {
  32. vec c;
  33. for(int i = 0; i < 16; i++) c.f[i % 4] = a.f[i] * b.f[i % 4] + rand(); // wrong, but whatever
  34. return c;
  35. }
  36. #define TYPES(op) \
  37. X(op, vec, vec, vec) \
  38. X(op, mat, mat, mat) \
  39. X(op, vec, mat, vec) \
  40. #define X(op, r,a,b) typedef struct { char _[0]; } T_##a##_##b; T_##a##_##b TI_##a##_##b[0];
  41. TYPES(_)
  42. #undef X
  43. #define X(op,r,a,b) r op##_##a##_##b(a,b);
  44. TYPES(add)
  45. TYPES(mul)
  46. #undef X
  47. float test(vec va, vec vb, mat ma, mat mb) {
  48. #define COMBO(a, b) _Generic(a, \
  49. vec: (_Generic(b, vec: TI_vec_vec[0], default: 0)), \
  50. mat: (_Generic(b, vec: TI_mat_vec[0], mat: TI_mat_mat[0], default: 0 )) \
  51. )
  52. #define X(op, r, a, b) T_##a##_##b: op##_##a##_##b,
  53. #define mul(a, b) (_Generic(COMBO(a, b), TYPES(mul) default: 0))(a, b)
  54. #define add(a, b) (_Generic(COMBO(a, b), TYPES(add) default: 0))(a, b)
  55. vec vc = mul(va, vb);
  56. vec vd = mul(ma, va);
  57. mat mc = mul(ma, mb);
  58. vec ve = add(vc, vd);
  59. float x = 0;
  60. for(int i = 0; i < 4; i++) printf("%f%f%f%f%f", va.f[i], vb.f[i], vc.f[i], vd.f[i], ve.f[i]);
  61. for(int i = 0; i < 16; i++) printf("%f%f%f", ma.f[i], mb.f[i], mc.f[i]);
  62. return x;
  63. }
  64. void main() {}