Add a ft_vec module for vector struct
authorLukas Jiriste <ljiriste@student.42prague.com>
Sat, 9 Dec 2023 17:26:53 +0000 (18:26 +0100)
committerLukas Jiriste <ljiriste@student.42prague.com>
Sat, 9 Dec 2023 17:26:53 +0000 (18:26 +0100)
Add vector struct and operations on it that are somewhat similar to C++
std::vector.

Makefile
ft_vec/ft_vec_access.c [new file with mode: 0644]
ft_vec/ft_vec_append.c [new file with mode: 0644]
ft_vec/ft_vec_erase.c [new file with mode: 0644]
ft_vec/ft_vec_free.c [new file with mode: 0644]
ft_vec/ft_vec_init.c [new file with mode: 0644]
ft_vec/ft_vec_insert.c [new file with mode: 0644]
ft_vec/ft_vec_reserve.c [new file with mode: 0644]
inc/ft_vec.h [new file with mode: 0644]
inc/libft.h

index 13997eeca61ebb6af9379afbe0e741ad3a39ef86..035bc78abab3dda7febed19aefd689923f11869a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -7,13 +7,13 @@ RM := rm -f
 INCDIR = ./inc
 INCLUDE := $(addprefix -I, $(INCDIR))
 
-SRCDIR := ft_gen ft_math ft_str ft_mem ft_io ft_check ft_conv ft_lst
+SRCDIR := ft_gen ft_math ft_str ft_mem ft_io ft_check ft_conv ft_lst ft_vec
 
-SRCgen :=      ft_swap.c                               \
+SRCgen :=      ft_swap.c                               \
 
-SRCmath :=     ft_abs.c                                \
+SRCmath        :=      ft_abs.c                                \
 
-SRCstr :=      ft_strncat_alloc.c              \
+SRCstr :=      ft_strncat_alloc.c              \
                        ft_strncmp.c                    \
                        ft_strndup.c                    \
                        ft_strchr.c                             \
@@ -30,7 +30,7 @@ SRCstr :=     ft_strncat_alloc.c              \
                        ft_strlcat.c                    \
                        ft_strrchr.c                    \
 
-SRCmem :=      ft_calloc.c                             \
+SRCmem :=      ft_calloc.c                             \
                        ft_memchr.c                             \
                        ft_memcmp.c                             \
                        ft_memset.c                             \
@@ -38,7 +38,7 @@ SRCmem :=     ft_calloc.c                             \
                        ft_memcpy.c                             \
                        ft_bzero.c                              \
 
-SRCio :=       ft_putendl_fd.c                 \
+SRCio  :=      ft_putendl_fd.c                 \
                        ft_putnbr_fd.c                  \
                        ft_printf/conversion.c  \
                        ft_printf/ft_printf.c   \
@@ -49,7 +49,7 @@ SRCio :=      ft_putendl_fd.c                 \
                        get_next_line.c                 \
                        ft_putstr_fd.c                  \
 
-SRCcheck :=    ft_isalnum.c                    \
+SRCcheck:=     ft_isalnum.c                    \
                        ft_isspace.c                    \
                        ft_isdigit.c                    \
                        ft_isascii.c                    \
@@ -58,7 +58,7 @@ SRCcheck :=   ft_isalnum.c                    \
                        ft_isupper.c                    \
                        ft_isprint.c                    \
 
-SRCconv :=     ft_itoa_base.c                  \
+SRCconv        :=      ft_itoa_base.c                  \
                        ft_tolower.c                    \
                        ft_toupper.c                    \
                        ft_atoi.c                               \
@@ -85,6 +85,14 @@ SRClst       :=      ft_lst_reverse.c                \
                        ft_lst_sort.c                   \
                        ft_lst_sorted_insert.c  \
 
+SRCvec :=      ft_vec_init.c                   \
+                       ft_vec_reserve.c                \
+                       ft_vec_insert.c                 \
+                       ft_vec_append.c                 \
+                       ft_vec_erase.c                  \
+                       ft_vec_access.c                 \
+                       ft_vec_free.c                   \
+
 SOURCES := $(foreach dir, $(SRCDIR), $(addprefix $(dir)/, $($(dir:ft_%=SRC%))))
 OBJECTS := $(SOURCES:.c=.o)
 
