diff --git a/03_xmacros/main.c b/03_xmacros/main.c new file mode 100644 index 0000000..4b7f6d3 --- /dev/null +++ b/03_xmacros/main.c @@ -0,0 +1,18 @@ +#define VEC_IMPLEMENTATION +#include "vec.h" +#undef VEC_IMPLEMENTATION +#include + +int main(int argc, char *argv[]) { + vec2i_t v1 = (vec2i_t){2, 3}; + vec2i_t v2 = (vec2i_t){4, 5}; + + vec_print(vec2i_t, vec_add(vec2i_t, v1, v2)); + vec_print(vec2i_t, vec_sub(vec2i_t, v1, v2)); + vec_print(vec2i_t, vec_mul(vec2i_t, v1, v2)); + printf("%d\n", vec_dot(vec2i_t, v1, v2)); + printf("%d\n", vec_magnitude(vec2i_t, v1)); + printf("%d\n", vec_magnitude(vec2i_t, v2)); + + return 0; +} diff --git a/03_xmacros/vec.h b/03_xmacros/vec.h new file mode 100644 index 0000000..3a54d08 --- /dev/null +++ b/03_xmacros/vec.h @@ -0,0 +1,51 @@ +#ifndef VEC_MACRO_H +#define VEC_MACRO_H + +#include "../aliases.h" + +#define vec_print(T, v1) vec_print_##T(v1) +#define vec_add(T, v1, v2) vec_add_##T(v1, v2) +#define vec_sub(T, v1, v2) vec_sub_##T(v1, v2) +#define vec_mul(T, v1, v2) vec_mul_##T(v1, v2) +#define vec_dot(T, v1, v2) vec_dot_##T(v1, v2) +#define vec_magnitude(T, v) vec_magnitude_##T(v) + +#define T i32 +#define C 2 +#define I i +#define PI d +#define VEC_FIELDS \ + VEC(i32, x) \ + VEC(i32, y) +#include "vec.inc" + +#define T i32 +#define C 3 +#define I i +#define PI d +#define VEC_FIELDS \ + VEC(i32, x) \ + VEC(i32, y) \ + VEC(i32, z) +#include "vec.inc" + +#define T f32 +#define C 2 +#define I f +#define PI f +#define VEC_FIELDS \ + VEC(f32, x) \ + VEC(f32, y) +#include "vec.inc" + +#define T f32 +#define C 3 +#define I f +#define PI f +#define VEC_FIELDS \ + VEC(f32, x) \ + VEC(f32, y) \ + VEC(f32, z) +#include "vec.inc" + +#endif // !VEC_MACRO_H diff --git a/03_xmacros/vec.inc b/03_xmacros/vec.inc new file mode 100644 index 0000000..48f842e --- /dev/null +++ b/03_xmacros/vec.inc @@ -0,0 +1,79 @@ +#include "../aliases.h" +#include +#include + +#define obj(o, m) o.m +#define stringify(x) #x +#define printf_spec(PI) "%" stringify(PI) ", " +#define typename_concat(C, I) vec##C##I##_t +#define typename(C, I) typename_concat(C, I) +#define funcname_concat(B, C, I) vec_##B##_vec##C##I##_t +#define funcname(B, C, I) funcname_concat(B, C, I) + +typedef struct { + #define VEC(type, name) type name; + VEC_FIELDS + #undef VEC +} typename(C, I); + +INTERNAL void funcname(print, C, I)(typename(C, I) v1); +INTERNAL typename(C, I) funcname(add, C, I)(typename(C, I) v1, typename(C, I) v2); +INTERNAL typename(C, I) funcname(sub, C, I)(typename(C, I) v1, typename(C, I) v2); +INTERNAL typename(C, I) funcname(mul, C, I)(typename(C, I) v1, typename(C, I) v2); +INTERNAL T funcname(dot, C, I)(typename(C, I) v1, typename(C, I) v2); +INTERNAL T funcname(magnitude, C, I)(typename(C, I) v1); + +#ifdef VEC_IMPLEMENTATION + void funcname(print, C, I)(typename(C, I) v1) { + printf("{ " + #define VEC(type, name) printf_spec(PI) + VEC_FIELDS "%c}\n", + #undef VEC + #define VEC(type, name) obj(v1, name), + VEC_FIELDS + #undef VEC + '\0'); + } + +INTERNAL typename(C, I) funcname(add, C, I)(typename(C, I) v1, typename(C, I) v2) { + return (typename(C, I)) { + #define VEC(type, name) obj(v1, name) + obj(v2, name), + VEC_FIELDS + #undef VEC + }; +} + +INTERNAL typename(C, I) funcname(sub, C, I)(typename(C, I) v1, typename(C, I) v2) { + return (typename(C, I)) { + #define VEC(type, name) obj(v1, name) - obj(v2, name), + VEC_FIELDS + #undef VEC + }; +} + +INTERNAL typename(C, I) funcname(mul, C, I)(typename(C, I) v1, typename(C, I) v2) { + return (typename(C, I)) { + #define VEC(type, name) obj(v1, name) * obj(v2, name), + VEC_FIELDS + #undef VEC + }; +} + +INTERNAL T funcname(dot, C, I)(typename(C, I) v1, typename(C, I) v2) { + return + #define VEC(type, name) obj(v1, name) * obj(v2, name) + + VEC_FIELDS 0; + #undef VEC +} + +INTERNAL T funcname(magnitude, C, I)(typename(C, I) v1) { + T dotproduct = funcname(dot, C, I)(v1, v1); + return (T)sqrtf(dotproduct); +} +#endif + +#undef VEC_FIELDS +#undef PI +#undef I +#undef C +#undef T