data-structures-c
Loading...
Searching...
No Matches
list.h
Go to the documentation of this file.
1/* list.h
2 *
3 * Copyright (C) 2023 abxh
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 * See the file LICENSE included with this distribution for more
10 * information. */
11
20#pragma once
21
22#include "container_of.h" // container_of
23
24#include <assert.h>
25#include <stdbool.h>
26#include <stddef.h>
27
31struct list_node {
34};
35
46#define list_node_entry(ptr, type, member) container_of(ptr, type, member)
47
49
50// Add a node between two (known) nodes.
51static inline void internal_list_node_add_between(struct list_node *node_ptr, struct list_node *before_ptr,
52 struct list_node *after_ptr);
53
54// Attach two nodes together, so anything in between is ignored.
55static inline void internal_list_node_attach(struct list_node *prev_ptr, struct list_node *next_ptr);
56
58
64static inline void list_node_init(struct list_node *node_ptr)
65{
66 assert(node_ptr != NULL);
67
68 node_ptr->prev_ptr = node_ptr->next_ptr = node_ptr;
69}
70
79static inline bool list_node_is_first(const struct list_node *node_ptr, const struct list_node *head_ptr)
80{
81 assert(node_ptr != NULL);
82 assert(head_ptr != NULL);
83
84 return node_ptr->prev_ptr == head_ptr;
85}
86
96static inline bool list_node_is_last(const struct list_node *node_ptr, const struct list_node *tail_ptr)
97{
98 assert(node_ptr != NULL);
99 assert(tail_ptr != NULL);
100
101 return node_ptr->next_ptr == tail_ptr;
102}
103
112static inline bool list_node_is_head(const struct list_node *node_ptr, const struct list_node *head_ptr)
113{
114 assert(node_ptr != NULL);
115 assert(head_ptr != NULL);
116
117 return node_ptr == head_ptr;
118}
119
128static inline bool list_node_is_tail(const struct list_node *node_ptr, const struct list_node *tail_ptr)
129{
130 assert(node_ptr != NULL);
131 assert(tail_ptr != NULL);
132
133 return node_ptr == tail_ptr;
134}
135
144static inline void list_node_add_after(struct list_node *node_ptr, struct list_node *prev_ptr)
145{
146 assert(node_ptr != NULL);
147 assert(prev_ptr != NULL);
148
149 internal_list_node_add_between(node_ptr, prev_ptr, prev_ptr->next_ptr);
150}
151
160static inline void list_node_add_before(struct list_node *node_ptr, struct list_node *next_ptr)
161{
162 assert(node_ptr != NULL);
163 assert(next_ptr != NULL);
164
165 internal_list_node_add_between(node_ptr, next_ptr->prev_ptr, next_ptr);
166}
167
179static inline struct list_node *list_node_remove(struct list_node *node_ptr)
180{
181 assert(node_ptr != NULL);
182 assert(node_ptr->prev_ptr != node_ptr);
183 assert(node_ptr->next_ptr != node_ptr);
184
185 internal_list_node_attach(node_ptr->prev_ptr, node_ptr->next_ptr);
186 list_node_init(node_ptr);
187
188 return node_ptr;
189}
190
201static inline void list_node_replace(struct list_node *old_ptr, struct list_node *new_ptr)
202{
203 assert(old_ptr != NULL);
204 assert(new_ptr != NULL);
205 assert(old_ptr != new_ptr);
206 assert(old_ptr->prev_ptr != old_ptr);
207 assert(old_ptr->next_ptr != old_ptr);
208
209 internal_list_node_add_between(new_ptr, old_ptr->prev_ptr, old_ptr->next_ptr);
210 list_node_init(old_ptr);
211}
212
214
215static inline void internal_list_node_add_between(struct list_node *node_ptr, struct list_node *before_ptr,
216 struct list_node *after_ptr)
217{
218 assert(node_ptr != NULL);
219 assert(before_ptr != NULL);
220 assert(after_ptr != NULL);
221
222 before_ptr->next_ptr = node_ptr;
223 node_ptr->prev_ptr = before_ptr;
224
225 after_ptr->prev_ptr = node_ptr;
226 node_ptr->next_ptr = after_ptr;
227}
228
229static inline void internal_list_node_attach(struct list_node *prev_ptr, struct list_node *next_ptr)
230{
231 assert(prev_ptr != NULL);
232 assert(next_ptr != NULL);
233
236}
237
239
240// vim: ft=c
container_of definition
static void list_node_add_after(struct list_node *node_ptr, struct list_node *prev_ptr)
Add a node after the given node.
Definition list.h:144
static bool list_node_is_head(const struct list_node *node_ptr, const struct list_node *head_ptr)
Check if a given list node is the head of the list.
Definition list.h:112
static bool list_node_is_last(const struct list_node *node_ptr, const struct list_node *tail_ptr)
Check if a given list node is the last of the list (aka before the tail).
Definition list.h:96
static bool list_node_is_first(const struct list_node *node_ptr, const struct list_node *head_ptr)
Check if a given list node is first in the list (aka after the head).
Definition list.h:79
static bool list_node_is_tail(const struct list_node *node_ptr, const struct list_node *tail_ptr)
Check if a given list node is the tail of the list.
Definition list.h:128
static void list_node_add_before(struct list_node *node_ptr, struct list_node *next_ptr)
Add a node before the given node.
Definition list.h:160
static struct list_node * list_node_remove(struct list_node *node_ptr)
Remove a node and deattach it from the list it resides in.
Definition list.h:179
static void list_node_replace(struct list_node *old_ptr, struct list_node *new_ptr)
Replace a given node by a new node.
Definition list.h:201
static void list_node_init(struct list_node *node_ptr)
Initialize a list node.
Definition list.h:64
Intrusive list node structure.
Definition list.h:31
struct list_node * next_ptr
next node pointer.
Definition list.h:33
struct list_node * prev_ptr
prev node pointer.
Definition list.h:32