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.
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%))))
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ft_mat_access.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2024/01/17 11:32:45 by ljiriste #+# #+# */
+/* Updated: 2024/01/17 13:03:13 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "libft.h"
+#include <stddef.h>
+
+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);
+}
/* By: ljiriste <ljiriste@student.42prague.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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)
{
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));
return (res);
}
reorganize(mat, move_index, cols_change);
- if (res != success)
- return (res);
copy(mat, vec, index);
- return (res);
+ return (success);
}
/* By: ljiriste <ljiriste@student.42prague.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */
{
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);
}
/* By: ljiriste <ljiriste@student.42prague.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */
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);