summaryrefslogtreecommitdiff
path: root/list.h
blob: b3a360170f2d05f511648499f9f28222e5adae84 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#ifndef LIST_H
#define LIST_H

/* Doubly linked lists */
typedef struct link_t link_t;
struct link_t
{
    link_t *next;
    link_t *prev;
};

typedef struct list_t list_t;
struct list_t
{
    link_t *head;
    link_t *tail;
};

static inline void
list_init (list_t *list)
{
    list->head = (link_t *)list;
    list->tail = (link_t *)list;
}

static inline void
list_prepend (list_t *list, link_t *link)
{
    link->next = list->head;
    link->prev = (link_t *)list;
    list->head->prev = link;
    list->head = link;
}

static inline void
list_append (list_t *list, link_t *link)
{
    link->prev = list->tail;
    link->next = (link_t *)list;
    list->tail->next = link;
    list->tail = link;
}

static inline void
list_unlink (link_t *link)
{
    link->prev->next = link->next;
    link->next->prev = link->prev;
}

static inline int
list_is_empty (list_t *list)
{
    return list->head == (link_t *)list;
}

static inline void
list_move_to_front (list_t *list, link_t *link)
{
    list_unlink (link);
    list_prepend (list, link);
}

#define LIST_FOREACH(list, link)					\
    for ((link) = (list)->head;						\
	 (link) != (link_t *)(list);					\
	 (link) = (link)->next)

#if defined(__GNUC__) && __GNUC__ >= 4
#   define OFFSET_OF(type, member)					\
    ((unsigned long)__builtin_offsetof(type, member))
#else
#   define OFFSET_OF(type, member)					\
    ((unsigned long)(&(((type *)0)->member))
#endif

#define CONTAINER_OF(type, member, data)				\
    ((type *)(((uint8_t *)data) - OFFSET_OF(type, member)))

#endif