From 62e9a9405bff5d2ca1d69af192a2b937afd132b2 Mon Sep 17 00:00:00 2001
From: Abdelrahman Said <said.abdelrahman89@gmail.com>
Date: Sat, 30 Dec 2023 19:09:20 +0000
Subject: [PATCH] Implement version with macros

---
 02_macros/main.c  | 17 +++++++++
 02_macros/vec.h   | 23 ++++++++++++
 02_macros/vec.inc | 93 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 133 insertions(+)
 create mode 100644 02_macros/main.c
 create mode 100644 02_macros/vec.h
 create mode 100644 02_macros/vec.inc

diff --git a/02_macros/main.c b/02_macros/main.c
new file mode 100644
index 0000000..2c23497
--- /dev/null
+++ b/02_macros/main.c
@@ -0,0 +1,17 @@
+#define VEC_IMPLEMENTATION
+#include "vec.h"
+#undef VEC_IMPLEMENTATION
+
+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/02_macros/vec.h b/02_macros/vec.h
new file mode 100644
index 0000000..bde5ece
--- /dev/null
+++ b/02_macros/vec.h
@@ -0,0 +1,23 @@
+#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 I i
+#define PI d
+#include "vec.inc"
+
+#define T f32
+#define I f
+#define PI f
+#include "vec.inc"
+
+#endif // VEC_MACRO_H
diff --git a/02_macros/vec.inc b/02_macros/vec.inc
new file mode 100644
index 0000000..6427f05
--- /dev/null
+++ b/02_macros/vec.inc
@@ -0,0 +1,93 @@
+#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 {
+	T x;
+	T y;
+} typename(2, I);
+
+typedef struct {
+	T x;
+	T y;
+	T z;
+} typename(3, I);
+
+INTERNAL void funcname(print, 2, I)(typename(2, I) v1);
+INTERNAL typename(2, I) funcname(add, 2, I)(typename(2, I) v1, typename(2, I) v2);
+INTERNAL typename(2, I) funcname(sub, 2, I)(typename(2, I) v1, typename(2, I) v2);
+INTERNAL typename(2, I) funcname(mul, 2, I)(typename(2, I) v1, typename(2, I) v2);
+INTERNAL T funcname(dot, 2, I)(typename(2, I) v1, typename(2, I) v2);
+INTERNAL T funcname(magnitude, 2, I)(typename(2, I) v1);
+
+INTERNAL void funcname(print, 3, I)(typename(3, I) v1);
+INTERNAL typename(3, I) funcname(add, 3, I)(typename(3, I) v1, typename(3, I) v3);
+INTERNAL typename(3, I) funcname(sub, 3, I)(typename(3, I) v1, typename(3, I) v3);
+INTERNAL typename(3, I) funcname(mul, 3, I)(typename(3, I) v1, typename(3, I) v3);
+INTERNAL T funcname(dot, 3, I)(typename(3, I) v1, typename(3, I) v3);
+INTERNAL T funcname(magnitude, 3, I)(typename(3, I) v1);
+
+#ifdef VEC_IMPLEMENTATION
+INTERNAL void funcname(print, 2, I)(typename(2, I) v1) {
+	printf("{%" printf_spec(PI) ", %" printf_spec(PI) "}\n", v1.x, v1.y);
+}
+
+INTERNAL typename(2, I) funcname(add, 2, I)(typename(2, I) v1, typename(2, I) v2) {
+	return (typename(2, I)){v1.x + v2.x, v1.y + v2.y};
+}
+
+INTERNAL typename(2, I) funcname(sub, 2, I)(typename(2, I) v1, typename(2, I) v2) {
+	return (typename(2, I)){v1.x - v2.x, v1.y - v2.y};
+}
+
+INTERNAL typename(2, I) funcname(mul, 2, I)(typename(2, I) v1, typename(2, I) v2) {
+	return (typename(2, I)){v1.x * v2.x, v1.y * v2.y};
+}
+
+INTERNAL T funcname(dot, 2, I)(typename(2, I) v1, typename(2, I) v2) {
+	return v1.x * v2.x + v1.y * v2.y;
+}
+
+INTERNAL T funcname(magnitude, 2, I)(typename(2, I) v1) {
+	T dotproduct = funcname(dot, 2, I)(v1, v1);
+	return (T)sqrtf(dotproduct);
+}
+
+INTERNAL void funcname(print, 3, I)(typename(3, I) v1) {
+	printf("{%" printf_spec(PI) ", %" printf_spec(PI) ", %" printf_spec(PI) "}\n", v1.x, v1.y, v1.z);
+}
+
+INTERNAL typename(3, I) funcname(add, 3, I)(typename(3, I) v1, typename(3, I) v2) {
+	return (typename(3, I)){v1.x + v2.x, v1.y + v2.y, v1.z + v2.z};
+}
+
+INTERNAL typename(3, I) funcname(sub, 3, I)(typename(3, I) v1, typename(3, I) v2) {
+	return (typename(3, I)){v1.x - v2.x, v1.y - v2.y, v1.z - v2.z};
+}
+
+INTERNAL typename(3, I) funcname(mul, 3, I)(typename(3, I) v1, typename(3, I) v2) {
+	return (typename(3, I)){v1.x * v2.x, v1.y * v2.y, v1.z * v2.z};
+}
+
+INTERNAL T funcname(dot, 3, I)(typename(3, I) v1, typename(3, I) v2) {
+	return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
+}
+
+INTERNAL T funcname(magnitude, 3, I)(typename(3, I) v1) {
+	T dotproduct = funcname(dot, 3, I)(v1, v1);
+	return (T)sqrtf(dotproduct);
+}
+#endif
+
+#undef PI
+#undef I
+#undef C
+#undef T