#ifndef LIST_H
#define LIST_H

#include <stddef.h>

/* from linux kernel (with some changes for "iso" c) */

typedef struct listhead listhead;
struct listhead {
	listhead *prev, *next;
};

#define container_of(ptr, type, member) ((type*) ((char*) (__typeof__(((type*) 0)->member)*) (ptr) - offsetof(type, member)))

/**
 * list_entry - get the struct for this entry
 * @ptr:    the &struct list_head pointer.
 * @type:   the type of the struct this is embedded in.
 * @member: the name of the list_struct within the struct.
 */
#define list_entry(ptr, type, member) container_of(ptr, type, member)

void alloc_things(void);
void* _allocentry(size_t size);
#define allocentry(type) (type*) _allocentry(sizeof(type))
void freeentry(void* ptr);

void list_add_tail(listhead* header, listhead* entry);
#define addtail(head, entry) list_add_tail(head, &(entry->list));

/* remove entry from list */
void list_del(listhead* entry);
#define removeitem(entry) list_del(&(entry->list));

void list_init_head(listhead* head);

void things_list_clear(listhead* head); /* listhead member must be the first member */

/**
 * list_for_each_entry - iterate over list of given type
 * @pos:    the type * to use as a loop cursor.
 * @head:   the head for your list.
 * @member: the name of the list_struct within the struct.
 */
#define list_for_each_entry(pos, head, member)                                                                                                                 \
	for (pos = list_entry((head)->next, __typeof__(*pos), member); /* prefetch(pos->member.next), */                                                           \
		 &pos->member != (head);                                                                                                                               \
		 pos = list_entry(pos->member.next, __typeof__(*pos), member))

/**
 * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
 * @pos:<-->the type * to use as a loop cursor.
 * @n:<><-->another type * to use as temporary storage
 * @head:<->the head for your list.
 * @member:>the name of the list_struct within the struct.
 */
#define list_for_each_entry_safe(pos, n, head, member)                                                                                                         \
	for (pos = list_entry((head)->next, __typeof__(*pos), member), n = list_entry(pos->member.next, __typeof__(*pos), member); &pos->member != (head);         \
		 pos = n, n = list_entry(n->member.next, __typeof__(*n), member))

#define list_empty(head) ((head) == (head)->next)

#endif
