#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