Impelement version with X macros

This commit is contained in:
Abdelrahman Said 2023-12-30 19:09:29 +00:00
parent 62e9a9405b
commit 6d1f5d3b4c
3 changed files with 148 additions and 0 deletions

18
03_xmacros/main.c Normal file
View File

@ -0,0 +1,18 @@
#define VEC_IMPLEMENTATION
#include "vec.h"
#undef VEC_IMPLEMENTATION
#include <stdio.h>
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;
}

51
03_xmacros/vec.h Normal file
View File

@ -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

79
03_xmacros/vec.inc Normal file
View File

@ -0,0 +1,79 @@
#include "../aliases.h"
#include <stdio.h>
#include <math.h>
#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