genclibs/linked_list.h
2024-10-14 15:26:57 +02:00

93 lines
2.9 KiB
C

#pragma once
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#define container_of(ptr, type, member) ((type *) ((uint8_t *)(ptr) - offsetof(type, member)))
typedef struct linked_list {
struct linked_list *prev;
struct linked_list *next;
} linked_list_t;
static inline void linked_list_init_head(linked_list_t *head){
head->prev = head;
head->next = head;
}
static inline void linked_list_add_internal(linked_list_t *prev, linked_list_t *elem, linked_list_t *next){
prev->next = elem;
elem->prev = prev;
elem->next = next;
next->prev = elem;
}
[[maybe_unused]] static inline void linked_list_add_head(linked_list_t *head, linked_list_t *elem){
linked_list_add_internal(head, elem, head->next);
}
[[maybe_unused]] static inline void linked_list_add_tail(linked_list_t *elem, linked_list_t *head)
{
linked_list_add_internal(head->prev, elem, head);
}
[[maybe_unused]] static inline bool list_empty(linked_list_t const *list){
return list->next == list;
}
static inline void linked_list_del_internal(linked_list_t *prev, linked_list_t *next){
next->prev = prev;
prev->next = next;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty on entry does not return true after this, the entry is
* in an undefined state.
*/
[[maybe_unused]] static inline void linked_list_del(linked_list_t *elem){
linked_list_del_internal(elem->prev, elem->next);
elem->next = NULL;
elem->prev = NULL;
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
[[maybe_unused]] static inline void linked_list_extract(linked_list_t *elem){
linked_list_del_internal(elem->prev, elem->next);
linked_list_init_head(elem);
}
/**
* list_for_each_entry - iterate over list of given type
* @current_elem: the type * to use as a loop counter.
* @list: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(current_elem, list, member) \
for (current_elem = container_of((list)->next, typeof(*current_elem), member); \
&current_elem->member != (list); \
current_elem = container_of(current_elem->member.next, typeof(*current_elem), member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @current_elem: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @list: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(current_elem, n, list, member) \
for (current_elem = container_of((list)->next, typeof(*current_elem), member), \
n = container_of(current_elem->member.next, typeof(*current_elem), member); \
&current_elem->member != (list); \
current_elem = n, n = container_of(n->member.next, typeof(*n), member))