aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2025-06-15 21:43:00 +0800
committerMistivia <i@mistivia.com>2025-06-15 21:43:00 +0800
commitd614ec90581e504b9888d2ed66c20a8a86fbc8b2 (patch)
tree32bffa84466531f44298c4b09a6a9e989dc7a92d
parent6b0baf133d799f03611d5fbf5f5b5dcb1d15480a (diff)
impl list
-rw-r--r--README.md7
-rw-r--r--src/list.c3
-rw-r--r--src/list.h94
3 files changed, 76 insertions, 28 deletions
diff --git a/README.md b/README.md
index a1e12d5..c469811 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,9 @@
# Type-safe Generic Algorithms and Data Structures for C
-- Generic Red-black tree
-- Generic Vector
-- Generic Priority queue
+- Generic red-black tree
+- Generic vector
+- Generic linked-list
+- Generic priority queue
- Generic Hash Table
- Generic quick sort
- Augmented red-black tree
diff --git a/src/list.c b/src/list.c
index e69de29..2d08bd5 100644
--- a/src/list.c
+++ b/src/list.c
@@ -0,0 +1,3 @@
+#include "list.h"
+
+LIST_IMPL(Int);
diff --git a/src/list.h b/src/list.h
index cd5c7e6..e20771f 100644
--- a/src/list.h
+++ b/src/list.h
@@ -3,6 +3,8 @@
#include <stdlib.h>
+#include "type_alias.h"
+
#define LIST_DEF(T) \
struct T##List_node { \
@@ -20,20 +22,21 @@
void T##List_init(T##List *self); \
void T##List_free(T##List *self); \
void T##List_move(T##List *self); \
- T##ListIter T##List_insert_before(T##List *self, T##ListIter iter); \
- T##ListIter T##List_insert_after(T##List *self, T##ListIter iter); \
- void T##List_remove_before(T##List *self, T##ListIter iter); \
- void T##List_remove_after(T##List *self, T##ListIter iter); \
+ T##ListIter T##List_insert_before(T##List *self, T##ListIter iter, T val); \
+ T##ListIter T##List_insert_after(T##List *self, T##ListIter iter, T val); \
+ void T##List_remove(T##List *self, T##ListIter iter); \
T##ListIter T##List_begin(T##List *self); \
T##ListIter T##List_last(T##List *self); \
T##ListIter T##List_end(T##List *self); \
- T##ListIter T##List_next(T##ListIter *iter); \
- T##ListIter T##List_prev(T##ListIter *iter); \
- size_t T##List_len(T##ListIter *iter); \
- void T##List_push_back(T##List *self, T val); \
- void T##List_push_front(T##List *self, T val); \
- void T##List_pop_back(T##List *self, T val); \
- void T##List_pop_front(T##List *self, T val); \
+ T##ListIter T##List_next(T##ListIter iter); \
+ T##ListIter T##List_prev(T##ListIter iter); \
+ size_t T##List_len(T##List *self); \
+ T##ListIter T##List_push_back(T##List *self, T val); \
+ T##ListIter T##List_push_front(T##List *self, T val); \
+ void T##List_pop_back(T##List *self); \
+ void T##List_pop_front(T##List *self); \
+
+LIST_DEF(Int);
#define LIST_IMPL(T) \
void T##List_init(T##List *self) { \
@@ -66,25 +69,66 @@
if (iter->prev == NULL) return NULL; \
T##ListIter newnode = malloc(sizeof(T##ListNode)); \
newnode->prev = iter->prev; \
- newnode->next = iter->next; \
+ newnode->next = iter; \
newnode->val = val; \
iter->prev->next = newnode; \
iter->prev = newnode; \
self->len++; \
+ return newnode; \
+ } \
+ T##ListIter T##List_insert_after(T##List *self, T##ListIter iter, T val) { \
+ if (iter->next == NULL) return NULL; \
+ T##ListIter newnode = malloc(sizeof(T##ListNode)); \
+ newnode->next = iter->next; \
+ newnode->prev= iter; \
+ newnode->val = val; \
+ iter->next->prev= newnode; \
+ iter->next = newnode; \
+ self->len++; \
+ return newnode; \
+ } \
+ void T##List_remove(T##List *self, T##ListIter iter) { \
+ if (iter->prev == NULL || iter->next == NULL) return; \
+ iter->prev->next = iter->next; \
+ iter->next->prev = iter->prev; \
+ free(iter); \
+ self->len--; \
+ } \
+ T##ListIter T##List_begin(T##List *self) { \
+ return self->vhead->next; \
+ } \
+ T##ListIter T##List_last(T##List *self) { \
+ if (self->vtail->prev == self->vhead) return NULL; \
+ return self->vtail->prev; \
+ } \
+ T##ListIter T##List_end(T##List *self) { \
+ return self->vtail; \
+ } \
+ T##ListIter T##List_next(T##ListIter iter) { \
+ if (iter == NULL) return NULL; \
+ return iter->next; \
+ } \
+ T##ListIter T##List_prev(T##ListIter iter) { \
+ if (iter == NULL) return NULL; \
+ if (iter->prev == NULL) return NULL; \
+ if (iter->prev->prev == NULL) return NULL; \
+ return iter->prev; \
+ } \
+ size_t T##List_len(T##List *self) { \
+ return self->len; \
+ } \
+ T##ListIter T##List_push_back(T##List *self, T val) { \
+ T##List_insert_before(self, self->vtail, val); \
+ } \
+ T##ListIter T##List_push_front(T##List *self, T val) { \
+ T##List_insert_after(self, self->vhead, val); \
+ } \
+ void T##List_pop_back(T##List *self) { \
+ T##List_remove(self, self->vtail->prev); \
+ } \
+ void T##List_pop_front(T##List *self) { \
+ T##List_remove(self, self->vhead->next); \
} \
- T##ListIter T##List_insert_after(T##List *self, T##ListIter iter); \
- void T##List_remove_before(T##List *self, T##ListIter iter); \
- void T##List_remove_after(T##List *self, T##ListIter iter); \
- T##ListIter T##List_begin(T##List *self); \
- T##ListIter T##List_last(T##List *self); \
- T##ListIter T##List_end(T##List *self); \
- T##ListIter T##List_next(T##ListIter *iter); \
- T##ListIter T##List_prev(T##ListIter *iter); \
- size_t T##List_len(T##ListIter *iter); \
- void T##List_push_back(T##List *self, T val); \
- void T##List_push_front(T##List *self, T val); \
- void T##List_pop_back(T##List *self, T val); \
- void T##List_pop_front(T##List *self, T val); \
#endif