93 lines
2.9 KiB
C
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); \
|
|
¤t_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); \
|
|
¤t_elem->member != (list); \
|
|
current_elem = n, n = container_of(n->member.next, typeof(*n), member))
|