mirror of
https://github.com/ish-app/ish.git
synced 2026-01-18 13:57:29 +00:00
86 lines
2.4 KiB
C
86 lines
2.4 KiB
C
#ifndef LIST_H
|
|
#define LIST_H
|
|
|
|
#include <unistd.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
|
|
struct list {
|
|
struct list *next, *prev;
|
|
};
|
|
|
|
static inline void list_init(struct list *list) {
|
|
list->next = list;
|
|
list->prev = list;
|
|
}
|
|
|
|
static inline bool list_null(struct list *list) {
|
|
return list->next == NULL && list->prev == NULL;
|
|
}
|
|
|
|
static inline bool list_empty(struct list *list) {
|
|
return list->next == list || list_null(list);
|
|
}
|
|
|
|
static inline void _list_add_between(struct list *prev, struct list *next, struct list *item) {
|
|
prev->next = item;
|
|
item->prev = prev;
|
|
item->next = next;
|
|
next->prev = item;
|
|
}
|
|
|
|
static inline void list_add(struct list *list, struct list *item) {
|
|
_list_add_between(list, list->next, item);
|
|
}
|
|
|
|
static inline void list_init_add(struct list *list, struct list *item) {
|
|
if (list_null(list))
|
|
list_init(list);
|
|
list_add(list, item);
|
|
}
|
|
|
|
static inline void list_remove(struct list *item) {
|
|
item->prev->next = item->next;
|
|
item->next->prev = item->prev;
|
|
item->next = item->prev = NULL;
|
|
}
|
|
|
|
static inline void list_remove_safe(struct list *item) {
|
|
if (!list_null(item))
|
|
list_remove(item);
|
|
}
|
|
|
|
#define list_entry(item, type, member) \
|
|
((type *) ((char *) (item) - offsetof(type, member)))
|
|
#define list_first_entry(list, type, member) \
|
|
list_entry((list)->next, type, member)
|
|
#define list_next_entry(item, member) \
|
|
list_entry((item)->member.next, typeof(*(item)), member)
|
|
|
|
#define list_for_each(list, item) \
|
|
for (item = (list)->next; item != (list); item = item->next)
|
|
#define list_for_each_safe(list, item, tmp) \
|
|
for (item = (list)->next, tmp = item->next; item != (list); \
|
|
item = tmp, tmp = item->next)
|
|
|
|
#define list_for_each_entry(list, item, member) \
|
|
for (item = list_entry((list)->next, typeof(*item), member); \
|
|
&item->member != (list); \
|
|
item = list_entry(item->member.next, typeof(*item), member))
|
|
#define list_for_each_entry_safe(list, item, tmp, member) \
|
|
for (item = list_first_entry(list, typeof(*(item)), member), \
|
|
tmp = list_next_entry(item, member); \
|
|
&item->member != (list); \
|
|
item = tmp, tmp = list_next_entry(item, member))
|
|
|
|
static inline int list_size(struct list *list) {
|
|
int count = 0;
|
|
struct list *item;
|
|
list_for_each(list, item) {
|
|
count++;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
#endif
|