From: Lukas Jiriste Date: Wed, 17 Jan 2024 13:56:09 +0000 (+0100) Subject: Improve matrix handling, remove VEC_INIT macro X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=00bb2e3124c52f1269675bb28175de780ffe9c6e;p=Libft.git Improve matrix handling, remove VEC_INIT macro Improve matrix insertion by patching bugs and adding bounds checking. Insert VEC_INIT macro as it is forbidden by the Norm. Add ft_mat_access as matrix analog to ft_vec_access. --- diff --git a/Makefile b/Makefile index 77db79f..431f293 100644 --- a/Makefile +++ b/Makefile @@ -102,6 +102,7 @@ SRCarr := ft_vec_init.c \ ft_mat_append.c \ ft_mat_insert_col.c \ ft_mat_insert_row.c \ + ft_mat_access.c \ ft_mat_free.c \ SOURCES := $(foreach dir, $(SRCDIR), $(addprefix $(dir)/, $($(dir:ft_%=SRC%)))) diff --git a/ft_arr/ft_mat_access.c b/ft_arr/ft_mat_access.c new file mode 100644 index 0000000..b8886e9 --- /dev/null +++ b/ft_arr/ft_mat_access.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_mat_access.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/17 11:32:45 by ljiriste #+# #+# */ +/* Updated: 2024/01/17 13:03:13 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include + +void *ft_mat_access(t_mat *mat, size_t row, size_t col) +{ + if (!mat) + return (NULL); + if (row >= mat->rows || col >= mat->cols) + return (NULL); + return ((char *)mat->vec.vec + (row * mat->cols + col) * mat->vec.el_size); +} diff --git a/ft_arr/ft_mat_insert_col.c b/ft_arr/ft_mat_insert_col.c index 6c043fb..9b92aee 100644 --- a/ft_arr/ft_mat_insert_col.c +++ b/ft_arr/ft_mat_insert_col.c @@ -6,50 +6,13 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/12 08:57:22 by ljiriste #+# #+# */ -/* Updated: 2024/01/12 17:24:31 by ljiriste ### ########.fr */ +/* Updated: 2024/01/17 13:12:34 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ #include "ft_arr.h" #include "ft_mem.h" -/* Failure is too complicated to deal with in this approach -void revert_partial_col_insert(t_mat *mat, size_t col, size_t failed_row) -{ - while (failed_row > 0) - { - ft_vec_forget(&(mat->vec), (failed_row - 1) * mat->cols + col); - --failed_row; - } - return ; -} - -// Number of bytes moved is O(n^2) but it is doable in O(n) (not that hard) -ft_mat_insert_col(t_mat *mat, const t_vec *vec, size_t index) -{ - size_t i; - t_arr_stat res; - - if (!mat || !input_row || mat->rows != vec->size) - return (invalid_input); - ++mat->cols; - i = 0; - while (i < mat->rows) - { - res = ft_vec_insert(&(mat->vec), (char *)vec->vec + i * vec->el_size, - i * mat->cols + index) - if (res) - { - revert_partial_col_insert(mat, index, i); - --mat->cols; - return (res); - } - ++i; - } - return (success); -} -*/ - // Creates space for the inserted column inside the mat->vec void reorganize(t_mat *mat, size_t move_index, size_t change) { @@ -93,19 +56,35 @@ static void copy(t_mat *mat, const t_vec *vec, size_t index) return ; } +static void set_auxiliary_vars(t_mat *mat, size_t index, + size_t *cols_change, size_t *move_index) +{ + if (index > mat->cols) + { + *cols_change = index - mat->cols + 1; + *move_index = mat->cols; + } + else + { + *cols_change = 1; + *move_index = index; + } + return ; +} + t_arr_stat ft_mat_insert_col(t_mat *mat, const t_vec *vec, size_t index) { size_t cols_change; size_t move_index; t_arr_stat res; - cols_change = 1; - move_index = index; - if (index > mat->cols) - { - cols_change = index - mat->cols + 1; - move_index = mat->cols; - } + if (!mat || !vec || vec->size == 0) + return (invalid_input); + if (mat->rows == 0) + mat->rows = vec->size; + else if (mat->rows != vec->size) + return (invalid_input); + set_auxiliary_vars(mat, index, &cols_change, &move_index); while ((mat->cols + cols_change) * mat->rows < mat->vec.capacity) { res = ft_vec_enlarge(&(mat->vec)); @@ -113,8 +92,6 @@ t_arr_stat ft_mat_insert_col(t_mat *mat, const t_vec *vec, size_t index) return (res); } reorganize(mat, move_index, cols_change); - if (res != success) - return (res); copy(mat, vec, index); - return (res); + return (success); } diff --git a/ft_arr/ft_mat_insert_row.c b/ft_arr/ft_mat_insert_row.c index 31fcfe0..b64944a 100644 --- a/ft_arr/ft_mat_insert_row.c +++ b/ft_arr/ft_mat_insert_row.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/11 19:20:00 by ljiriste #+# #+# */ -/* Updated: 2024/01/12 17:08:04 by ljiriste ### ########.fr */ +/* Updated: 2024/01/17 13:53:42 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,12 +16,19 @@ t_arr_stat ft_mat_insert_row(t_mat *mat, const t_vec *vec, size_t index) { size_t res; - if (!mat || !vec || mat->cols != vec->size) + if (!mat || !vec || vec->size == 0) + return (invalid_input); + if (mat->cols == 0) + mat->cols = vec->size; + else if (mat->cols != vec->size) return (invalid_input); res = ft_vec_insert_range(&(mat->vec), vec->vec, mat->cols, index * mat->cols); if (res != success) return (res); - ++mat->rows; + if (index < mat->rows) + ++mat->rows; + else + mat->rows += index - mat->rows + 1; return (success); } diff --git a/inc/ft_arr.h b/inc/ft_arr.h index c4f6d9c..4b69c95 100644 --- a/inc/ft_arr.h +++ b/inc/ft_arr.h @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/09 13:58:15 by ljiriste #+# #+# */ -/* Updated: 2024/01/14 16:03:00 by ljiriste ### ########.fr */ +/* Updated: 2024/01/17 14:52:46 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -58,7 +58,14 @@ t_arr_stat ft_vec_forget_range(t_vec *vec, size_t index, size_t count); t_arr_stat ft_vec_erase_range(t_vec *vec, size_t count, size_t index, void (*free_el)(void *)); -# define VEC_INIT(x) {.capacity = 0, .size = 0, .el_size = (x), .vec = NULL} +// This macro should have been used for static t_vec initialization +// as I see no other way. +// But the Norm forbids macro functions, so just use the literal itself +/* +# define VEC_INIT(x) \ + (t_vec){.capacity = 0, .size = 0, .el_size = (x), .vec = NULL} \ +*/ + t_arr_stat ft_vec_init(t_vec *vec, size_t el_size); void ft_vec_free(t_vec *vec, void (*free_el)(void *)); void *ft_vec_access(t_vec *vec, size_t index);