diff --git a/ft_vec/ft_vec_access.c b/ft_vec/ft_vec_access.c
new file mode 100644 (file)
index 0000000..d47d979
--- /dev/null
@@ -0,0 +1,23 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_vec_access.c                                    :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2023/12/09 17:14:49 by ljiriste          #+#    #+#             */
+/*   Updated: 2023/12/09 17:25:17 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ft_vec.h"
+#include <stddef.h>
+
+void   *ft_vec_access(t_vec *vec, size_t index)
+{
+       if (!vec)
+               return (NULL);
+       if (index >= vec->size)
+               return (NULL);
+       return (vec->vec + vec->el_size * index);
+}
diff --git a/ft_vec/ft_vec_append.c b/ft_vec/ft_vec_append.c
new file mode 100644 (file)
index 0000000..f05465f
--- /dev/null
@@ -0,0 +1,20 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_vec_append.c                                    :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2023/12/09 16:39:20 by ljiriste          #+#    #+#             */
+/*   Updated: 2023/12/09 17:10:27 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ft_vec.h"
+
+t_vec_stat     ft_vec_append(t_vec *vec, const void *element)
+{
+       if (!vec)
+               return (invalid_input);
+       return (ft_vec_insert(vec, element, vec->size));
+}
diff --git a/ft_vec/ft_vec_erase.c b/ft_vec/ft_vec_erase.c
new file mode 100644 (file)
index 0000000..b8a92cc
--- /dev/null
@@ -0,0 +1,24 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_vec_erase.c                                     :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2023/12/09 17:10:39 by ljiriste          #+#    #+#             */
+/*   Updated: 2023/12/09 18:23:06 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ft_vec.h"
+#include "libft.h"
+
+t_vec_stat     ft_vec_erase(t_vec *vec, size_t index)
+{
+       if (!vec || index == SIZE_MAX)
+               return (invalid_input);
+       ft_memmove(vec->vec + index, vec->vec + vec->el_size * (index + 1),
+                       vec->el_size * (vec->size - index - 1));
+       --vec->size;
+       return (success);
+}
diff --git a/ft_vec/ft_vec_free.c b/ft_vec/ft_vec_free.c
new file mode 100644 (file)
index 0000000..73e6aad
--- /dev/null
@@ -0,0 +1,23 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_vec_free.c                                      :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2023/12/09 17:37:13 by ljiriste          #+#    #+#             */
+/*   Updated: 2023/12/09 17:49:52 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ft_vec.h"
+#include <stdlib.h>
+
+void   ft_vec_free(t_vec *vec)
+{
+       if (!vec)
+               return ;
+       free(vec->vec);
+       ft_vec_init(vec, vec->el_size);
+       return ;
+}
diff --git a/ft_vec/ft_vec_init.c b/ft_vec/ft_vec_init.c
new file mode 100644 (file)
index 0000000..5731308
--- /dev/null
@@ -0,0 +1,26 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_vec_init.c                                      :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2023/12/09 16:04:26 by ljiriste          #+#    #+#             */
+/*   Updated: 2023/12/09 17:49:19 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ft_vec.h"
+#include "libft.h"
+#include <stddef.h>
+
+t_vec_stat     ft_vec_init(t_vec *vec, size_t el_size)
+{
+       if (el_size == 0 || !vec)
+               return (invalid_input);
+       vec->capacity = 0;
+       vec->size = 0;
+       vec->el_size = el_size;
+       vec->vec = NULL;
+       return (success);
+}
diff --git a/ft_vec/ft_vec_insert.c b/ft_vec/ft_vec_insert.c
new file mode 100644 (file)
index 0000000..39efe99
--- /dev/null
@@ -0,0 +1,55 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_vec_insert.c                                    :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2023/12/09 16:50:57 by ljiriste          #+#    #+#             */
+/*   Updated: 2023/12/09 18:19:13 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ft_vec.h"
+#include "libft.h"
+
+static t_vec_stat      ft_vec_enlarge(t_vec *vec)
+{
+       if (vec->capacity == SIZE_MAX)
+               return (alloc_fail);
+       if (vec->capacity > SIZE_MAX / 2)
+       {
+               if (ft_vec_reserve(vec, SIZE_MAX))
+                       return (alloc_fail);
+       }
+       else if (vec->capacity == 0)
+       {
+               if(ft_vec_reserve(vec, V_DEFAULT_CAPACITY))
+                       return (alloc_fail);
+       }
+       else
+       {
+               if (ft_vec_reserve(vec, vec->capacity * 2))
+                       return (alloc_fail);
+       }
+       return (success);
+}
+
+t_vec_stat     ft_vec_insert(t_vec *vec, void const *element, size_t index)
+{
+       if (!element || !vec || index == SIZE_MAX)
+               return (invalid_input);
+       while (vec->size == vec->capacity || index >= vec->capacity)
+       {
+               if (ft_vec_enlarge(vec))
+                       return (alloc_fail);
+       }
+       if (index < vec->size)
+               ft_memmove(vec->vec + vec->el_size * (index + 1),
+                       vec->vec + vec->el_size * index, vec->el_size * (vec->size - index));
+       ft_memcpy(vec->vec + vec->el_size * index, element, vec->el_size);
+       if (index > vec->size)
+               vec->size = index;
+       ++vec->size;
+       return (success);
+}
diff --git a/ft_vec/ft_vec_reserve.c b/ft_vec/ft_vec_reserve.c
new file mode 100644 (file)
index 0000000..6db8ce7
--- /dev/null
@@ -0,0 +1,36 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_vec_reserve.c                                   :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2023/12/09 16:17:46 by ljiriste          #+#    #+#             */
+/*   Updated: 2023/12/09 18:11:38 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ft_vec.h"
+#include "libft.h"
+#include <stdlib.h>
+
+t_vec_stat     ft_vec_reserve(t_vec *vec, size_t capacity)
+{
+       void    *tmp;
+
+       if (!vec)
+               return (invalid_input);
+       if (vec->capacity >= capacity)
+               return (invalid_input);
+       tmp = vec->vec;
+       vec->vec = ft_calloc(capacity, vec->el_size);
+       if (!vec->vec)
+       {
+               vec->vec = tmp;
+               return (alloc_fail);
+       }
+       vec->capacity = capacity;
+       ft_memcpy(vec->vec, tmp, vec->size * vec->el_size);
+       free(tmp);
+       return (success);
+}
diff --git a/inc/ft_vec.h b/inc/ft_vec.h
new file mode 100644 (file)
index 0000000..33733e4
--- /dev/null
@@ -0,0 +1,49 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_vec.h                                           :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2023/12/09 13:58:15 by ljiriste          #+#    #+#             */
+/*   Updated: 2023/12/09 17:36:45 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef FT_VEC_H
+# define FT_VEC_H
+
+# include <stddef.h>
+
+# ifndef V_DEFAULT_CAPACITY
+#  define V_DEFAULT_CAPACITY 8
+# endif
+
+typedef enum e_vec_stat
+{
+       success,
+       alloc_fail,
+       invalid_size,
+       invalid_input,
+}                      t_vec_stat;
+
+// It should be possible to remove el_size with the use of macros
+typedef struct s_vec
+{
+       size_t  capacity;
+       size_t  size;
+       size_t  el_size;
+       void    *vec;
+}                      t_vec;
+
+t_vec_stat     ft_vec_init(t_vec *vec, size_t  el_size);
+void           ft_vec_free(t_vec *vec);
+
+t_vec_stat     ft_vec_reserve(t_vec *vec, size_t capacity);
+t_vec_stat     ft_vec_append(t_vec *vec, const void *element);
+t_vec_stat     ft_vec_insert(t_vec *vec, const void *element, size_t index);
+t_vec_stat     ft_vec_erase(t_vec *vec, size_t index);
+
+void           *ft_vec_access(t_vec *vec, size_t index);
+
+#endif
index 33b86b076576414b0d46f357d95e8057e7ed149f..1c4eb1a6c670f0e146994d67a9a79f4e8b94283f 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2023/08/15 12:58:15 by ljiriste          #+#    #+#             */
-/*   Updated: 2023/12/09 15:13:41 by ljiriste         ###   ########.fr       */
+/*   Updated: 2023/12/09 17:27:06 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -21,5 +21,6 @@
 # include "ft_mem.h"
 # include "ft_io.h"
 # include "ft_lst.h"
+# include "ft_vec.h"
 
 #endif