liblist-c

C type-agnostic linked-list library
git clone https://git.sinitax.com/sinitax/liblist-c
Log | Files | Refs | LICENSE | sfeed.txt

commit 257a494eb3442b50d2ee49b00ba6932b93fb89cc
parent a2f0d5c60438905c14ec25763a6704a542175275
Author: Louis Burda <quent.burda@gmail.com>
Date:   Wed, 12 Apr 2023 22:05:33 -0400

Set C99 standard and add link detach functions

Diffstat:
MMakefile | 2+-
Minclude/list.h | 70+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/list.c | 27---------------------------
Msrc/test.c | 6+++---
4 files changed, 71 insertions(+), 34 deletions(-)

diff --git a/Makefile b/Makefile @@ -2,7 +2,7 @@ PREFIX ?= /usr/local LIBDIR ?= /lib INCLDIR ?= /include -CFLAGS = -I include +CFLAGS = -I include -std=c99 CFLAGS += -Wunused-function -Wunused-variable -Wno-prototype CFLAGS += -Wconversion -Wsign-compare -Werror diff --git a/include/list.h b/include/list.h @@ -1,7 +1,8 @@ #pragma once #include <stdbool.h> -#include <stdlib.h> +#include <sys/types.h> +#include <stddef.h> #define LIST_LINK_INIT ((struct list_link) { 0 }) @@ -66,8 +67,14 @@ struct list_link *list_link_pop(struct list_link *link); struct list_link *list_iter_fwd(struct list_link *link, size_t n); struct list_link *list_iter_bwd(struct list_link *link, size_t n); -void list_link_prepend(struct list_link *list, struct list_link *link); -void list_link_append(struct list_link *list, struct list_link *link); +static inline void list_link_prepend(struct list_link *a, struct list_link *b); +static inline void list_link_append(struct list_link *a, struct list_link *b); + +static inline void list_link_attach_next(struct list_link *a, struct list_link *b); +static inline void list_link_attach_prev(struct list_link *a, struct list_link *b); + +static inline void list_link_detach_next(struct list_link *link); +static inline void list_link_detach_prev(struct list_link *link); static inline struct list_link * list_front(const struct list *list) @@ -125,3 +132,60 @@ list_insert_back(struct list *list, struct list_link *link) list_link_prepend(&list->tail, link); } +/* attach b before a: b -> a */ +static inline void +list_link_prepend(struct list_link *a, struct list_link *b) +{ + list_link_attach_prev(a, b); +} + +/* attach b after a: a -> b */ +static inline void +list_link_append(struct list_link *a, struct list_link *b) +{ + list_link_attach_next(a, b); +} + +/* attach b before a: b -> a */ +static inline void +list_link_attach_prev(struct list_link *a, struct list_link *b) +{ + LIST_ABORT_ON_ARGS(!a || !b); + + b->prev = a->prev; + b->next = a; + + if (b->prev) b->prev->next = b; + a->prev = b; +} + +/* attach b after a: a -> b */ +static inline void +list_link_attach_next(struct list_link *a, struct list_link *b) +{ + LIST_ABORT_ON_ARGS(!a || !b); + + b->next = a->next; + b->prev = a; + + if (b->next) b->next->prev = b; + a->next = b; +} + +static inline void +list_link_detach_next(struct list_link *link) +{ + LIST_ABORT_ON_ARGS(!link); + + if (link->next) link->next->prev = NULL; + link->next = NULL; +} + +static inline void +list_link_detach_prev(struct list_link *link) +{ + LIST_ABORT_ON_ARGS(!link); + + if (link->prev) link->prev->next = NULL; + link->prev = NULL; +} diff --git a/src/list.c b/src/list.c @@ -196,30 +196,3 @@ list_iter_bwd(struct list_link *link, size_t n) return link; } -void -list_link_prepend(struct list_link *cur, struct list_link *link) -{ - LIST_ABORT_ON_ARGS(!cur || !link); - - link->prev = cur->prev; - link->next = cur; - - if (link->prev) - link->prev->next = link; - if (link->next) - link->next->prev = link; -} - -void -list_link_append(struct list_link *cur, struct list_link *link) -{ - LIST_ABORT_ON_ARGS(!cur || !link); - - link->prev = cur; - link->next = cur->next; - - if (link->prev) - link->prev->next = link; - if (link->next) - link->next->prev = link; -} diff --git a/src/test.c b/src/test.c @@ -11,9 +11,9 @@ struct arg { }; bool -test_sort(struct list_link *link1, struct list_link *link2) +test_sort(const struct list_link *link1, const struct list_link *link2) { - struct arg *arg1, *arg2; + const struct arg *arg1, *arg2; arg1 = LIST_UPCAST(link1, struct arg, link); arg2 = LIST_UPCAST(link2, struct arg, link); @@ -41,7 +41,7 @@ main(int argc, const char **argv) if (!item) return 0; item->str = *arg; item->link = LIST_LINK_INIT; - list_push_back(&list, &item->link); + list_insert_back(&list, &item->link); } list_insertion_sort(&list, atoi(argv[1]), test_sort);