solidc
Robust collection of general-purpose cross-platform C libraries and data structures designed for rapid and safe development in C
Loading...
Searching...
No Matches
slist.c
1#include "../include/slist.h"
2
3#include <stdalign.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7
8#define ALIGNMENT 8U
9#define ALIGNMENT_MASK (ALIGNMENT - 1)
10
11// Round up to proper alignment
12static inline size_t aligned_size(size_t n) { return (n + ALIGNMENT_MASK) & ~(ALIGNMENT_MASK); }
13
14slist* slist_new(size_t elem_size) {
15 slist* list = (slist*)malloc(sizeof(slist));
16 if (!list) return NULL;
17
18 list->head = NULL;
19 list->tail = NULL;
20 list->size = 0;
21 list->elem_size = elem_size;
22 return list;
23}
24
25void slist_free(slist* list) {
26 if (!list) return;
27 slist_clear(list);
28 free(list);
29}
30
31size_t slist_size(const slist* list) { return list ? list->size : 0; }
32
33void slist_clear(slist* list) {
34 if (!list) return;
35
36 slist_node_t* current = list->head;
37 while (current) {
38 slist_node_t* next = current->next;
39 slist_node_free(current);
40 current = next;
41 }
42 list->head = list->tail = NULL;
43 list->size = 0;
44}
45
46slist_node_t* slist_node_new(size_t elem_size, void* data) {
47 size_t total_size = sizeof(slist_node_t) + aligned_size(elem_size);
48 slist_node_t* node = (slist_node_t*)malloc(total_size);
49 if (!node) return NULL;
50
51 node->next = NULL;
52 node->data = (void*)(node + 1); // data lives right after struct
53 memcpy(node->data, data, elem_size);
54 return node;
55}
56
58 free(node); // single allocation
59}
60
61void slist_push_front(slist* list, void* elem) {
62 if (!list) return;
63 slist_node_t* node = slist_node_new(list->elem_size, elem);
64 if (!node) return;
65
66 node->next = list->head;
67 list->head = node;
68 if (!list->tail) list->tail = node; // first element
69 list->size++;
70}
71
72void slist_push_back(slist* list, void* elem) {
73 if (!list) return;
74 slist_node_t* node = slist_node_new(list->elem_size, elem);
75 if (!node) return;
76
77 if (!list->head) {
78 list->head = list->tail = node;
79 } else {
80 list->tail->next = node;
81 list->tail = node;
82 }
83 list->size++;
84}
85
87 if (!list || !list->head) return;
88 slist_node_t* temp = list->head;
89 list->head = temp->next;
90 if (!list->head) list->tail = NULL;
91 slist_node_free(temp);
92 list->size--;
93}
94
95void slist_insert(slist* list, size_t index, void* elem) {
96 if (!list || index > list->size) return;
97
98 if (index == 0) {
99 slist_push_front(list, elem);
100 return;
101 }
102 if (index == list->size) {
103 slist_push_back(list, elem);
104 return;
105 }
106
107 slist_node_t* current = list->head;
108 for (size_t i = 0; i < index - 1; i++) {
109 current = current->next;
110 }
111
112 slist_node_t* node = slist_node_new(list->elem_size, elem);
113 if (!node) return;
114
115 node->next = current->next;
116 current->next = node;
117 list->size++;
118}
119
120void slist_remove(slist* list, size_t index) {
121 if (!list || index >= list->size) return;
122
123 if (index == 0) {
124 slist_pop_front(list);
125 return;
126 }
127
128 slist_node_t* current = list->head;
129 for (size_t i = 0; i < index - 1; i++) {
130 current = current->next;
131 }
132
133 slist_node_t* temp = current->next;
134 current->next = temp->next;
135 if (temp == list->tail) list->tail = current;
136 slist_node_free(temp);
137 list->size--;
138}
139
140void* slist_get(const slist* list, size_t index) {
141 if (!list || index >= list->size) return NULL;
142
143 slist_node_t* current = list->head;
144 for (size_t i = 0; i < index; i++) {
145 current = current->next;
146 }
147 return current->data;
148}
149
150int slist_index_of(const slist* list, void* elem) {
151 if (!list) return -1;
152
153 slist_node_t* current = list->head;
154 int index = 0;
155 while (current) {
156 if (memcmp(current->data, elem, list->elem_size) == 0) return index;
157 current = current->next;
158 index++;
159 }
160 return -1;
161}
162
163void slist_insert_after(slist* list, void* elem, void* after) {
164 int idx = slist_index_of(list, after);
165 if (idx >= 0 && (size_t)idx < list->size) slist_insert(list, (size_t)idx + 1, elem);
166}
167
168void slist_insert_before(slist* list, void* elem, void* before) {
169 int idx = slist_index_of(list, before);
170 if (idx > 0 && (size_t)idx < list->size)
171 slist_insert(list, (size_t)idx - 1, elem);
172 else if (idx == 0)
173 slist_push_front(list, elem);
174}
175
176void slist_print_asint(const slist* list) {
177 SLIST_FOR_EACH(list, node) { printf("%d ", *(int*)node->data); }
178 printf("\n");
179}
180
181void slist_print_aschar(const slist* list) {
182 SLIST_FOR_EACH(list, node) { printf("%c ", *(char*)node->data); }
183 printf("\n");
184}
#define SLIST_FOR_EACH(list, node)
Definition slist.h:192
void slist_print_asint(const slist *list)
Definition slist.c:176
void slist_insert(slist *list, size_t index, void *elem)
Definition slist.c:95
void slist_insert_before(slist *list, void *elem, void *before)
Definition slist.c:168
void slist_clear(slist *list)
Definition slist.c:33
void slist_pop_front(slist *list)
Definition slist.c:86
void slist_node_free(slist_node_t *node)
Definition slist.c:57
size_t slist_size(const slist *list)
Definition slist.c:31
void slist_push_back(slist *list, void *elem)
Definition slist.c:72
struct slist_node slist_node_t
void slist_remove(slist *list, size_t index)
Definition slist.c:120
void slist_push_front(slist *list, void *elem)
Definition slist.c:61
void * slist_get(const slist *list, size_t index)
Definition slist.c:140
slist_node_t * slist_node_new(size_t elem_size, void *data)
Definition slist.c:46
slist * slist_new(size_t elem_size)
Definition slist.c:14
void slist_print_aschar(const slist *list)
Definition slist.c:181
void slist_insert_after(slist *list, void *elem, void *after)
Definition slist.c:163
void slist_free(slist *list)
Definition slist.c:25
int slist_index_of(const slist *list, void *elem)
Definition slist.c:150
struct slist_node * next
Definition slist.h:24
void * data
Definition slist.h:22
Definition slist.h:32
size_t elem_size
Definition slist.h:40
slist_node_t * tail
Definition slist.h:36
slist_node_t * head
Definition slist.h:34
size_t size
Definition slist.h:38