Improve matrix handling, remove VEC_INIT macro
authorLukas Jiriste <ljiriste@student.42prague.com>
Wed, 17 Jan 2024 13:56:09 +0000 (14:56 +0100)
committerLukas Jiriste <ljiriste@student.42prague.com>
Wed, 17 Jan 2024 13:56:09 +0000 (14:56 +0100)
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.

Makefile
ft_arr/ft_mat_access.c [new file with mode: 0644]
ft_arr/ft_mat_insert_col.c
ft_arr/ft_mat_insert_row.c
inc/ft_arr.h

index 77db79ffb47b915d6ea08ddb81d369465ad186b1..431f293dd015ca0e8320d0e1bdd25f81836c0b8e 100644 (file)
--- 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 (file)
index 0000000..b8886e9
--- /dev/null
@@ -0,0 +1,23 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   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);
+}
index 6c043fbd3184a7467e49152a85020e77524dc58e..9b92aeeb8c2a221bdd287ed61c32af549e3fc387 100644 (file)
@@ -6,50 +6,13 @@
 /*   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)
 {
@@ -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);
 }
index 31fcfe065bb93410e74be1e303055f1f1ebc2d41..b64944a1ce53d6b0d6b6478c0b6ef4572a558e43 100644 (file)
@@ -6,7 +6,7 @@
 /*   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       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -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);
 }
index c4f6d9cba15d0a971aca6bfb5bd8b0aabb273215..4b69c9509e62a707829fbb6d0d948f54172b52ae 100644 (file)
@@ -6,7 +6,7 @@
 /*   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       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -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);