cpfast/vec.c
Slendi 414decf167
Initial commit.
Signed-off-by: Slendi <slendi@socopon.com>
2023-09-08 01:13:04 +03:00

376 lines
6.7 KiB
C

#include "vec.h"
int vec_new(t_vec *dst, size_t init_len, size_t elem_size)
{
if (!dst || elem_size == 0)
return (-1);
dst->alloc_size = init_len * elem_size;
dst->len = 0;
dst->elem_size = elem_size;
if (init_len == 0)
dst->memory = NULL;
else
{
dst->memory = malloc(dst->alloc_size);
if (!dst->memory)
return (-1);
}
return (1);
}
void vec_free(t_vec *src)
{
if (!src || src->alloc_size == 0)
return ;
free(src->memory);
src->memory = NULL;
src->alloc_size = 0;
src->elem_size = 0;
src->len = 0;
}
int vec_from(t_vec *dst, void *src, size_t len, size_t elem_size)
{
if (!dst || !src || elem_size == 0)
return (-1);
else if (vec_new(dst, len, elem_size) < 0)
return (-1);
memcpy(
dst->memory,
src,
dst->alloc_size);
dst->len = len;
return (1);
}
int vec_copy(t_vec *dst, t_vec *src)
{
size_t copy_size;
if (!dst || !src || !src->memory)
return (-1);
else if (!dst->memory)
vec_new(dst, src->len, dst->elem_size);
if (src->len * src->elem_size < dst->alloc_size)
copy_size = src->len * src->elem_size;
else
copy_size = src->alloc_size;
memcpy(
dst->memory,
src->memory,
copy_size);
dst->len = copy_size / dst->elem_size;
return (1);
}
int vec_resize(t_vec *src, size_t target_len)
{
t_vec dst;
if (!src)
return (-1);
else if (!src->memory)
return vec_new(src, target_len, src->elem_size);
else if (vec_new(&dst, target_len, src->elem_size) < 0)
return (-1);
memcpy(
dst.memory,
src->memory,
src->len * src->elem_size);
dst.len = src->len;
vec_free(src);
*src = dst;
return (1);
}
void *vec_get(t_vec *src, size_t index)
{
unsigned char *ptr;
if (index >= src->len || !src || !src->memory)
return (NULL);
ptr = &src->memory[src->elem_size * index];
return (ptr);
}
int vec_push(t_vec *dst, void *src)
{
if (!dst || !src)
return (-1);
else if (!dst->memory)
vec_new(dst, 1, dst->elem_size);
if (dst->elem_size * dst->len >= dst->alloc_size)
if (vec_resize(dst, dst->len * 2) < 0)
return (-1);
memcpy(&dst->memory[dst->elem_size * dst->len], src, dst->elem_size);
dst->len++;
return (1);
}
int vec_pop(void *dst, t_vec *src)
{
if (!dst || !src)
return (-1);
else if (!src->memory || src->len == 0)
return (0);
memcpy(dst, vec_get(src, src->len - 1), src->elem_size);
src->len--;
return (1);
}
int vec_clear(t_vec *src)
{
if (!src)
return (-1);
src->len = 0;
return (1);
}
int vec_insert(t_vec *dst, void *src, size_t index)
{
if (!dst || !src || index > dst->len)
return (-1);
else if (index == dst->len)
return (vec_push(dst, src));
if (dst->elem_size * dst->len >= dst->alloc_size)
if (vec_resize(dst, (dst->alloc_size * 2) / dst->elem_size) < 0)
return (-1);
memmove(
vec_get(dst, index + 1),
vec_get(dst, index),
(dst->len - index) * dst->elem_size);
memcpy(
vec_get(dst, index),
src, dst->elem_size);
dst->len++;
return (1);
}
int vec_remove(t_vec *src, size_t index)
{
if (!src || index > src->len)
return (-1);
else if (index == src->len)
{
src->len--;
return (1);
}
memmove(
vec_get(src, index),
&src->memory[src->elem_size * (index + 1)],
(src->len - index) * src->elem_size);
src->len--;
return (1);
}
int vec_append(t_vec *dst, t_vec *src)
{
int ret;
size_t alloc_size;
if (!dst || !src || !src->memory)
return (-1);
else if (!dst->memory)
vec_new(dst, 1, dst->elem_size);
alloc_size = dst->len * dst->elem_size + src->len * src->elem_size;
if (dst->alloc_size < alloc_size)
{
if (dst->alloc_size * 2 < dst->len * alloc_size)
ret = vec_resize(dst, alloc_size);
else
ret = vec_resize(dst, dst->alloc_size * 2);
if (ret < 0)
return (-1);
}
memcpy(
&dst->memory[dst->elem_size * dst->len],
src->memory,
src->len * src->elem_size);
dst->len += src->len;
return (1);
}
int vec_prepend(t_vec *dst, t_vec *src)
{
t_vec new;
size_t alloc_size;
if (!dst || !src)
return (-1);
else if (!dst->memory)
vec_new(dst, 1, dst->elem_size);
alloc_size = dst->len * dst->elem_size + src->len * src->elem_size;
if (vec_new(&new, alloc_size / dst->elem_size, dst->elem_size) < 0)
return (-1);
vec_copy(&new, src);
new.len = src->len + dst->len;
memcpy(
&new.memory[dst->elem_size * dst->len],
dst->memory,
dst->len * dst->elem_size);
vec_free(dst);
*dst = new;
return (1);
}
void vec_iter(t_vec *src, void (*f) (void *))
{
void *ptr;
size_t i;
if (!src || !src->memory)
return ;
i = 0;
while (i < src->len)
{
ptr = vec_get(src, i);
f(ptr);
i++;
}
}
void *vec_find(t_vec *src, bool (*f) (void *))
{
void *ptr;
size_t i;
if (!src || !src->memory)
return (NULL);
i = 0;
while (i < src->len)
{
ptr = vec_get(src, i);
if (f(ptr) == true)
return (ptr);
i++;
}
return (NULL);
}
int vec_map(t_vec *dst, t_vec *src, void (*f) (void *))
{
void *ptr;
void *res;
size_t i;
if (!dst || !src || !src->memory)
return (-1);
else if (!dst->memory)
vec_new(dst, 1, dst->elem_size);
res = malloc(dst->elem_size);
if (!res)
return (-1);
i = 0;
while (i < src->len)
{
ptr = vec_get(src, i);
memcpy(res, ptr, dst->elem_size);
f(res);
vec_push(dst, res);
i++;
}
free(res);
return (1);
}
int vec_filter(t_vec *dst, t_vec *src, bool (*f) (void *))
{
void *ptr;
void *res;
size_t i;
if (!dst || !src || !src->memory)
return (-1);
else if (!dst->memory)
vec_new(dst, 1, dst->elem_size);
res = malloc(dst->elem_size);
if (!res)
return (-1);
i = 0;
while (i < src->len)
{
ptr = vec_get(src, i);
memcpy(res, ptr, dst->elem_size);
if (f(res) == true)
vec_push(dst, res);
i++;
}
free(res);
return (1);
}
int vec_reduce(void *dst, t_vec *src, void (*f) (void *, void *))
{
void *ptr;
size_t i;
if (!dst || !src || !src->memory)
return (-1);
i = 0;
while (i < src->len)
{
ptr = vec_get(src, i);
f(dst, ptr);
i++;
}
return (1);
}
static void memswap8(unsigned char *a, unsigned char *b)
{
if (a == b)
return ;
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
static void memswap(unsigned char *a, unsigned char *b, size_t bytes)
{
size_t i;
if (!a || !b)
return ;
i = 0;
while (i < bytes)
{
memswap8(&a[i], &b[i]);
i++;
}
}
static void vec_sort_recurse(t_vec *src,
long int low,
long int high,
int (*f)(void *, void *))
{
long int pivot;
long int a;
long int b;
if (low >= high)
return ;
pivot = low;
a = low;
b = high;
while (a < b)
{
while (a <= high && f(vec_get(src, a), vec_get(src, pivot)) <= 0)
a++;
while (b >= low && f(vec_get(src, b), vec_get(src, pivot)) > 0)
b--;
if (a < b)
memswap(vec_get(src, a), vec_get(src, b), src->elem_size);
}
memswap(vec_get(src, pivot), vec_get(src, b), src->elem_size);
vec_sort_recurse(src, low, b - 1, f);
vec_sort_recurse(src, b + 1, high, f);
}
void vec_sort(t_vec *src, int (*f)(void *, void *))
{
if (!src || !src->memory)
return ;
vec_sort_recurse(src, 0, src->len - 1, f);
}