mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
list: switch lists to circular lists
This commit is contained in:
+39
-45
@@ -1,6 +1,7 @@
|
|||||||
#ifndef _LIST_H
|
#ifndef _LIST_H
|
||||||
#define _LIST_H
|
#define _LIST_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
typedef struct _list_node {
|
typedef struct _list_node {
|
||||||
@@ -8,77 +9,70 @@ typedef struct _list_node {
|
|||||||
struct _list_node *next;
|
struct _list_node *next;
|
||||||
} list_node_t;
|
} list_node_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef list_node_t list_t;
|
||||||
list_node_t *head;
|
|
||||||
list_node_t *tail;
|
|
||||||
} list_t;
|
|
||||||
|
|
||||||
#define LIST_INIT_VALUE ((list_t) {.head = NULL, .tail = NULL})
|
#define LIST_INIT_VALUE(NAME) ((list_t) {.prev = &(NAME), .next = &(NAME)})
|
||||||
|
|
||||||
static inline void list_init(list_t *list) {
|
static inline void list_init(list_t *list) {
|
||||||
list->head = NULL;
|
list->prev = list;
|
||||||
list->tail = NULL;
|
list->next = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool list_is_empty(const list_t *list) {
|
||||||
|
return list->next == list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline list_node_t *list_get_first(const list_t *list) {
|
||||||
|
return list_is_empty(list) ? NULL : list->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline list_node_t *list_get_last(const list_t *list) {
|
||||||
|
return list_is_empty(list) ? NULL : list->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void list_push_front(list_t *list, list_node_t *node) {
|
static inline void list_push_front(list_t *list, list_node_t *node) {
|
||||||
node->prev = NULL;
|
node->prev = list;
|
||||||
node->next = list->head;
|
node->next = list->next;
|
||||||
if (list->head != NULL) {
|
list->next->prev = node;
|
||||||
list->head->prev = node;
|
list->next = node;
|
||||||
} else {
|
|
||||||
list->tail = node;
|
|
||||||
}
|
|
||||||
list->head = node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void list_push_back(list_t *list, list_node_t *node) {
|
static inline void list_push_back(list_t *list, list_node_t *node) {
|
||||||
node->next = NULL;
|
node->next = list;
|
||||||
node->prev = list->tail;
|
node->prev = list->prev;
|
||||||
if (list->tail != NULL) {
|
list->prev->next = node;
|
||||||
list->tail->next = node;
|
list->prev = node;
|
||||||
} else {
|
|
||||||
list->head = node;
|
|
||||||
}
|
|
||||||
list->tail = node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void list_remove(list_t *list, list_node_t *node) {
|
static inline void list_remove(list_node_t *node) {
|
||||||
if (node->prev != NULL) {
|
node->prev->next = node->next;
|
||||||
node->prev->next = node->next;
|
node->next->prev = node->prev;
|
||||||
} else {
|
|
||||||
list->head = node->next;
|
|
||||||
}
|
|
||||||
if (node->next != NULL) {
|
|
||||||
node->next->prev = node->prev;
|
|
||||||
} else {
|
|
||||||
list->tail = node->prev;
|
|
||||||
}
|
|
||||||
node->prev = NULL;
|
node->prev = NULL;
|
||||||
node->next = NULL;
|
node->next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline list_node_t *list_pop_front(list_t *list) {
|
static inline list_node_t *list_pop_front(list_t *list) {
|
||||||
if (list->head == NULL) {
|
list_node_t *node = list->next;
|
||||||
|
if (node == list)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
list_remove(node);
|
||||||
list_node_t *node = list->head;
|
|
||||||
list_remove(list, node);
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline list_node_t *list_pop_back(list_t *list) {
|
static inline list_node_t *list_pop_back(list_t *list) {
|
||||||
if (list->tail == NULL) {
|
list_node_t *node = list->prev;
|
||||||
|
if (node == list)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
list_remove(node);
|
||||||
list_node_t *node = list->tail;
|
|
||||||
list_remove(list, node);
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define list_for_each(LIST, ITER) \
|
#define list_for_each(LIST, ITER) \
|
||||||
for (list_node_t *ITER = (LIST)->head; ITER != NULL; ITER = ITER->next)
|
for (list_node_t *ITER = (LIST)->next; ITER != (LIST); ITER = ITER->next)
|
||||||
|
|
||||||
#define list_for_each_safe(LIST, ITER) \
|
#define list_for_each_safe(LIST, ITER, NEXT) \
|
||||||
for (list_node_t *ITER = (LIST)->head, *_next = (ITER ? ITER->next : NULL); ITER != NULL; ITER = _next, _next = (ITER ? ITER->next : NULL))
|
for (list_node_t *ITER = (LIST)->next, *NEXT = ITER->next; \
|
||||||
|
ITER != (LIST); \
|
||||||
|
ITER = NEXT, NEXT = ITER->next)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user