ft_dict_traversal.c \
ft_linked_list.c \
ft_linked_list_helpers.c \
+ ft_graph.c \
+ ft_graph_helpers.c \
SRCparse:= ft_parse.c \
ft_parsing_table_init.c \
--- /dev/null
+#include "ft_struct.h"
+
+t_ft_stat ft_graph_init(t_graph *graph, size_t el_size)
+{
+ if (!graph)
+ return (invalid_input);
+ graph->el_size = el_size;
+ return (ft_linked_list_init(&graph->nodes, sizeof(t_graph_node) + el_size));
+}
+
+// Static global function pointer would be more elegant
+static t_free_fun handle_generic_free(int set, t_free_fun free_el)
+{
+ static t_free_fun saved_free_el;
+
+ if (set)
+ saved_free_el = free_el;
+ return (saved_free_el);
+}
+
+static void generic_free(void *element)
+{
+ t_graph_node *node;
+ t_free_fun free_el;
+
+ node = element;
+ free_el = handle_generic_free(0, NULL);
+ if (free_el)
+ free_el(ft_graph_access(node));
+ ft_vec_free(&node->connected_nodes, NULL);
+ return ;
+}
+
+void ft_graph_free(t_graph *graph, t_free_fun free_el)
+{
+ if (!graph)
+ return ;
+ handle_generic_free(1, free_el);
+ ft_linked_list_free(&graph->nodes, generic_free);
+ return ;
+}
+
+void ft_graph_delete(t_graph *graph, t_graph_node *node, t_free_fun free_el)
+{
+ t_graph_node **disconnecting_node;
+ t_linked_list_node *list_node;
+
+ while (node->connected_nodes.size > 0)
+ {
+ disconnecting_node = ft_vec_access(&node->connected_nodes, 0);
+ ft_graph_disconnect(node, *disconnecting_node);
+ }
+ handle_generic_free(1, free_el);
+ list_node = (t_linked_list_node *)
+ ((char *)node - offsetof(t_linked_list_node, data));
+ ft_linked_list_delete(&graph->nodes, list_node, generic_free);
+ return ;
+}
--- /dev/null
+#include "ft_struct.h"
+#include "libft.h"
+
+t_graph_node *ft_graph_insert(t_graph *graph, void *element)
+{
+ t_graph_node new_node;
+
+ if (!graph || !element)
+ return (NULL);
+ if (ft_vec_init(&new_node.connected_nodes, sizeof(t_graph_node *)))
+ return (NULL);
+ ft_memcpy(&new_node.data, element, graph->el_size);
+ return ((t_graph_node *)
+ &ft_linked_list_insert(&graph->nodes, &new_node)->data);
+}
+
+void *ft_graph_access(t_graph_node *node)
+{
+ return (&node->data);
+}
+
+t_ft_stat ft_graph_connect(t_graph_node *node1, t_graph_node *node2)
+{
+ t_ft_stat res;
+
+ res = ft_vec_append(&node1->connected_nodes, &node2);
+ if (res != success)
+ return (res);
+ res = ft_vec_append(&node2->connected_nodes, &node1);
+ if (res != success)
+ ft_vec_forget(&node1->connected_nodes, node1->connected_nodes.size - 1);
+ return (res);
+}
+
+static int cmp_address(const void *v_address1, const void *v_address2)
+{
+ t_graph_node *const *address1;
+ t_graph_node *const *address2;
+
+ address1 = v_address1;
+ address2 = v_address2;
+ return ((*address1 > *address2) - (*address1 < *address2));
+}
+
+void ft_graph_disconnect(t_graph_node *node1, t_graph_node *node2)
+{
+ size_t index;
+
+ ft_vec_find_index(&node1->connected_nodes, node2, &index, cmp_address);
+ ft_vec_forget(&node1->connected_nodes, index);
+ ft_vec_find_index(&node2->connected_nodes, node1, &index, cmp_address);
+ ft_vec_forget(&node2->connected_nodes, index);
+ return ;
+}
/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/20 16:59:43 by ljiriste #+# #+# */
-/* Updated: 2025/12/30 09:43:24 by ljiriste ### ########.fr */
+/* Updated: 2025/12/30 15:01:59 by ljiriste ### ########.fr */
/* */
/* ************************************************************************** */
t_linked_list_node *node, t_free_fun free_el);
void ft_linked_list_free(t_linked_list *list, t_free_fun free_el);
+typedef struct s_graph_node
+{
+ t_vec connected_nodes;
+ char data[];
+} t_graph_node;
+
+// A linked list is used for storage so that node addresses stay constant
+typedef struct s_graph
+{
+ size_t el_size;
+ t_linked_list nodes;
+} t_graph;
+
+t_ft_stat ft_graph_init(t_graph *graph, size_t el_size);
+t_graph_node *ft_graph_insert(t_graph *graph, void *element);
+void *ft_graph_access(t_graph_node *node);
+t_ft_stat ft_graph_connect(t_graph_node *node1, t_graph_node *node2);
+void ft_graph_disconnect(t_graph_node *node1, t_graph_node *node2);
+void ft_graph_delete(t_graph *graph, t_graph_node *node,
+ t_free_fun free_el);
+void ft_graph_free(t_graph *graph, t_free_fun free_el);
+
# ifdef __cplusplus
}
# endif // __cplusplus