aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbonmas14 <bonmas14@gmail.com>2025-08-23 01:28:41 +0300
committerbonmas14 <bonmas14@gmail.com>2025-08-23 01:28:41 +0300
commit8ebdc95621bc61fdf3c98cd7ae4ddca67398df23 (patch)
tree205413ed09ac001e37267889d429a363c37008f2
parentc96c355b360f18f982459e1a866dcbf5864efdb8 (diff)
downloadungrateful-8ebdc95621bc61fdf3c98cd7ae4ddca67398df23.tar.gz
ungrateful-8ebdc95621bc61fdf3c98cd7ae4ddca67398df23.zip
Ungrateful changes, added more stuffHEADmain
-rw-r--r--README.md5
-rw-r--r--USAGE.md22
-rw-r--r--build.bat5
-rw-r--r--src/un_list.c39
-rw-r--r--src/un_math.c220
-rw-r--r--src/un_mem_linux_x64.c16
-rw-r--r--src/un_mem_std.c14
-rw-r--r--src/un_mem_win_x64.c18
-rw-r--r--src/un_memory.c90
-rw-r--r--src/un_splines.c93
-rw-r--r--src/un_vecr.c353
-rw-r--r--src/un_wstrings.c66
-rw-r--r--src/ungrateful.c9
-rw-r--r--src/ungrateful.h497
-rw-r--r--tests/un/allocs.c11
-rw-r--r--tests/un/lists.c20
-rw-r--r--tests/un/math.c2
-rw-r--r--tests/un/mathd.c28
-rw-r--r--tests/un/mathf.c28
-rw-r--r--tests/un/mathr.c280
-rw-r--r--tests/un/matrix.c8
-rw-r--r--tests/un/strings.c10
-rw-r--r--tests/un/win_wstr.c26
23 files changed, 855 insertions, 1005 deletions
diff --git a/README.md b/README.md
index 0f7864a..4800262 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,8 @@ Types, Strings, basic memory allocators (platform specific), and so on. Features
+ easing;
+ vecs;
+ splines (qubic);
++ ~ Memory debugging; @todo, we have wrapper but none of the debug functionality.
++ complex numbers;
Todo:
- matrix;
@@ -38,9 +40,8 @@ Todo:
- Random;
- Noises;
- Compression;
-- Wide strings (internal);
+- Wide strings (internal);
- Sorting;
-- Memory debugging;
# Cynic
diff --git a/USAGE.md b/USAGE.md
index 706b9c3..bc06f69 100644
--- a/USAGE.md
+++ b/USAGE.md
@@ -12,16 +12,32 @@ It will create include folder and copy all of the headers, create lib folder and
- Don't use *_internal.h files, as they are only for implementation and could add fun things as windows.h
+# GCC
+
+Basically after running `build.sh` just compile your code with adding link path and include path.
+
+## Arch
+
+```
+sudo pacman -S base-devel
+```
+
+## Debian
+
+```
+sudo pacman -S build-essentials
+```
+
# MSVC
-Here are warnings you should disable:
+Note: Tested on VS2022 with compiler 19.39.33523
+Disable these warnings:
```
-/wd4244
+/wd4244 /wd5105
```
Also here are defines:
-
```
/D _CRT_SECURE_NO_WARNINGS /D _UNICODE /D UNICODE
```
diff --git a/build.bat b/build.bat
index 1b8e58d..145b068 100644
--- a/build.bat
+++ b/build.bat
@@ -25,6 +25,7 @@
:: /LDd - ...
setlocal
+setlocal enabledelayedexpansion
set "cc=cl.exe"
set "ar=lib.exe"
@@ -35,7 +36,7 @@ set "obj_dir=obj\"
set "inc_dir=include\"
set "lib_dir=lib\"
-set "warn=/wd4244"
+set "warn=/wd4244 /wd5105"
set "cdefines=/D _CRT_SECURE_NO_WARNINGS /D _UNICODE /D UNICODE"
set "cflags=/nologo /std:c11 /utf-8 /W4 /WX- /diagnostics:column /TC /Zi /fp:fast"
@@ -88,7 +89,7 @@ echo:
for %%f in ("%bin_dir%*.exe") do (
%%f
- if %errorlevel% == 0 (
+ if !errorlevel! == 0 (
echo [DONE] %%f
) else (
echo [FAIL] %%f
diff --git a/src/un_list.c b/src/un_list.c
index 133dc12..9d6a5ce 100644
--- a/src/un_list.c
+++ b/src/un_list.c
@@ -8,12 +8,16 @@ List un_list_create(u64 start_capacity, u64 element_size, Allocator alloc) {
list.data = un_memory_alloc(list.capacity * list.element_size, alloc);
- assert(list.data != NULL);
+ if (list.data == NULL) {
+ list.alloc = un_allocator_get_temporary();
+ list.data = un_memory_alloc(list.capacity * list.element_size, list.alloc);
+ }
+
return list;
}
-void un_list_destroy(List *list) {
- un_memory_destroy(&list->alloc);
+void un_list_destroy(List *list, b32 delete_allocator) {
+ if (delete_allocator) { un_memory_destroy(&list->alloc); }
UN_CLEAR(*list);
}
@@ -25,6 +29,11 @@ List un_list_clone(List *list, Allocator alloc) {
result.data = un_memory_alloc(result.capacity * result.element_size, alloc);
assert(result.data != NULL);
+ if (result.data == NULL) {
+ result.alloc = un_allocator_get_temporary();
+ result.data = un_memory_alloc(result.capacity * result.element_size, result.alloc);
+ }
+
un_memory_copy(result.data, list->data, result.count * result.element_size);
return result;
@@ -34,12 +43,15 @@ static b32 list_grow_if_needed(List *list) {
if ((list->count + 1) <= list->capacity) {
return true;
} else {
- void *mem = un_memory_realloc(list->data, list->element_size * list->capacity * 2, list->alloc);
+ void *mem = un_memory_alloc(list->element_size * list->capacity * 2, list->alloc);
if (!mem) {
return false;
}
+ un_memory_copy(mem, list->data, list->element_size * list->capacity);
+ un_memory_free(list->data, list->alloc);
+
list->data = mem;
list->capacity *= 2;
}
@@ -47,7 +59,22 @@ static b32 list_grow_if_needed(List *list) {
return true;
}
+static void un_list_create_if_needed(List *list) {
+ assert(list != NULL);
+
+ if (list->data != NULL) return;
+
+ assert(list->capacity == 0);
+ assert(list->element_size != 0);
+
+ if (!list->data) {
+ Allocator alloc = list->alloc.proc == NULL ? un_allocator_get_standard() : list->alloc;
+ *list = un_list_create(UN_LIST_STANDARD_CAPACITY, list->element_size, alloc);
+ }
+}
+
b32 un_list_append(List *list, void *data) {
+ un_list_create_if_needed(list);
void *addr;
if (list_grow_if_needed(list)) {
@@ -63,6 +90,8 @@ b32 un_list_append(List *list, void *data) {
void *un_list_get(List *list, u64 index) {
if (index >= list->count) return NULL;
+ assert(list->data != NULL);
+
return (u8*)list->data + index * list->element_size;
}
@@ -72,8 +101,8 @@ void un_list_remove(List *list, u64 index) {
if (index >= list->count) return;
+ assert(list->data != NULL);
addr = (u8*)list->data + index * list->element_size;
-
move_elements = list->count - (index + 1);
if (move_elements) {
diff --git a/src/un_math.c b/src/un_math.c
index 42a1c4b..a2ff65e 100644
--- a/src/un_math.c
+++ b/src/un_math.c
@@ -1,50 +1,13 @@
-/* reals */
-
-real un_m_lerpr(real a, real b, real t) {
+/* lerps */
+f32 un_m_lerpf(f32 a, f32 b, f32 t) {
return (1.0 - t) * a + b * t;
}
-real un_m_ease_isiner(real t) {
-#if defined(UN_DOUBLE_PRECISION)
- return 1.0 - cos((t * PI_D) / 2.0);
-#else
- return 1.0 - cosf((t * PI) / 2.0);
-#endif
-}
-
-real un_m_ease_iosiner(real t) {
-#if defined(UN_DOUBLE_PRECISION)
- return sin((t * PI_D) / 2.0f);
-#else
- return sinf((t * PI) / 2.0f);
-#endif
-}
-
-real un_m_ease_osiner(real t) {
-#if defined(UN_DOUBLE_PRECISION)
- return -(cos(t * PI_D) - 1.0) / 2.0;
-#else
- return -(cosf(t * PI) - 1.0) / 2.0;
-#endif
-}
-
-real un_m_ease_iquadr(real t) {
- return t * t;
-}
-
-real un_m_ease_ioquadr(real t) {
- return 1.0 - (1.0 - t) * (1.0 - t);
-}
-
-real un_m_ease_oquadr(real t) {
- return t < 0.5 ? 2.0 * t * t : 1.0 - ((-2.0 * t + 2.0) * (-2.0 * t + 2.0)) / 2.0;
-}
-
-/* floats */
-f32 un_m_lerpf(f32 a, f32 b, f32 t) {
+f64 un_m_lerpd(f64 a, f64 b, f64 t) {
return (1.0 - t) * a + b * t;
}
+/* easing */
f32 un_m_ease_isinef(f32 t) {
return 1.0 - cosf((t * PI) / 2.0);
}
@@ -69,11 +32,6 @@ f32 un_m_ease_oquadf(f32 t) {
return t < 0.5 ? 2.0 * t * t : 1.0 - ((-2.0 * t + 2.0) * (-2.0 * t + 2.0)) / 2.0;
}
-/* doubles */
-f64 un_m_lerpd(f64 a, f64 b, f64 t) {
- return (1.0 - t) * a + b * t;
-}
-
f64 un_m_ease_isined(f64 t) {
return 1.0 - cos((t * PI) / 2.0);
}
@@ -97,3 +55,173 @@ f64 un_m_ease_ioquadd(f64 t) {
f64 un_m_ease_oquadd(f64 t) {
return t < 0.5 ? 2.0 * t * t : 1.0 - ((-2.0 * t + 2.0) * (-2.0 * t + 2.0)) / 2.0;
}
+
+/* complex */
+
+void un_m_complex_divf(f32 *v, f32 *a, f32 *b) {
+ f32 divisor;
+
+ // un_m_complex_mulf(v, a, conjugated_b)
+ v[0] = a[0] * b[0] - a[1] * -b[1];
+ v[1] = a[0] * -b[1] + a[1] * b[0];
+
+ divisor = b[0] * b[0] + b[1] * b[1];
+
+ v[0] /= divisor;
+ v[1] /= divisor;
+}
+
+void un_m_complex_mulf(f32 *v, f32 *a, f32 *b) {
+ v[0] = a[0] * b[0] - a[1] * b[1];
+ v[1] = a[0] * b[1] + a[1] * b[0];
+}
+
+
+void un_m_complex_divd(f64 *v, f64 *a, f64 *b) {
+ f64 divisor;
+
+ // un_m_complex_muld(v, a, conjugated_b)
+ v[0] = a[0] * b[0] - a[1] * -b[1];
+ v[1] = a[0] * -b[1] + a[1] * b[0];
+
+ divisor = b[0] * b[0] + b[1] * b[1];
+
+ v[0] /= divisor;
+ v[1] /= divisor;
+}
+
+void un_m_complex_muld(f64 *v, f64 *a, f64 *b) {
+ v[0] = a[0] * b[0] - a[1] * b[1];
+ v[1] = a[0] * b[1] + a[1] * b[0];
+}
+
+/* splines */
+
+void un_m_bezierf(f32 *v, f32 a, f32 q0, f32 q1, f32 b, f32 t) {
+ f32 i0, i1, i2, p0, p1, ti;
+
+ ti = 1.0 - t;
+
+ i0 = ti * a + q0 * t;
+ i1 = ti * q0 + q1 * t;
+ i2 = ti * q1 + b * t;
+
+ p0 = ti * i0 + i1 * t;
+ p1 = ti * i1 + i2 * t;
+
+ *v = ti * p0 + p1 * t;
+}
+
+void un_m_bezierd(f64 *v, f64 a, f64 q0, f64 q1, f64 b, f64 t) {
+ f64 i0, i1, i2, p0, p1, ti;
+
+ ti = 1.0 - t;
+
+ i0 = ti * a + q0 * t;
+ i1 = ti * q0 + q1 * t;
+ i2 = ti * q1 + b * t;
+
+ p0 = ti * i0 + i1 * t;
+ p1 = ti * i1 + i2 * t;
+
+ *v = ti * p0 + p1 * t;
+}
+
+void un_m_bezier2f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
+ un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
+}
+
+void un_m_bezier3f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
+ un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
+ un_m_bezierf(v + 2, a[2], q0[2], q1[2], b[2], t);
+}
+
+void un_m_bezier4f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
+ un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
+ un_m_bezierf(v + 2, a[2], q0[2], q1[2], b[2], t);
+ un_m_bezierf(v + 3, a[3], q0[3], q1[3], b[3], t);
+}
+
+
+void un_m_bezier2d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
+ un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
+}
+
+void un_m_bezier3d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
+ un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
+ un_m_bezierd(v + 2, a[2], q0[2], q1[2], b[2], t);
+}
+
+void un_m_bezier4d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
+ un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
+ un_m_bezierd(v + 2, a[2], q0[2], q1[2], b[2], t);
+ un_m_bezierd(v + 3, a[3], q0[3], q1[3], b[3], t);
+}
+
+
+
+/* matrix and quaternions */
+
+/* convention of matrix is: Column-major
+ *
+ * stored in memory as x0 y0 z0 w0 x1 y1 z1 w1 ...
+ *
+ * transform
+ * inverse transform
+ * multiply
+ * reverse
+ * rotate
+ * quaternion -> matrix
+ * matrix -> quaternion
+ * matrix to components: un_mat_disassemble(f32 *pos3, f32 *scale3, f32 *quat4)
+ * un_mat_assemble(f32 *v, f32 *pos3, f32 *scale3, f32 *quat4)
+ * assembe_inverse
+ *
+ * */
+
+
+
+void un_m_mat_identityf(f32 *v) {
+ un_memory_set((void*)v, 0, sizeof(*v) * UN_MATRIX_SIZE);
+
+ v[0 + 0 * UN_MATRIX_STRIPE] = 1.0f;
+ v[1 + 1 * UN_MATRIX_STRIPE] = 1.0f;
+ v[2 + 2 * UN_MATRIX_STRIPE] = 1.0f;
+ v[3 + 3 * UN_MATRIX_STRIPE] = 1.0f;
+}
+
+void un_m_mat_mulf(f32 *v, f32 *left, f32 *right) {
+ u64 row, col, i;
+ un_memory_set((void*)v, 0, sizeof(*v) * UN_MATRIX_SIZE);
+
+ for (col = 0; col < 4; col++) {
+ for (row = 0; row < 4; row++) {
+ for (i = 0; i < 4; i++) {
+ v[row + col * UN_MATRIX_STRIPE] += left[row + i * UN_MATRIX_STRIPE] * right[i + col * UN_MATRIX_STRIPE];
+ }
+ }
+ }
+}
+
+void un_mat_xformf(f32 *v, f32 *xform) {
+ un_m_mat_identityf(v);
+
+ v[3 + 0 * UN_MATRIX_STRIPE] += xform[0];
+ v[3 + 1 * UN_MATRIX_STRIPE] += xform[1];
+ v[3 + 2 * UN_MATRIX_STRIPE] += xform[2];
+}
+
+void un_mat_scalef(f32 *v, f32 *scale) {
+ un_m_mat_identityf(v);
+
+ v[0 + 0 * UN_MATRIX_STRIPE] = scale[0];
+ v[1 + 1 * UN_MATRIX_STRIPE] = scale[1];
+ v[2 + 2 * UN_MATRIX_STRIPE] = scale[2];
+}
+
diff --git a/src/un_mem_linux_x64.c b/src/un_mem_linux_x64.c
new file mode 100644
index 0000000..3d498bc
--- /dev/null
+++ b/src/un_mem_linux_x64.c
@@ -0,0 +1,16 @@
+// @todo: mmap
+
+static ALLOCATOR_PROC_SIGNATURE(un_std_alloc_proc) {
+ UNUSED(data);
+
+ switch (message) {
+ case UN_ALLOC_MSG_ALLOCATE:
+ return calloc(1, size);
+ case UN_ALLOC_MSG_FREE:
+ free(p);
+ break;
+ case UN_ALLOC_MSG_SELF_DELETE: break;
+ }
+
+ return NULL;
+}
diff --git a/src/un_mem_std.c b/src/un_mem_std.c
new file mode 100644
index 0000000..0d5d288
--- /dev/null
+++ b/src/un_mem_std.c
@@ -0,0 +1,14 @@
+static ALLOCATOR_PROC_SIGNATURE(un_std_alloc_proc) {
+ UNUSED(data);
+
+ switch (message) {
+ case UN_ALLOC_MSG_ALLOCATE:
+ return calloc(1, size);
+ case UN_ALLOC_MSG_FREE:
+ free(p);
+ break;
+ case UN_ALLOC_MSG_SELF_DELETE: break;
+ }
+
+ return NULL;
+}
diff --git a/src/un_mem_win_x64.c b/src/un_mem_win_x64.c
new file mode 100644
index 0000000..91f838f
--- /dev/null
+++ b/src/un_mem_win_x64.c
@@ -0,0 +1,18 @@
+#include <windows.h>
+
+static ALLOCATOR_PROC_SIGNATURE(un_std_alloc_proc) {
+ UNUSED(data);
+
+ switch (message) {
+ case UN_ALLOC_MSG_ALLOCATE:
+ return VirtualAlloc(NULL, (SIZE_T)size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+ case UN_ALLOC_MSG_FREE:
+ if (!VirtualFree(p, 0, MEM_RELEASE)) {
+ assert(false);
+ }
+ break;
+ case UN_ALLOC_MSG_SELF_DELETE: break;
+ }
+
+ return NULL;
+}
diff --git a/src/un_memory.c b/src/un_memory.c
index b092196..178fcbc 100644
--- a/src/un_memory.c
+++ b/src/un_memory.c
@@ -56,14 +56,9 @@ void *un_memory_alloc(u64 size, Allocator alloc) {
return alloc.proc(NULL, size, UN_ALLOC_MSG_ALLOCATE, alloc.data);
}
-void *un_memory_realloc(void *ptr, u64 size, Allocator alloc) {
+void un_memory_free(void *ptr, Allocator alloc) {
assert(alloc.proc != NULL);
- return alloc.proc(ptr, size, UN_ALLOC_MSG_REALLOCATE, alloc.data);
-}
-
-void *un_memory_free(void *ptr, Allocator alloc) {
- assert(alloc.proc != NULL);
- return alloc.proc(ptr, 0, UN_ALLOC_MSG_FREE, alloc.data);
+ alloc.proc(ptr, 0, UN_ALLOC_MSG_FREE, alloc.data);
}
void un_memory_destroy(Allocator *alloc) {
@@ -77,22 +72,16 @@ void un_memory_destroy(Allocator *alloc) {
/// -------- Stdlib allocator
-static ALLOCATOR_PROC_SIGNATURE(un_std_alloc_proc) {
- UNUSED(data);
+#if defined(OS_WINDOWS)
+#include "un_mem_win_x64.c"
- switch (message) {
- case UN_ALLOC_MSG_ALLOCATE:
- return calloc(1, size);
- case UN_ALLOC_MSG_REALLOCATE:
- return realloc(p, size);
- case UN_ALLOC_MSG_FREE:
- free(p);
- break;
- case UN_ALLOC_MSG_SELF_DELETE: break;
- }
+#elif defined(OS_LINUX)
+#include "un_mem_linux_x64.c"
- return NULL;
-}
+#else
+#include "un_mem_std.c"
+
+#endif
Allocator un_allocator_get_standard(void) {
return CLITERAL(Allocator) { .proc = un_std_alloc_proc };
@@ -134,7 +123,6 @@ static ALLOCATOR_PROC_SIGNATURE(un_temp_alloc_proc) {
switch (message) {
case UN_ALLOC_MSG_ALLOCATE:
return temp_alloc(size);
- case UN_ALLOC_MSG_REALLOCATE:
case UN_ALLOC_MSG_FREE:
break;
case UN_ALLOC_MSG_SELF_DELETE: break;
@@ -204,8 +192,6 @@ static ALLOCATOR_PROC_SIGNATURE(un_arena_alloc_proc) {
switch (message) {
case UN_ALLOC_MSG_ALLOCATE:
return arena_allocate(size, (Arena*)data);
- case UN_ALLOC_MSG_REALLOCATE:
- break;
case UN_ALLOC_MSG_FREE:
break;
case UN_ALLOC_MSG_SELF_DELETE:
@@ -224,3 +210,59 @@ Allocator un_allocator_create_arena(u64 size) {
return alloc;
}
+
+/// Wrapping allocator
+
+
+typedef struct Allocation_Info {
+ void *p;
+ u64 size;
+} Allocation_Info;
+
+typedef struct Wrapper {
+ // we need to create hashmap and add all allocations in here
+ // List allocations;
+ Allocator target;
+} Wrapper;
+
+static Wrapper *wrapper_create(Allocator target) {
+ Wrapper *wrapper = (Wrapper *)un_memory_alloc(sizeof(Wrapper), un_allocator_get_standard());
+
+ un_memory_set((void*)wrapper, 0, sizeof(Wrapper));
+ wrapper->target = target;
+
+ return wrapper;
+}
+
+static void wrapper_destroy(Wrapper *wrapper) {
+ assert(wrapper != NULL);
+
+ un_memory_free(wrapper, un_allocator_get_standard());
+}
+
+static ALLOCATOR_PROC_SIGNATURE(un_wrapper_alloc_proc) {
+ assert(data != NULL);
+
+ switch (message) {
+ case UN_ALLOC_MSG_ALLOCATE:
+ return un_memory_alloc(size, ((Wrapper*)data)->target);
+ case UN_ALLOC_MSG_FREE:
+ un_memory_free(p, ((Wrapper*)data)->target);
+ break;
+ case UN_ALLOC_MSG_SELF_DELETE:
+ un_memory_destroy(&((Wrapper*)data)->target);
+ wrapper_destroy((Wrapper*)data);
+ break;
+ }
+
+ return NULL;
+}
+
+Allocator un_allocator_create_wrapper(Allocator target) {
+ Allocator alloc = { 0 };
+
+ alloc.proc = un_wrapper_alloc_proc;
+ alloc.data = wrapper_create(target);
+
+ return alloc;
+}
diff --git a/src/un_splines.c b/src/un_splines.c
deleted file mode 100644
index c6d2844..0000000
--- a/src/un_splines.c
+++ /dev/null
@@ -1,93 +0,0 @@
-void un_m_bezierr(real *v, real a, real q0, real q1, real b, real t) {
- real i0, i1, i2, p0, p1;
-
- i0 = un_m_lerpr(a, q0, t);
- i1 = un_m_lerpr(q0, q1, t);
- i2 = un_m_lerpr(q1, b, t);
-
- p0 = un_m_lerpr(i0, i1, t);
- p1 = un_m_lerpr(i1, i2, t);
-
- *v = un_m_lerpr(p0, p1, t);
-}
-
-void un_m_bezierf(f32 *v, f32 a, f32 q0, f32 q1, f32 b, f32 t) {
- f32 i0, i1, i2, p0, p1;
-
- i0 = un_m_lerpf(a, q0, t);
- i1 = un_m_lerpf(q0, q1, t);
- i2 = un_m_lerpf(q1, b, t);
-
- p0 = un_m_lerpf(i0, i1, t);
- p1 = un_m_lerpf(i1, i2, t);
-
- *v = un_m_lerpf(p0, p1, t);
-}
-
-void un_m_bezierd(f64 *v, f64 a, f64 q0, f64 q1, f64 b, f64 t) {
- f64 i0, i1, i2, p0, p1;
-
- i0 = un_m_lerpd(a, q0, t);
- i1 = un_m_lerpd(q0, q1, t);
- i2 = un_m_lerpd(q1, b, t);
-
- p0 = un_m_lerpd(i0, i1, t);
- p1 = un_m_lerpd(i1, i2, t);
-
- *v = un_m_lerpd(p0, p1, t);
-}
-
-void un_m_bezier2r(real *v, real *a, real *q0, real *q1, real *b, real t) {
- un_m_bezierr(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierr(v + 1, a[1], q0[1], q1[1], b[1], t);
-}
-
-void un_m_bezier3r(real *v, real *a, real *q0, real *q1, real *b, real t) {
- un_m_bezierr(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierr(v + 1, a[1], q0[1], q1[1], b[1], t);
- un_m_bezierr(v + 2, a[2], q0[2], q1[2], b[2], t);
-}
-
-void un_m_bezier4r(real *v, real *a, real *q0, real *q1, real *b, real t) {
- un_m_bezierr(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierr(v + 1, a[1], q0[1], q1[1], b[1], t);
- un_m_bezierr(v + 2, a[2], q0[2], q1[2], b[2], t);
- un_m_bezierr(v + 3, a[3], q0[3], q1[3], b[3], t);
-}
-
-void un_m_bezier2f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
- un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
-}
-
-void un_m_bezier3f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
- un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
- un_m_bezierf(v + 2, a[2], q0[2], q1[2], b[2], t);
-}
-
-void un_m_bezier4f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
- un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
- un_m_bezierf(v + 2, a[2], q0[2], q1[2], b[2], t);
- un_m_bezierf(v + 3, a[3], q0[3], q1[3], b[3], t);
-}
-
-
-void un_m_bezier2d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
- un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
-}
-
-void un_m_bezier3d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
- un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
- un_m_bezierd(v + 2, a[2], q0[2], q1[2], b[2], t);
-}
-
-void un_m_bezier4d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
- un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
- un_m_bezierd(v + 2, a[2], q0[2], q1[2], b[2], t);
- un_m_bezierd(v + 3, a[3], q0[3], q1[3], b[3], t);
-}
diff --git a/src/un_vecr.c b/src/un_vecr.c
deleted file mode 100644
index 0fcf672..0000000
--- a/src/un_vecr.c
+++ /dev/null
@@ -1,353 +0,0 @@
-void un_m_add2r(real *v, real *a, real *b) {
- v[0] = a[0] + b[0];
- v[1] = a[1] + b[1];
-}
-
-void un_m_add3r(real *v, real *a, real *b) {
- v[0] = a[0] + b[0];
- v[1] = a[1] + b[1];
- v[2] = a[2] + b[2];
-}
-
-void un_m_add4r(real *v, real *a, real *b) {
- v[0] = a[0] + b[0];
- v[1] = a[1] + b[1];
- v[2] = a[2] + b[2];
- v[3] = a[3] + b[3];
-}
-
-void un_m_sub2r(real *v, real *a, real *b) {
- v[0] = a[0] - b[0];
- v[1] = a[1] - b[1];
-}
-
-void un_m_sub3r(real *v, real *a, real *b) {
- v[0] = a[0] - b[0];
- v[1] = a[1] - b[1];
- v[2] = a[2] - b[2];
-}
-
-void un_m_sub4r(real *v, real *a, real *b) {
- v[0] = a[0] - b[0];
- v[1] = a[1] - b[1];
- v[2] = a[2] - b[2];
- v[3] = a[3] - b[3];
-}
-
-void un_m_add_scalar2r(real *v, real *a, real scalar) {
- v[0] = a[0] + scalar;
- v[1] = a[1] + scalar;
-}
-
-void un_m_add_scalar3r(real *v, real *a, real scalar) {
- v[0] = a[0] + scalar;
- v[1] = a[1] + scalar;
- v[2] = a[2] + scalar;
-}
-
-void un_m_add_scalar4r(real *v, real *a, real scalar) {
- v[0] = a[0] + scalar;
- v[1] = a[1] + scalar;
- v[2] = a[2] + scalar;
- v[3] = a[3] + scalar;
-}
-
-void un_m_sub_scalar2r(real *v, real *a, real scalar) {
- v[0] = a[0] - scalar;
- v[1] = a[1] - scalar;
-}
-
-void un_m_sub_scalar3r(real *v, real *a, real scalar) {
- v[0] = a[0] - scalar;
- v[1] = a[1] - scalar;
- v[2] = a[2] - scalar;
-}
-
-void un_m_sub_scalar4r(real *v, real *a, real scalar) {
- v[0] = a[0] - scalar;
- v[1] = a[1] - scalar;
- v[2] = a[2] - scalar;
- v[3] = a[3] - scalar;
-}
-
-void un_m_mul_scalar2r(real *v, real *a, real scalar) {
- v[0] = a[0] * scalar;
- v[1] = a[1] * scalar;
-}
-
-void un_m_mul_scalar3r(real *v, real *a, real scalar) {
- v[0] = a[0] * scalar;
- v[1] = a[1] * scalar;
- v[2] = a[2] * scalar;
-}
-
-void un_m_mul_scalar4r(real *v, real *a, real scalar) {
- v[0] = a[0] * scalar;
- v[1] = a[1] * scalar;
- v[2] = a[2] * scalar;
- v[3] = a[3] * scalar;
-}
-
-void un_m_div_scalar2r(real *v, real *a, real scalar) {
- v[0] = a[0] / scalar;
- v[1] = a[1] / scalar;
-}
-
-void un_m_div_scalar3r(real *v, real *a, real scalar) {
- v[0] = a[0] / scalar;
- v[1] = a[1] / scalar;
- v[2] = a[2] / scalar;
-}
-
-void un_m_div_scalar4r(real *v, real *a, real scalar) {
- v[0] = a[0] / scalar;
- v[1] = a[1] / scalar;
- v[2] = a[2] / scalar;
- v[3] = a[3] / scalar;
-}
-
-void un_m_dot2r(real *v, real *a, real *b) {
- *v = a[0] * b[0] + a[1] * b[1];
-}
-
-void un_m_dot3r(real *v, real *a, real *b) {
- *v = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
-}
-
-void un_m_dot4r(real *v, real *a, real *b) {
- *v = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
-}
-
-void un_m_hadamard2r(real *v, real *a, real *b) {
- v[0] = a[0] * b[0];
- v[1] = a[1] * b[1];
-}
-
-void un_m_hadamard3r(real *v, real *a, real *b) {
- v[0] = a[0] * b[0];
- v[1] = a[1] * b[1];
- v[2] = a[2] * b[2];
-}
-
-void un_m_hadamard4r(real *v, real *a, real *b) {
- v[0] = a[0] * b[0];
- v[1] = a[1] * b[1];
- v[2] = a[2] * b[2];
- v[3] = a[3] * b[3];
-}
-
-void un_m_cross2r(real *v, real *a) {
- v[0] = a[1];
- v[1] =-a[0];
-}
-
-void un_m_cross3r(real *v, real *a, real *b) {
- v[0] = a[1] * b[2] - a[2] * b[1];
- v[1] = a[2] * b[0] - a[0] * b[2];
- v[2] = a[0] * b[1] - a[1] * b[0];
-}
-
-void un_m_magnitude2r(real *v, real *a) {
-#if defined(UN_DOUBLE_PRECISION)
- *v = sqrt(a[0] * a[0] + a[1] * a[1]);
-#else
- *v = sqrtf(a[0] * a[0] + a[1] * a[1]);
-#endif
-}
-
-void un_m_magnitude3r(real *v, real *a) {
-#if defined(UN_DOUBLE_PRECISION)
- *v = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
-#else
- *v = sqrtf(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
-#endif
-}
-
-void un_m_magnitude4r(real *v, real *a) {
-#if defined(UN_DOUBLE_PRECISION)
- *v = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]);
-#else
- *v = sqrtf(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]);
-#endif
-}
-
-void un_m_magnitude_sqr2r(real *v, real *a) {
- *v = a[0] * a[0] + a[1] * a[1];
-}
-
-void un_m_magnitude_sqr3r(real *v, real *a) {
- *v = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
-}
-
-void un_m_magnitude_sqr4r(real *v, real *a) {
- *v = a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3];
-}
-
-void un_m_distance2r(real *v, real *a, real *b) {
- real f[2];
- un_m_sub2r(f, b, a);
-#if defined(UN_DOUBLE_PRECISION)
- *v = sqrt(f[0] * f[0] + f[1] * f[1]);
-#else
- *v = sqrtf(f[0] * f[0] + f[1] * f[1]);
-#endif
-}
-
-void un_m_distance3r(real *v, real *a, real *b) {
- real f[3];
- un_m_sub3r(f, b, a);
-#if defined(UN_DOUBLE_PRECISION)
- *v = sqrt(f[0] * f[0] + f[1] * f[1] + f[2] * f[2]);
-#else
- *v = sqrtf(f[0] * f[0] + f[1] * f[1] + f[2] * f[2]);
-#endif
-}
-
-void un_m_distance4r(real *v, real *a, real *b) {
- real f[4];
- un_m_sub4r(f, b, a);
-#if defined(UN_DOUBLE_PRECISION)
- *v = sqrt(f[0] * f[0] + f[1] * f[1] + f[2] * f[2] + f[3] * f[3]);
-#else
- *v = sqrtf(f[0] * f[0] + f[1] * f[1] + f[2] * f[2] + f[3] * f[3]);
-#endif
-}
-
-void un_m_distance_sqr2r(real *v, real *a, real *b) {
- real f[2];
- un_m_sub2r(f, b, a);
- *v = f[0] * f[0] + f[1] * f[1];
-}
-
-void un_m_distance_sqr3r(real *v, real *a, real *b) {
- real f[3];
- un_m_sub3r(f, b, a);
- *v = f[0] * f[0] + f[1] * f[1] + f[2] * f[2];
-}
-
-void un_m_distance_sqr4r(real *v, real *a, real *b) {
- real f[4];
- un_m_sub4r(f, b, a);
- *v = f[0] * f[0] + f[1] * f[1] + f[2] * f[2] + f[3] * f[3];
-}
-
-void un_m_normalize2r(real *v, real *a) {
- real f;
- un_m_magnitude2r(&f, a);
- v[0] = a[0] / f;
- v[1] = a[1] / f;
-}
-
-void un_m_normalize3r(real *v, real *a) {
- real f;
- un_m_magnitude3r(&f, a);
- v[0] = a[0] / f;
- v[1] = a[1] / f;
- v[2] = a[2] / f;
-}
-
-void un_m_normalize4r(real *v, real *a) {
- real f;
- un_m_magnitude4r(&f, a);
- v[0] = a[0] / f;
- v[1] = a[1] / f;
- v[2] = a[2] / f;
- v[3] = a[3] / f;
-}
-
-void un_m_project2r(real *v, real *a, real *onto) {
- real dot, magn, scale;
-
- un_m_dot2r(&dot, a, onto);
- un_m_magnitude_sqr2r(&magn, onto);
-
-
-#if defined(UN_DOUBLE_PRECISION)
- if (magn < EPSILON_D) {
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
- return;
- }
-#else
- if (magn < EPSILON) {
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
- return;
- }
-#endif
-
- scale = dot / magn;
- v[0] = onto[0] * scale;
- v[1] = onto[1] * scale;
-}
-
-void un_m_project3r(real *v, real *a, real *onto) {
- real dot, magn, scale;
-
- un_m_dot3r(&dot, a, onto);
- un_m_magnitude_sqr3r(&magn, onto);
-
-#if defined(UN_DOUBLE_PRECISION)
- if (magn < EPSILON_D) {
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
- return;
- }
-#else
- if (magn < EPSILON) {
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
- return;
- }
-#endif
-
- scale = dot / magn;
- v[0] = onto[0] * scale;
- v[1] = onto[1] * scale;
- v[2] = onto[2] * scale;
-}
-
-void un_m_project4r(real *v, real *a, real *onto) {
- real dot, magn, scale;
-
- un_m_dot4r(&dot, a, onto);
- un_m_magnitude_sqr4r(&magn, onto);
-
-#if defined(UN_DOUBLE_PRECISION)
- if (magn < EPSILON_D) {
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
- return;
- }
-#else
- if (magn < EPSILON) {
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
- return;
- }
-#endif
-
- scale = dot / magn;
- v[0] = onto[0] * scale;
- v[1] = onto[1] * scale;
- v[2] = onto[2] * scale;
- v[3] = onto[3] * scale;
-}
-
-void un_m_reflect2r(real *v, real *a, real *normal) {
- real dot;
-
- un_m_dot2r(&dot, a, normal);
- un_m_mul_scalar2r(v, normal, 2.0 * dot);
- un_m_sub2r(v, v, a);
-}
-
-void un_m_reflect3r(real *v, real *a, real *normal) {
- real dot;
-
- un_m_dot3r(&dot, a, normal);
- un_m_mul_scalar3r(v, normal, 2.0 * dot);
- un_m_sub3r(v, v, a);
-}
-
-void un_m_reflect4r(real *v, real *a, real *normal) {
- real dot;
-
- un_m_dot4r(&dot, a, normal);
- un_m_mul_scalar4r(v, normal, 2.0 * dot);
- un_m_sub4r(v, v, a);
-}
diff --git a/src/un_wstrings.c b/src/un_wstrings.c
new file mode 100644
index 0000000..601c809
--- /dev/null
+++ b/src/un_wstrings.c
@@ -0,0 +1,66 @@
+#if defined(OS_WINDOWS)
+wchar* un_wstring_from_string(String utf8_string, Allocator alloc) {
+ return un_wstring_from_cstring(un_string_to_cstring(utf8_string, un_allocator_get_temporary()), alloc);
+}
+
+wchar* un_wstring_from_cstring(u8 *utf8_string, Allocator alloc) {
+ u32 error_code, buffer_size, wrote_chars;
+ wchar *string_buffer;
+ assert(utf8_string != NULL);
+
+ buffer_size = MultiByteToWideChar(
+ CP_UTF8,
+ 0, // or MB_PRECOMPOSED
+ (LPCCH)utf8_string,
+ -1,
+ NULL,
+ 0
+ );
+
+ if (!buffer_size) {
+ error_code = GetLastError();
+
+ switch (error_code) {
+ case ERROR_NO_UNICODE_TRANSLATION: return NULL; break;
+ default:
+ assert(false);
+ break;
+ }
+
+ return NULL;
+ }
+
+ string_buffer = un_memory_alloc(sizeof(wchar) * buffer_size, alloc);
+
+ if (string_buffer == NULL) {
+ return NULL;
+ }
+
+ wrote_chars = MultiByteToWideChar(
+ CP_UTF8,
+ 0, // or MB_PRECOMPOSED
+ (LPCCH)utf8_string,
+ -1,
+ (LPWSTR)string_buffer,
+ buffer_size
+ );
+
+ assert(wrote_chars == buffer_size);
+
+ return string_buffer;
+}
+#else
+
+wchar* un_wstring_from_string(String utf8_string, Allocator alloc) {
+ UNUSED(utf8_string);
+ UNUSED(alloc);
+ __TRAP();
+}
+
+wchar* un_wstring_from_cstring(u8 *utf8_string, Allocator alloc) {
+ UNUSED(utf8_string);
+ UNUSED(alloc);
+ __TRAP();
+}
+
+#endif
diff --git a/src/ungrateful.c b/src/ungrateful.c
index 61d8185..5031a45 100644
--- a/src/ungrateful.c
+++ b/src/ungrateful.c
@@ -1,13 +1,16 @@
#include "ungrateful.h"
+#if defined(OS_WINDOWS)
+#include <windows.h>
+#elif defined(OS_LINUX)
+#endif
+
#include "un_memory.c"
#include "un_strings.c"
+#include "un_wstrings.c"
#include "un_list.c"
#include "un_math.c"
#include "un_vec.c"
#include "un_vecd.c"
-#include "un_vecr.c"
-
-#include "un_splines.c"
diff --git a/src/ungrateful.h b/src/ungrateful.h
index bbbea47..82152fa 100644
--- a/src/ungrateful.h
+++ b/src/ungrateful.h
@@ -61,6 +61,7 @@
#include <limits.h>
#include <assert.h>
#include <math.h>
+#include <wchar.h>
#define UNUSED(x) (void)(x)
@@ -71,6 +72,7 @@
#define UN_MAX(a, b) (a) > (b) ? (a) : (b)
#define UN_MIN(a, b) (a) < (b) ? (a) : (b)
+#define UN_TODO(msg) assert((msg, false))
#define UN_CSTR (u8*)
#define UN_STR(cstr) un_string_from_cstring(UN_CSTR cstr)
#define CSTR (char*)
@@ -97,19 +99,21 @@ typedef int8_t b8;
typedef float f32;
typedef double f64;
-#ifndef PI
+typedef wchar_t wchar;
+
+#if !defined(PI)
# define PI 3.14159265358979323846f
#endif
-#ifndef EPSILON
+#if !defined(EPSILON)
# define EPSILON 0.000001f
#endif
-#ifndef DEG2RAD
+#if !defined(DEG2RAD)
# define DEG2RAD (PI/180.0f)
#endif
-#ifndef RAD2DEG
+#if !defined(RAD2DEG)
# define RAD2DEG (180.0f/PI)
#endif
@@ -119,18 +123,18 @@ typedef double f64;
typedef float real;
#endif // UN_DOUBLE_PRECISION
-#ifndef PI_D
+#if !defined(PI_D)
# define PI_D 3.14159265358979323846
#endif
-#ifndef EPSILON_D
+#if !defined(EPSILON_D)
# define EPSILON_D 0.000000000000001
#endif
-#ifndef DEG2RAD_D
+#if !defined(DEG2RAD_D)
# define DEG2RAD_D (PI/180.0)
#endif
-#ifndef RAD2DEG_D
+#if !defined(RAD2DEG_D)
# define RAD2DEG_D (180.0/PI)
#endif
@@ -143,7 +147,6 @@ typedef double f64;
typedef enum {
UN_ALLOC_MSG_ALLOCATE,
- UN_ALLOC_MSG_REALLOCATE,
UN_ALLOC_MSG_FREE,
UN_ALLOC_MSG_SELF_DELETE,
} Allocator_Message;
@@ -158,15 +161,15 @@ typedef struct {
void *data;
} Allocator;
-// extern Allocator un_allocator_create_heap(s64 chunk_size); /* ... for large things */
-extern Allocator un_allocator_create_arena(u64 initial_size); /* Grouping allocator, that will recursively grow */
+// extern Allocator un_allocator_create_heap(s64 chunk_size); /* ... for large things. */
+extern Allocator un_allocator_create_arena(u64 initial_size); /* Grouping allocator, that will recursively grow. */
+extern Allocator un_allocator_create_wrapper(Allocator target); /* Allocator for debug purposes. */
extern Allocator un_allocator_get_standard(void);
extern Allocator un_allocator_get_temporary(void);
extern void *un_memory_alloc(u64 size, Allocator alloc);
-extern void *un_memory_realloc(void *ptr, u64 size, Allocator alloc);
-extern void *un_memory_free(void *ptr, Allocator alloc);
+extern void un_memory_free(void *ptr, Allocator alloc);
extern void un_memory_destroy(Allocator *alloc);
extern void un_memory_set(u8 *dest, u8 value, u64 size);
@@ -176,6 +179,8 @@ extern s32 un_memory_compare(u8 *left, u8 *right, u64 size); /* checks for ever
/* ---- Generic list structure ---- */
+#define UN_LIST_STANDARD_CAPACITY UN_KB(1)
+
typedef struct {
u64 count;
u64 capacity;
@@ -185,7 +190,7 @@ typedef struct {
} List;
extern List un_list_create(u64 start_capacity, u64 element_size, Allocator alloc);
-extern void un_list_destroy(List *list);
+extern void un_list_destroy(List *list, b32 delete_allocator);
extern List un_list_clone(List *list, Allocator alloc);
extern b32 un_list_append(List *list, void *data); /* Returns true if succeed. */
@@ -228,202 +233,304 @@ extern s64 un_string_index_of_last(String input, u8 value);
extern String un_string_format(Allocator alloc, String buffer, ...);
extern String un_string_vformat(Allocator alloc, String buffer, va_list args);
+/* ---- wide strings API ---- */
+
+extern wchar* un_wstring_from_string(String utf8_string, Allocator alloc);
+extern wchar* un_wstring_from_cstring(u8 *utf8_string, Allocator alloc);
+
/* ---- math, and vecmath ---- */
-real un_m_lerpr(real a, real b, real t);
+#if defined(UN_DOUBLE_PRECISION)
+#define un_m_lerpr un_m_lerpd
+#else
+#define un_m_lerpr un_m_lerpf
+#endif
+
f32 un_m_lerpf(f32 a, f32 b, f32 t);
f64 un_m_lerpd(f64 a, f64 b, f64 t);
/* 2d f32 */
-void un_m_add2f(f32 *v, f32 *a, f32 *b);
-void un_m_sub2f(f32 *v, f32 *a, f32 *b);
-void un_m_add_scalar2f(f32 *v, f32 *a, f32 scalar);
-void un_m_sub_scalar2f(f32 *v, f32 *a, f32 scalar);
-void un_m_mul_scalar2f(f32 *v, f32 *a, f32 scalar);
-void un_m_div_scalar2f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_add2f(f32 *v, f32 *a, f32 *b);
+extern void un_m_sub2f(f32 *v, f32 *a, f32 *b);
+extern void un_m_add_scalar2f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_sub_scalar2f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_mul_scalar2f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_div_scalar2f(f32 *v, f32 *a, f32 scalar);
-void un_m_dot2f(f32 *v, f32 *a, f32 *b);
-void un_m_hadamard2f(f32 *v, f32 *a, f32 *b);
-void un_m_project2f(f32 *v, f32 *a, f32 *onto);
-void un_m_reflect2f(f32 *v, f32 *a, f32 *normal);
-void un_m_cross2f(f32 *v, f32 *a);
+extern void un_m_dot2f(f32 *v, f32 *a, f32 *b);
+extern void un_m_hadamard2f(f32 *v, f32 *a, f32 *b);
+extern void un_m_project2f(f32 *v, f32 *a, f32 *onto);
+extern void un_m_reflect2f(f32 *v, f32 *a, f32 *normal);
+extern void un_m_cross2f(f32 *v, f32 *a);
-void un_m_normalize2f(f32 *v, f32 *a);
-void un_m_magnitude2f(f32 *v, f32 *a);
-void un_m_magnitude_sqr2f(f32 *v, f32 *a);
-void un_m_distance2f(f32 *v, f32 *a, f32 *b);
-void un_m_distance_sqr2f(f32 *v, f32 *a, f32 *b);
+extern void un_m_normalize2f(f32 *v, f32 *a);
+extern void un_m_magnitude2f(f32 *v, f32 *a);
+extern void un_m_magnitude_sqr2f(f32 *v, f32 *a);
+extern void un_m_distance2f(f32 *v, f32 *a, f32 *b);
+extern void un_m_distance_sqr2f(f32 *v, f32 *a, f32 *b);
/* 3d f32 */
-void un_m_add3f(f32 *v, f32 *a, f32 *b);
-void un_m_sub3f(f32 *v, f32 *a, f32 *b);
-void un_m_add_scalar3f(f32 *v, f32 *a, f32 scalar);
-void un_m_sub_scalar3f(f32 *v, f32 *a, f32 scalar);
-void un_m_mul_scalar3f(f32 *v, f32 *a, f32 scalar);
-void un_m_div_scalar3f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_add3f(f32 *v, f32 *a, f32 *b);
+extern void un_m_sub3f(f32 *v, f32 *a, f32 *b);
+extern void un_m_add_scalar3f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_sub_scalar3f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_mul_scalar3f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_div_scalar3f(f32 *v, f32 *a, f32 scalar);
-void un_m_dot3f(f32 *v, f32 *a, f32 *b);
-void un_m_hadamard3f(f32 *v, f32 *a, f32 *b);
-void un_m_project3f(f32 *v, f32 *a, f32 *onto);
-void un_m_reflect3f(f32 *v, f32 *a, f32 *normal);
-void un_m_cross3f(f32 *v, f32 *a, f32 *b);
+extern void un_m_dot3f(f32 *v, f32 *a, f32 *b);
+extern void un_m_hadamard3f(f32 *v, f32 *a, f32 *b);
+extern void un_m_project3f(f32 *v, f32 *a, f32 *onto);
+extern void un_m_reflect3f(f32 *v, f32 *a, f32 *normal);
+extern void un_m_cross3f(f32 *v, f32 *a, f32 *b);
-void un_m_normalize3f(f32 *v, f32 *a);
-void un_m_magnitude3f(f32 *v, f32 *a);
-void un_m_magnitude_sqr3f(f32 *v, f32 *a);
-void un_m_distance3f(f32 *v, f32 *a, f32 *b);
-void un_m_distance_sqr3f(f32 *v, f32 *a, f32 *b);
+extern void un_m_normalize3f(f32 *v, f32 *a);
+extern void un_m_magnitude3f(f32 *v, f32 *a);
+extern void un_m_magnitude_sqr3f(f32 *v, f32 *a);
+extern void un_m_distance3f(f32 *v, f32 *a, f32 *b);
+extern void un_m_distance_sqr3f(f32 *v, f32 *a, f32 *b);
/* 4d f32 */
-void un_m_add4f(f32 *v, f32 *a, f32 *b);
-void un_m_sub4f(f32 *v, f32 *a, f32 *b);
-void un_m_add_scalar4f(f32 *v, f32 *a, f32 scalar);
-void un_m_sub_scalar4f(f32 *v, f32 *a, f32 scalar);
-void un_m_mul_scalar4f(f32 *v, f32 *a, f32 scalar);
-void un_m_div_scalar4f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_add4f(f32 *v, f32 *a, f32 *b);
+extern void un_m_sub4f(f32 *v, f32 *a, f32 *b);
+extern void un_m_add_scalar4f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_sub_scalar4f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_mul_scalar4f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_div_scalar4f(f32 *v, f32 *a, f32 scalar);
-void un_m_dot4f(f32 *v, f32 *a, f32 *b);
-void un_m_hadamard4f(f32 *v, f32 *a, f32 *b);
-void un_m_project4f(f32 *v, f32 *a, f32 *onto);
-void un_m_reflect4f(f32 *v, f32 *a, f32 *normal);
+extern void un_m_dot4f(f32 *v, f32 *a, f32 *b);
+extern void un_m_hadamard4f(f32 *v, f32 *a, f32 *b);
+extern void un_m_project4f(f32 *v, f32 *a, f32 *onto);
+extern void un_m_reflect4f(f32 *v, f32 *a, f32 *normal);
-void un_m_normalize4f(f32 *v, f32 *a);
-void un_m_magnitude4f(f32 *v, f32 *a);
-void un_m_magnitude_sqr4f(f32 *v, f32 *a);
-void un_m_distance4f(f32 *v, f32 *a, f32 *b);
-void un_m_distance_sqr4f(f32 *v, f32 *a, f32 *b);
+extern void un_m_normalize4f(f32 *v, f32 *a);
+extern void un_m_magnitude4f(f32 *v, f32 *a);
+extern void un_m_magnitude_sqr4f(f32 *v, f32 *a);
+extern void un_m_distance4f(f32 *v, f32 *a, f32 *b);
+extern void un_m_distance_sqr4f(f32 *v, f32 *a, f32 *b);
/* 2d f64 */
-void un_m_add2d(f64 *v, f64 *a, f64 *b);
-void un_m_sub2d(f64 *v, f64 *a, f64 *b);
+extern void un_m_add2d(f64 *v, f64 *a, f64 *b);
+extern void un_m_sub2d(f64 *v, f64 *a, f64 *b);
-void un_m_add_scalar2d(f64 *v, f64 *a, f64 scalar);
-void un_m_sub_scalar2d(f64 *v, f64 *a, f64 scalar);
-void un_m_mul_scalar2d(f64 *v, f64 *a, f64 scalar);
-void un_m_div_scalar2d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_add_scalar2d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_sub_scalar2d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_mul_scalar2d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_div_scalar2d(f64 *v, f64 *a, f64 scalar);
-void un_m_dot2d(f64 *v, f64 *a, f64 *b);
-void un_m_hadamard2d(f64 *v, f64 *a, f64 *b);
-void un_m_project2d(f64 *v, f64 *a, f64 *onto);
-void un_m_reflect2d(f64 *v, f64 *a, f64 *normal);
-void un_m_cross2d(f64 *v, f64 *a);
+extern void un_m_dot2d(f64 *v, f64 *a, f64 *b);
+extern void un_m_hadamard2d(f64 *v, f64 *a, f64 *b);
+extern void un_m_project2d(f64 *v, f64 *a, f64 *onto);
+extern void un_m_reflect2d(f64 *v, f64 *a, f64 *normal);
+extern void un_m_cross2d(f64 *v, f64 *a);
-void un_m_normalize2d(f64 *v, f64 *a);
-void un_m_magnitude2d(f64 *v, f64 *a);
-void un_m_magnitude_sqr2d(f64 *v, f64 *a);
-void un_m_distance2d(f64 *v, f64 *a, f64 *b);
-void un_m_distance_sqr2d(f64 *v, f64 *a, f64 *b);
+extern void un_m_normalize2d(f64 *v, f64 *a);
+extern void un_m_magnitude2d(f64 *v, f64 *a);
+extern void un_m_magnitude_sqr2d(f64 *v, f64 *a);
+extern void un_m_distance2d(f64 *v, f64 *a, f64 *b);
+extern void un_m_distance_sqr2d(f64 *v, f64 *a, f64 *b);
/* 3d f64 */
-void un_m_add3d(f64 *v, f64 *a, f64 *b);
-void un_m_sub3d(f64 *v, f64 *a, f64 *b);
+extern void un_m_add3d(f64 *v, f64 *a, f64 *b);
+extern void un_m_sub3d(f64 *v, f64 *a, f64 *b);
-void un_m_add_scalar3d(f64 *v, f64 *a, f64 scalar);
-void un_m_sub_scalar3d(f64 *v, f64 *a, f64 scalar);
-void un_m_mul_scalar3d(f64 *v, f64 *a, f64 scalar);
-void un_m_div_scalar3d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_add_scalar3d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_sub_scalar3d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_mul_scalar3d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_div_scalar3d(f64 *v, f64 *a, f64 scalar);
-void un_m_dot3d(f64 *v, f64 *a, f64 *b);
-void un_m_hadamard3d(f64 *v, f64 *a, f64 *b);
-void un_m_project3d(f64 *v, f64 *a, f64 *onto);
-void un_m_reflect3d(f64 *v, f64 *a, f64 *normal);
-void un_m_cross3d(f64 *v, f64 *a, f64 *b);
+extern void un_m_dot3d(f64 *v, f64 *a, f64 *b);
+extern void un_m_hadamard3d(f64 *v, f64 *a, f64 *b);
+extern void un_m_project3d(f64 *v, f64 *a, f64 *onto);
+extern void un_m_reflect3d(f64 *v, f64 *a, f64 *normal);
+extern void un_m_cross3d(f64 *v, f64 *a, f64 *b);
-void un_m_normalize3d(f64 *v, f64 *a);
-void un_m_magnitude3d(f64 *v, f64 *a);
-void un_m_magnitude_sqr3d(f64 *v, f64 *a);
-void un_m_distance3d(f64 *v, f64 *a, f64 *b);
-void un_m_distance_sqr3d(f64 *v, f64 *a, f64 *b);
+extern void un_m_normalize3d(f64 *v, f64 *a);
+extern void un_m_magnitude3d(f64 *v, f64 *a);
+extern void un_m_magnitude_sqr3d(f64 *v, f64 *a);
+extern void un_m_distance3d(f64 *v, f64 *a, f64 *b);
+extern void un_m_distance_sqr3d(f64 *v, f64 *a, f64 *b);
/* 4d f64 */
-void un_m_add4d(f64 *v, f64 *a, f64 *b);
-void un_m_sub4d(f64 *v, f64 *a, f64 *b);
+extern void un_m_add4d(f64 *v, f64 *a, f64 *b);
+extern void un_m_sub4d(f64 *v, f64 *a, f64 *b);
+
+extern void un_m_add_scalar4d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_sub_scalar4d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_mul_scalar4d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_div_scalar4d(f64 *v, f64 *a, f64 scalar);
-void un_m_add_scalar4d(f64 *v, f64 *a, f64 scalar);
-void un_m_sub_scalar4d(f64 *v, f64 *a, f64 scalar);
-void un_m_mul_scalar4d(f64 *v, f64 *a, f64 scalar);
-void un_m_div_scalar4d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_dot4d(f64 *v, f64 *a, f64 *b);
+extern void un_m_hadamard4d(f64 *v, f64 *a, f64 *b);
+extern void un_m_project4d(f64 *v, f64 *a, f64 *onto);
+extern void un_m_reflect4d(f64 *v, f64 *a, f64 *normal);
-void un_m_dot4d(f64 *v, f64 *a, f64 *b);
-void un_m_hadamard4d(f64 *v, f64 *a, f64 *b);
-void un_m_project4d(f64 *v, f64 *a, f64 *onto);
-void un_m_reflect4d(f64 *v, f64 *a, f64 *normal);
+extern void un_m_normalize4d(f64 *v, f64 *a);
+extern void un_m_magnitude4d(f64 *v, f64 *a);
+extern void un_m_magnitude_sqr4d(f64 *v, f64 *a);
+extern void un_m_distance4d(f64 *v, f64 *a, f64 *b);
+extern void un_m_distance_sqr4d(f64 *v, f64 *a, f64 *b);
-void un_m_normalize4d(f64 *v, f64 *a);
-void un_m_magnitude4d(f64 *v, f64 *a);
-void un_m_magnitude_sqr4d(f64 *v, f64 *a);
-void un_m_distance4d(f64 *v, f64 *a, f64 *b);
-void un_m_distance_sqr4d(f64 *v, f64 *a, f64 *b);
+#if defined(UN_DOUBLE_PRECISION)
/* 2d real */
-void un_m_add2r(real *v, real *a, real *b);
-void un_m_sub2r(real *v, real *a, real *b);
+#define un_m_add2r un_m_add2d
+#define un_m_sub2r un_m_sub2d
-void un_m_add_scalar2r(real *v, real *a, real scalar);
-void un_m_sub_scalar2r(real *v, real *a, real scalar);
-void un_m_mul_scalar2r(real *v, real *a, real scalar);
-void un_m_div_scalar2r(real *v, real *a, real scalar);
+#define un_m_add_scalar2r un_m_add_scalar2d
+#define un_m_sub_scalar2r un_m_sub_scalar2d
+#define un_m_mul_scalar2r un_m_mul_scalar2d
+#define un_m_div_scalar2r un_m_div_scalar2d
-void un_m_dot2r(real *v, real *a, real *b);
-void un_m_hadamard2r(real *v, real *a, real *b);
-void un_m_project2r(real *v, real *a, real *onto);
-void un_m_reflect2r(real *v, real *a, real *normal);
-void un_m_cross2r(real *v, real *a);
+#define un_m_dot2r un_m_dot2d
+#define un_m_hadamard2r un_m_hadamard2d
+#define un_m_project2r un_m_project2d
+#define un_m_reflect2r un_m_reflect2d
+#define un_m_cross2r un_m_cross2d
-void un_m_normalize2r(real *v, real *a);
-void un_m_magnitude2r(real *v, real *a);
-void un_m_magnitude_sqr2r(real *v, real *a);
-void un_m_distance2r(real *v, real *a, real *b);
-void un_m_distance_sqr2r(real *v, real *a, real *b);
+#define un_m_normalize2r un_m_normalize2d
+#define un_m_magnitude2r un_m_magnitude2d
+#define un_m_magnitude_sqr2r un_m_magnitude_sqr2d
+#define un_m_distance2r un_m_distance2d
+#define un_m_distance_sqr2r un_m_distance_sqr2d
/* 3d real */
-void un_m_add3r(real *v, real *a, real *b);
-void un_m_sub3r(real *v, real *a, real *b);
+#define un_m_add3r un_m_add3d
+#define un_m_sub3r un_m_sub3d
-void un_m_add_scalar3r(real *v, real *a, real scalar);
-void un_m_sub_scalar3r(real *v, real *a, real scalar);
-void un_m_mul_scalar3r(real *v, real *a, real scalar);
-void un_m_div_scalar3r(real *v, real *a, real scalar);
+#define un_m_add_scalar3r un_m_add_scalar3d
+#define un_m_sub_scalar3r un_m_sub_scalar3d
+#define un_m_mul_scalar3r un_m_mul_scalar3d
+#define un_m_div_scalar3r un_m_div_scalar3d
-void un_m_dot3r(real *v, real *a, real *b);
-void un_m_hadamard3r(real *v, real *a, real *b);
-void un_m_project3r(real *v, real *a, real *onto);
-void un_m_reflect3r(real *v, real *a, real *normal);
-void un_m_cross3r(real *v, real *a, real *b);
+#define un_m_dot3r un_m_dot3d
+#define un_m_hadamard3r un_m_hadamard3d
+#define un_m_project3r un_m_project3d
+#define un_m_reflect3r un_m_reflect3d
+#define un_m_cross3r un_m_cross3d
-void un_m_normalize3r(real *v, real *a);
-void un_m_magnitude3r(real *v, real *a);
-void un_m_magnitude_sqr3r(real *v, real *a);
-void un_m_distance3r(real *v, real *a, real *b);
-void un_m_distance_sqr3r(real *v, real *a, real *b);
+#define un_m_normalize3r un_m_normalize3d
+#define un_m_magnitude3r un_m_magnitude3d
+#define un_m_magnitude_sqr3r un_m_magnitude_sqr3d
+#define un_m_distance3r un_m_distance3d
+#define un_m_distance_sqr3r un_m_distance_sqr3d
/* 4d real */
-void un_m_add4r(real *v, real *a, real *b);
-void un_m_sub4r(real *v, real *a, real *b);
+#define un_m_add4r un_m_add4d
+#define un_m_sub4r un_m_sub4d
-void un_m_add_scalar4r(real *v, real *a, real scalar);
-void un_m_sub_scalar4r(real *v, real *a, real scalar);
-void un_m_mul_scalar4r(real *v, real *a, real scalar);
-void un_m_div_scalar4r(real *v, real *a, real scalar);
+#define un_m_add_scalar4r un_m_add_scalar4d
+#define un_m_sub_scalar4r un_m_sub_scalar4d
+#define un_m_mul_scalar4r un_m_mul_scalar4d
+#define un_m_div_scalar4r un_m_div_scalar4d
-void un_m_dot4r(real *v, real *a, real *b);
-void un_m_hadamard4r(real *v, real *a, real *b);
-void un_m_project4r(real *v, real *a, real *onto);
-void un_m_reflect4r(real *v, real *a, real *normal);
+#define un_m_dot4r un_m_dot4d
+#define un_m_hadamard4r un_m_hadamard4d
+#define un_m_project4r un_m_project4d
+#define un_m_reflect4r un_m_reflect4d
-void un_m_normalize4r(real *v, real *a);
-void un_m_magnitude4r(real *v, real *a);
-void un_m_magnitude_sqr4r(real *v, real *a);
-void un_m_distance4r(real *v, real *a, real *b);
-void un_m_distance_sqr4r(real *v, real *a, real *b);
+#define un_m_normalize4r un_m_normalize4d
+#define un_m_magnitude4r un_m_magnitude4d
+#define un_m_magnitude_sqr4r un_m_magnitude_sqr4d
+#define un_m_distance4r un_m_distance4d
+#define un_m_distance_sqr4r un_m_distance_sqr4d
-/* ---- splines ---- */
+#else
+
+/* 2d real */
+#define un_m_add2r un_m_add2f
+#define un_m_sub2r un_m_sub2f
+
+#define un_m_add_scalar2r un_m_add_scalar2f
+#define un_m_sub_scalar2r un_m_sub_scalar2f
+#define un_m_mul_scalar2r un_m_mul_scalar2f
+#define un_m_div_scalar2r un_m_div_scalar2f
+
+#define un_m_dot2r un_m_dot2f
+#define un_m_hadamard2r un_m_hadamard2f
+#define un_m_project2r un_m_project2f
+#define un_m_reflect2r un_m_reflect2f
+#define un_m_cross2r un_m_cross2f
+
+#define un_m_normalize2r un_m_normalize2f
+#define un_m_magnitude2r un_m_magnitude2f
+#define un_m_magnitude_sqr2r un_m_magnitude_sqr2f
+#define un_m_distance2r un_m_distance2f
+#define un_m_distance_sqr2r un_m_distance_sqr2f
+
+/* 3d real */
+#define un_m_add3r un_m_add3f
+#define un_m_sub3r un_m_sub3f
+
+#define un_m_add_scalar3r un_m_add_scalar3f
+#define un_m_sub_scalar3r un_m_sub_scalar3f
+#define un_m_mul_scalar3r un_m_mul_scalar3f
+#define un_m_div_scalar3r un_m_div_scalar3f
+
+#define un_m_dot3r un_m_dot3f
+#define un_m_hadamard3r un_m_hadamard3f
+#define un_m_project3r un_m_project3f
+#define un_m_reflect3r un_m_reflect3f
+#define un_m_cross3r un_m_cross3f
+
+#define un_m_normalize3r un_m_normalize3f
+#define un_m_magnitude3r un_m_magnitude3f
+#define un_m_magnitude_sqr3r un_m_magnitude_sqr3f
+#define un_m_distance3r un_m_distance3f
+#define un_m_distance_sqr3r un_m_distance_sqr3f
+
+/* 4d real */
+#define un_m_add4r un_m_add4f
+#define un_m_sub4r un_m_sub4f
+
+#define un_m_add_scalar4r un_m_add_scalar4f
+#define un_m_sub_scalar4r un_m_sub_scalar4f
+#define un_m_mul_scalar4r un_m_mul_scalar4f
+#define un_m_div_scalar4r un_m_div_scalar4f
-void un_m_bezierr(real *v, real a, real q0, real q1, real b, real t);
-void un_m_bezier2r(real *v, real *a, real *q0, real *q1, real *b, real t);
-void un_m_bezier3r(real *v, real *a, real *q0, real *q1, real *b, real t);
-void un_m_bezier4r(real *v, real *a, real *q0, real *q1, real *b, real t);
+#define un_m_dot4r un_m_dot4f
+#define un_m_hadamard4r un_m_hadamard4f
+#define un_m_project4r un_m_project4f
+#define un_m_reflect4r un_m_reflect4f
+
+#define un_m_normalize4r un_m_normalize4f
+#define un_m_magnitude4r un_m_magnitude4f
+#define un_m_magnitude_sqr4r un_m_magnitude_sqr4f
+#define un_m_distance4r un_m_distance4f
+#define un_m_distance_sqr4r un_m_distance_sqr4f
+
+#endif // UN_DOUBLE_PRECISION
+
+/* ---- complex ---- */
+
+#define un_m_complex_addf un_m_add2f
+#define un_m_complex_subf un_m_sub2f
+extern void un_m_complex_divf(f32 *v, f32 *a, f32 *b);
+extern void un_m_complex_mulf(f32 *v, f32 *a, f32 *b);
+
+#define un_m_complex_addd un_m_add2d
+#define un_m_complex_subd un_m_sub2d
+extern void un_m_complex_divd(f64 *v, f64 *a, f64 *b);
+extern void un_m_complex_muld(f64 *v, f64 *a, f64 *b);
+
+#define un_m_complex_magnitudef un_m_magnitude2f
+#define un_m_complex_magnituded un_m_magnitude2d
+
+#if defined(UN_DOUBLE_PRECISION)
+#define un_m_complex_addr un_m_complex_addd
+#define un_m_complex_subr un_m_complex_subd
+#define un_m_complex_divr un_m_complex_divd
+#define un_m_complex_mulr un_m_complex_muld
+#define un_m_complex_magnituder un_m_complex_magnituded
+#else
+#define un_m_complex_addr un_m_complex_addf
+#define un_m_complex_subr un_m_complex_subf
+#define un_m_complex_divr un_m_complex_divf
+#define un_m_complex_mulr un_m_complex_mulf
+#define un_m_complex_magnituder un_m_complex_magnitudef
+#endif // UN_DOUBLE_PRECISION
+
+/* ---- splines ---- */
void un_m_bezierf(f32 *v, f32 a, f32 q0, f32 q1, f32 b, f32 t);
void un_m_bezier2f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t);
@@ -435,28 +542,60 @@ void un_m_bezier2d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t);
void un_m_bezier3d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t);
void un_m_bezier4d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t);
+#if defined(UN_DOUBLE_PRECISION)
+#define un_m_bezierr un_m_bezierd
+#define un_m_bezier2r un_m_bezier2d
+#define un_m_bezier3r un_m_bezier3d
+#define un_m_bezier4r un_m_bezier4d
+#else
+#define un_m_bezierr un_m_bezierf
+#define un_m_bezier2r un_m_bezier2f
+#define un_m_bezier3r un_m_bezier3f
+#define un_m_bezier4r un_m_bezier4f
+#endif // UN_DOUBLE_PRECISION
+
/* ---- easing ---- */
-real un_m_ease_isiner(real t);
-real un_m_ease_iosiner(real t);
-real un_m_ease_osiner(real t);
-real un_m_ease_iquadr(real t);
-real un_m_ease_ioquadr(real t);
-real un_m_ease_oquadr(real t);
+extern f32 un_m_ease_isinef(f32 t);
+extern f32 un_m_ease_iosinef(f32 t);
+extern f32 un_m_ease_osinef(f32 t);
+extern f32 un_m_ease_iquadf(f32 t);
+extern f32 un_m_ease_ioquadf(f32 t);
+extern f32 un_m_ease_oquadf(f32 t);
+
+extern f64 un_m_ease_isined(f64 t);
+extern f64 un_m_ease_iosined(f64 t);
+extern f64 un_m_ease_osined(f64 t);
+extern f64 un_m_ease_iquadd(f64 t);
+extern f64 un_m_ease_ioquadd(f64 t);
+extern f64 un_m_ease_oquadd(f64 t);
+
+#if defined(UN_DOUBLE_PRECISION)
+#define un_m_ease_isiner un_m_ease_isined
+#define un_m_ease_iosiner un_m_ease_iosined
+#define un_m_ease_osiner un_m_ease_osined
+#define un_m_ease_iquadr un_m_ease_iquadd
+#define un_m_ease_ioquadr un_m_ease_ioquadd
+#define un_m_ease_oquadr un_m_ease_oquadd
+#else
+#define un_m_ease_isiner un_m_ease_isinef
+#define un_m_ease_iosiner un_m_ease_iosinef
+#define un_m_ease_osiner un_m_ease_osinef
+#define un_m_ease_iquadr un_m_ease_iquadf
+#define un_m_ease_ioquadr un_m_ease_ioquadf
+#define un_m_ease_oquadr un_m_ease_oquadf
+#endif // UN_DOUBLE_PRECISION
+
+/* --- matrix ----
+ * Convention of matrices!
+ * column-major matrices and all matrices are 4x4.
+ */
-f32 un_m_ease_isinef(f32 t);
-f32 un_m_ease_iosinef(f32 t);
-f32 un_m_ease_osinef(f32 t);
-f32 un_m_ease_iquadf(f32 t);
-f32 un_m_ease_ioquadf(f32 t);
-f32 un_m_ease_oquadf(f32 t);
+#define UN_MATRIX_SIZE (16)
+#define UN_MATRIX_STRIPE (4)
-f64 un_m_ease_isined(f64 t);
-f64 un_m_ease_iosined(f64 t);
-f64 un_m_ease_osined(f64 t);
-f64 un_m_ease_iquadd(f64 t);
-f64 un_m_ease_ioquadd(f64 t);
-f64 un_m_ease_oquadd(f64 t);
+extern void un_m_mat_mulf(f32 *v, f32 *left, f32 *right);
+extern void un_m_mat_identityf(f32 *v);
#if defined(__cplusplus)
}
diff --git a/tests/un/allocs.c b/tests/un/allocs.c
index 608d9f4..3348e70 100644
--- a/tests/un/allocs.c
+++ b/tests/un/allocs.c
@@ -36,4 +36,15 @@ int main(void) {
un_memory_destroy(&arena);
}
+
+ { // wrapper
+ Allocator wrapper = un_allocator_create_wrapper(un_allocator_create_arena(size));
+
+ for (i = 0; i < 1000; i++) {
+ value = un_memory_alloc(8, wrapper);
+ *value = 0xAC;
+ }
+
+ un_memory_destroy(&wrapper);
+ }
}
diff --git a/tests/un/lists.c b/tests/un/lists.c
index a8627ac..bacb358 100644
--- a/tests/un/lists.c
+++ b/tests/un/lists.c
@@ -2,22 +2,21 @@
int main(void) {
u64 i, v, times, size;
- List list;
- Allocator alloc;
+ List list = { 0 };
- size = 16;
+ size = UN_LIST_STANDARD_CAPACITY;
times = 4;
{
- alloc = un_allocator_get_standard();
- list = un_list_create(size, sizeof(u64), alloc);
+ list.alloc = un_allocator_get_temporary();
+ list.element_size = sizeof(u64);
assert(un_list_get(&list, 0) == NULL);
for (i = 0; i < size; i++) {
v = i * times;
- un_list_append(&list, (void *)(&v));
+ assert(un_list_append(&list, (void *)(&v)));
}
assert(*(u64*)un_list_get(&list, size - 1) == ((size - 1) * times));
@@ -31,20 +30,23 @@ int main(void) {
assert(*(u64*)un_list_get(&list, 0) == times);
un_list_remove(&list, list.count); // will be ignored
- un_list_remove(&list, list.count - 1);
+ assert(list.count == (size - 1));
+ un_list_remove(&list, list.count - 1);
assert(list.count == (size - 2));
for (i = 0; i < size; i++) {
v = i * times;
- un_list_append(&list, (void *)(&v));
+ assert(un_list_append(&list, (void *)(&v)));
}
assert(list.capacity == (size * 2));
- un_list_destroy(&list);
+ un_list_destroy(&list, true);
assert(list.data == NULL);
}
+
+ return 0;
}
diff --git a/tests/un/math.c b/tests/un/math.c
index eab0dcb..8b8df67 100644
--- a/tests/un/math.c
+++ b/tests/un/math.c
@@ -14,7 +14,7 @@ int main() {
assert(fabsf(f - 1.5f) < EPSILON);
d = un_m_lerpd(1.0, 2.0, 0.5);
- assert(fabs(d - 1.5) < 0.000001);
+ assert(fabs(d - 1.5) < EPSILON);
}
// Test Bezier curve functions
diff --git a/tests/un/mathd.c b/tests/un/mathd.c
index 3381dfb..829a4a6 100644
--- a/tests/un/mathd.c
+++ b/tests/un/mathd.c
@@ -276,5 +276,33 @@ int main() {
un_memory_set((void*)v, 0, sizeof(*v) * 4);
}
+ { // Complex
+ f64 v[2], a[2] = { 1, 2 }, b[2] = { 3, 4 }, c[2] = { 1, 0 }, d[3] = { 0, 1 };
+
+ un_m_complex_addd(v, a, b);
+ assert((v[0] - 4.0) < EPSILON);
+ assert((v[1] - 6.0) < EPSILON);
+ un_memory_set((void*)v, 0, sizeof(*v) * 2);
+
+ un_m_complex_subd(v, a, b);
+ assert((v[0] + 2.0) < EPSILON);
+ assert((v[1] + 2.0) < EPSILON);
+ un_memory_set((void*)v, 0, sizeof(*v) * 2);
+
+ un_m_complex_muld(v, a, b);
+ assert((v[0] + 5.0) < EPSILON);
+ assert((v[1] - 10.0) < EPSILON);
+ un_memory_set((void*)v, 0, sizeof(*v) * 2);
+
+ un_m_complex_divd(v, c, d);
+ assert(v[0] < EPSILON);
+ assert((v[1] + 1.0) < EPSILON);
+ un_memory_set((void*)v, 0, sizeof(*v) * 2);
+
+ un_m_complex_magnituded(v, c);
+ assert((v[0] - 1.0) < EPSILON);
+ un_memory_set((void*)v, 0, sizeof(*v) * 2);
+ }
+
return 0;
}
diff --git a/tests/un/mathf.c b/tests/un/mathf.c
index cd3a24f..2f95f40 100644
--- a/tests/un/mathf.c
+++ b/tests/un/mathf.c
@@ -276,5 +276,33 @@ int main() {
un_memory_set((void*)v, 0, sizeof(*v) * 4);
}
+ { // Complex
+ f32 v[2], a[2] = { 1, 2 }, b[2] = { 3, 4 }, c[2] = { 1, 0 }, d[3] = { 0, 1 };
+
+ un_m_complex_addf(v, a, b);
+ assert((v[0] - 4.0) < EPSILON);
+ assert((v[1] - 6.0) < EPSILON);
+ un_memory_set((void*)v, 0, sizeof(*v) * 2);
+
+ un_m_complex_subf(v, a, b);
+ assert((v[0] + 2.0) < EPSILON);
+ assert((v[1] + 2.0) < EPSILON);
+ un_memory_set((void*)v, 0, sizeof(*v) * 2);
+
+ un_m_complex_mulf(v, a, b);
+ assert((v[0] + 5.0) < EPSILON);
+ assert((v[1] - 10.0) < EPSILON);
+ un_memory_set((void*)v, 0, sizeof(*v) * 2);
+
+ un_m_complex_divf(v, c, d);
+ assert(v[0] < EPSILON);
+ assert((v[1] + 1.0) < EPSILON);
+ un_memory_set((void*)v, 0, sizeof(*v) * 2);
+
+ un_m_complex_magnitudef(v, c);
+ assert((v[0] - 1.0) < EPSILON);
+ un_memory_set((void*)v, 0, sizeof(*v) * 2);
+ }
+
return 0;
}
diff --git a/tests/un/mathr.c b/tests/un/mathr.c
deleted file mode 100644
index 05653b4..0000000
--- a/tests/un/mathr.c
+++ /dev/null
@@ -1,280 +0,0 @@
-#include <ungrateful.h>
-
-int main() {
- /* 2d */
- {
- real a[2] = {1.0, 2.0};
- real b[2] = {3.0, 4.0};
- real n[2] = {0.0, 1.0};
- real v[2];
-
- un_m_add2r(v, a, b);
- assert(fabs(v[0] - 4.0) < EPSILON);
- assert(fabs(v[1] - 6.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_sub2r(v, a, b);
- assert(fabs(v[0] + 2.0) < EPSILON);
- assert(fabs(v[1] + 2.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_add_scalar2r(v, a, 1);
- assert(fabs(v[0] - 2.0) < EPSILON);
- assert(fabs(v[1] - 3.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_sub_scalar2r(v, a, 1);
- assert(fabs(v[0]) < EPSILON);
- assert(fabs(v[1] - 1.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_mul_scalar2r(v, a, 2);
- assert(fabs(v[0] - 2.0) < EPSILON);
- assert(fabs(v[1] - 4.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_div_scalar2r(v, a, 2);
- assert(fabs(v[0] - 0.5) < EPSILON);
- assert(fabs(v[1] - 1.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_dot2r(v, a, b);
- assert(fabs(v[0] - 11.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_hadamard2r(v, a, b);
- assert(fabs(v[0] - 3.0) < EPSILON);
- assert(fabs(v[1] - 8.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_project2r(v, a, b);
- assert(fabs(v[0] - 1.32) < EPSILON);
- assert(fabs(v[1] - 1.76) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_cross2r(v, a);
- assert(fabs(v[0] - 2.0) < EPSILON);
- assert(fabs(v[1] + 1.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_magnitude2r(v, b);
- assert(fabs(v[0] - 5.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_magnitude_sqr2r(v, b);
- assert(fabs(v[0] - 25.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_distance2r(v, a, b);
- assert(fabs(v[0] - sqrt(8.0)) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_distance_sqr2r(v, a, b);
- assert(fabs(v[0] - 8.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_normalize2r(v, b);
- assert(fabs(v[0] - 0.6) < EPSILON);
- assert(fabs(v[1] - 0.8) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
-
- un_m_reflect2r(v, a, n);
- assert(fabs(v[0] + a[0]) < EPSILON);
- assert(fabs(v[1] - a[1]) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
- }
-
- /* 3d */
- {
- real a[3] = {1.0, 2.0, 3.0};
- real b[3] = {3.0, 4.0, 5.0};
- real n[3] = {0.0, 1.0, 0.0};
- real v[3];
-
- un_m_add3r(v, a, b);
- assert(fabs(v[0] - 4.0) < EPSILON);
- assert(fabs(v[1] - 6.0) < EPSILON);
- assert(fabs(v[2] - 8.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_sub3r(v, a, b);
- assert(fabs(v[0] + 2.0) < EPSILON);
- assert(fabs(v[1] + 2.0) < EPSILON);
- assert(fabs(v[2] + 2.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_add_scalar3r(v, a, 1);
- assert(fabs(v[0] - 2.0) < EPSILON);
- assert(fabs(v[1] - 3.0) < EPSILON);
- assert(fabs(v[2] - 4.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_sub_scalar3r(v, a, 1);
- assert(fabs(v[0]) < EPSILON);
- assert(fabs(v[1] - 1.0) < EPSILON);
- assert(fabs(v[2] - 2.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_mul_scalar3r(v, a, 2);
- assert(fabs(v[0] - 2.0) < EPSILON);
- assert(fabs(v[1] - 4.0) < EPSILON);
- assert(fabs(v[2] - 6.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_div_scalar3r(v, a, 2);
- assert(fabs(v[0] - 0.5) < EPSILON);
- assert(fabs(v[1] - 1.0) < EPSILON);
- assert(fabs(v[2] - 1.5) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_dot3r(v, a, b);
- assert(fabs(v[0] - 26.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_hadamard3r(v, a, b);
- assert(fabs(v[0] - 3.0) < EPSILON);
- assert(fabs(v[1] - 8.0) < EPSILON);
- assert(fabs(v[2] - 15.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_project3r(v, a, b);
- assert(fabs(v[0] - 1.56) < EPSILON);
- assert(fabs(v[1] - 2.08) < EPSILON);
- assert(fabs(v[2] - 2.6) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_cross3r(v, a, b);
- assert(fabs(v[0] + 2.0) < EPSILON);
- assert(fabs(v[1] - 4.0) < EPSILON);
- assert(fabs(v[2] + 2.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_magnitude3r(v, b);
- assert(fabs(v[0] - sqrt(50.0)) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_magnitude_sqr3r(v, b);
- assert(fabs(v[0] - 50.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_distance3r(v, a, b);
- assert(fabs(v[0] - sqrt(12.0)) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_distance_sqr3r(v, a, b);
- assert(fabs(v[0] - 12.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_normalize3r(v, b);
- assert(fabs(v[0] - 0.424264) < EPSILON);
- assert(fabs(v[1] - 0.565685) < EPSILON);
- assert(fabs(v[2] - 0.707107) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
-
- un_m_reflect3r(v, a, n);
- assert(fabs(v[0] + a[0]) < EPSILON);
- assert(fabs(v[1] - a[1]) < EPSILON);
- assert(fabs(v[2] + a[2]) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
- }
-
- /* 4d */
- {
- real a[4] = {1.0, 2.0, 3.0, 4.0};
- real b[4] = {3.0, 4.0, 5.0, 6.0};
- real n[4] = {0.0, 1.0, 0.0, 0.0};
- real v[4];
-
- un_m_add4r(v, a, b);
- assert(fabs(v[0] - 4.0) < EPSILON);
- assert(fabs(v[1] - 6.0) < EPSILON);
- assert(fabs(v[2] - 8.0) < EPSILON);
- assert(fabs(v[3] - 10.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
-
- un_m_sub4r(v, a, b);
- assert(fabs(v[0] + 2.0) < EPSILON);
- assert(fabs(v[1] + 2.0) < EPSILON);
- assert(fabs(v[2] + 2.0) < EPSILON);
- assert(fabs(v[3] + 2.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
-
- un_m_add_scalar4r(v, a, 1);
- assert(fabs(v[0] - 2.0) < EPSILON);
- assert(fabs(v[1] - 3.0) < EPSILON);
- assert(fabs(v[2] - 4.0) < EPSILON);
- assert(fabs(v[3] - 5.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
-
- un_m_sub_scalar4r(v, a, 1);
- assert(fabs(v[0]) < EPSILON);
- assert(fabs(v[1] - 1.0) < EPSILON);
- assert(fabs(v[2] - 2.0) < EPSILON);
- assert(fabs(v[3] - 3.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
-
- un_m_mul_scalar4r(v, a, 2);
- assert(fabs(v[0] - 2.0) < EPSILON);
- assert(fabs(v[1] - 4.0) < EPSILON);
- assert(fabs(v[2] - 6.0) < EPSILON);
- assert(fabs(v[3] - 8.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
-
- un_m_div_scalar4r(v, a, 2);
- assert(fabs(v[0] - 0.5) < EPSILON);
- assert(fabs(v[1] - 1.0) < EPSILON);
- assert(fabs(v[2] - 1.5) < EPSILON);
- assert(fabs(v[3] - 2.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
-
- un_m_dot4r(v, a, b);
- assert(fabs(v[0] - 50.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
-
- un_m_hadamard4r(v, a, b);
- assert(fabs(v[0] - 3.0) < EPSILON);
- assert(fabs(v[1] - 8.0) < EPSILON);
- assert(fabs(v[2] - 15.0) < EPSILON);
- assert(fabs(v[3] - 24.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
-
- un_m_project4r(v, a, b);
- assert(fabs(v[0] - 1.744186) < EPSILON);
- assert(fabs(v[1] - 2.325581) < EPSILON);
- assert(fabs(v[2] - 2.906976) < EPSILON);
- assert(fabs(v[3] - 3.488372) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
-
- un_m_magnitude4r(v, b);
- assert(fabs(v[0] - sqrt(86.0)) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
-
- un_m_magnitude_sqr4r(v, b);
- assert(fabs(v[0] - 86.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
-
- un_m_distance4r(v, a, b);
- assert(fabs(v[0] - 4.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
-
- un_m_distance_sqr4r(v, a, b);
- assert(fabs(v[0] - 16.0) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
-
- un_m_normalize4r(v, b);
- assert(fabs(v[0] - 0.323498) < EPSILON);
- assert(fabs(v[1] - 0.431331) < EPSILON);
- assert(fabs(v[2] - 0.539164) < EPSILON);
- assert(fabs(v[3] - 0.646997) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
-
- un_m_reflect4r(v, a, n);
- assert(fabs(v[0] + a[0]) < EPSILON);
- assert(fabs(v[1] - a[1]) < EPSILON);
- assert(fabs(v[2] + a[2]) < EPSILON);
- assert(fabs(v[3] + a[3]) < EPSILON);
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
- }
-
- return 0;
-}
diff --git a/tests/un/matrix.c b/tests/un/matrix.c
new file mode 100644
index 0000000..deb9e4c
--- /dev/null
+++ b/tests/un/matrix.c
@@ -0,0 +1,8 @@
+#include <ungrateful.h>
+
+int main() {
+ f32 output[UN_MATRIX_SIZE];
+ u64 i;
+
+ return 0;
+}
diff --git a/tests/un/strings.c b/tests/un/strings.c
index d49d525..87f1aed 100644
--- a/tests/un/strings.c
+++ b/tests/un/strings.c
@@ -27,7 +27,7 @@ int main(void) {
assert(!un_string_compare(*(String*)un_list_get(&splits, 4), UN_STR("honey")));
assert(!un_string_compare(*(String*)un_list_get(&splits, 5), UN_STR("mustard")));
- un_list_destroy(&splits);
+ un_list_destroy(&splits, true);
splits = un_string_split(UN_STR("Eatin||burger||wit||no||honey||mustard"), UN_STR("||"), talloc);
@@ -40,7 +40,7 @@ int main(void) {
assert(!un_string_compare(*(String*)un_list_get(&splits, 4), UN_STR("honey")));
assert(!un_string_compare(*(String*)un_list_get(&splits, 5), UN_STR("mustard")));
- un_list_destroy(&splits);
+ un_list_destroy(&splits, true);
splits = un_string_split(UN_STR("Eatin||burger||wit||no||honey||mustard||a"), UN_STR("||"), talloc);
@@ -54,7 +54,7 @@ int main(void) {
assert(!un_string_compare(*(String*)un_list_get(&splits, 5), UN_STR("mustard")));
assert(!un_string_compare(*(String*)un_list_get(&splits, 6), UN_STR("a")));
- un_list_destroy(&splits);
+ un_list_destroy(&splits, true);
splits = un_string_split(UN_STR("a||Eatin||burger||wit||no||honey||mustard||a"), UN_STR("||"), talloc);
@@ -69,7 +69,7 @@ int main(void) {
assert(!un_string_compare(*(String*)un_list_get(&splits, 6), UN_STR("mustard")));
assert(!un_string_compare(*(String*)un_list_get(&splits, 7), UN_STR("a")));
- un_list_destroy(&splits);
+ un_list_destroy(&splits, true);
splits = un_string_split(UN_STR("||Eatin||burger||wit||no||honey||mustard||"), UN_STR("||"), talloc);
@@ -84,7 +84,7 @@ int main(void) {
assert(!un_string_compare(un_string_join(splits, UN_STR(" "), talloc), UN_STR("Eatin burger wit no honey mustard")));
- un_list_destroy(&splits);
+ un_list_destroy(&splits, true);
assert(!un_string_compare(un_string_substring(UN_STR("HelloWorld!"), 5, 6), UN_STR("World!")));
assert(!un_string_compare(un_string_substring(UN_STR("HelloWorld!"), 0, 11), UN_STR("HelloWorld!")));
diff --git a/tests/un/win_wstr.c b/tests/un/win_wstr.c
new file mode 100644
index 0000000..55cec57
--- /dev/null
+++ b/tests/un/win_wstr.c
@@ -0,0 +1,26 @@
+#include <ungrateful.h>
+#if !defined(OS_WINDOWS)
+int main(void) {
+ return 0;
+}
+#else
+
+#include <windows.h>
+#pragma comment(lib, "User32.lib")
+
+int main(void) {
+ wchar *caption, *text;
+ Allocator talloc = un_allocator_get_temporary();
+
+
+ caption = un_wstring_from_cstring(UN_CSTR "Внимание", talloc);
+ text = un_wstring_from_cstring(UN_CSTR "Тестовое сообщение", talloc);
+
+
+ assert(caption != NULL);
+ assert(text != NULL);
+
+ // MessageBoxW(NULL, text, caption, MB_OK);
+}
+
+#endif