1 #ifndef __LIST_H__
2 #define __LIST_H__
3
4 typedef struct LIST LIST;
5 struct LIST
6 {
7 LIST *next;
8 LIST *prev;
9 };
10
11 typedef struct LIST_HEAD
12 {
13 int count;
14 LIST first;
15 } LIST_HEAD;
16
17 #define DO_LIST_INIT(name) \
18 { &(name), &(name)}
19
20 #define LIST_INIT(head) \
21 LIST head = DO_LIST_INIT(head)
22
23 #define INIT_LIST(head) \
24 do { (head)->next = (head); (head)->prev = (head); } while (0)
25
26 // list is first member of struct
27 #define LIST_ITEM_PTR_CAST(list_ptr, item_type) ((item_type *)(list_ptr) )
28
29 // list is not first member of struct
30 #define LIST_ITEM_PTR(list_ptr, item_type, list_member) \
31 ((item_type *)((char *)(list_ptr)-(unsigned int)(&((item_type *)0)->list_member)))
32
33 LIST * list_get_prev(LIST *entry);
34 LIST * list_get_next(LIST *entry);
35
36 unsigned int list_is_empty(LIST *head);
37 unsigned int list_is_empty_careful(LIST *head);
38 unsigned int list_is_last(LIST *entry, LIST *head);
39
40 void list_item_add(LIST_HEAD * head, LIST * item);
41 void list_item_del(LIST_HEAD * head, LIST * item);
42
43 void list_add_after_head(LIST *entry, LIST *head); // head entry ... tail
44 void list_add_before_head(LIST *entry, LIST *head); // entry head ... tail
45
46 void list_add_after(LIST *entry, LIST * where);
47 void list_add_before(LIST *entry, LIST * where);
48
49 void list_del_after_head(LIST *head);
50 void list_del_before_head(LIST *head);
51 void list_del(LIST *entry);
52
53 void list_splice_after_head(LIST * list, LIST * head);
54 void list_splice_before_head(LIST * list, LIST * head);
55
56 void list_replace(LIST *old, LIST *new);
57
58 void list_move_after_head(LIST *entry, LIST *head);
59 void list_move_before_head(LIST *entry, LIST *head);
60
61 void list_init(LIST *list); // INIT_LIST(list)
62
63 #endif /* __LIST_H__ */
1 #include "list.h"
2
3 unsigned int list_is_empty(LIST *head)
4 {
5 return head->next == head;
6 }
7
8 unsigned int list_is_empty_careful(LIST *head)
9 {
10 LIST *next = head->next;
11 return ( next == head ) && ( next == head->prev );
12 }
13
14 unsigned int list_is_last(LIST *entry, LIST *head)
15 {
16 return entry->next == head;
17 }
18
19 LIST * list_get_prev(LIST *entry)
20 {
21 return entry->prev;
22 }
23
24 LIST * list_get_next(LIST *entry)
25 {
26 return entry->next;
27 }
28
29 void __list_add(LIST *entry, LIST *prev, LIST *next)
30 {
31 next->prev = entry;
32 entry->next = next;
33 entry->prev = prev;
34 prev->next = entry;
35 }
36
37 // head entry ... tail
38 void list_add_after_head(LIST *entry, LIST *head)
39 {
40 __list_add( entry, head, head->next );
41 }
42
43 // entry head ... tail
44 void list_add_before_head(LIST *entry, LIST *head)
45 {
46 __list_add( entry, head->prev, head );
47 }
48
49 // ... where entry ...
50 void list_add_after(LIST *entry, LIST * where)
51 {
52 list_add_after_head( entry, where );
53 }
54
55 // ... entry where ...
56 void list_add_before(LIST *entry, LIST * where)
57 {
58 list_add_before_head( entry, where );
59 }
60
61 void __list_del(LIST *prev, LIST *next)
62 {
63 next->prev = prev;
64 prev->next = next;
65 }
66
67 // head [ **entry** ] ... tail
68 void list_del_after_head(LIST *head)
69 {
70 __list_del( head, head->next );
71 }
72
73 // [ **entry** ] head ... tail
74 void list_del_before_head(LIST *head)
75 {
76 __list_del( head->prev, head );
77 }
78
79 // ... [ **entry** ] ...
80 void list_del(LIST *entry)
81 {
82 __list_del( entry->prev, entry->next );
83 INIT_LIST( entry );
84 }
85
86 // prev : list->next list->prev : next
87 void __list_splice(const LIST *list, LIST *prev, LIST *next)
88 {
89 LIST *first = list->next;
90 LIST *last = list->prev;
91
92 first->prev = prev;
93 prev->next = first;
94
95 last->next = next;
96 next->prev = last;
97
98 }
99
100 // head list_tail ... list_head ... tail
101 void list_splice_after_head(LIST * list, LIST * head)
102 {
103 if (!list_is_empty( list ))
104 {
105 __list_splice( list, head, head->next );
106 INIT_LIST( list );
107 }
108 }
109
110 // list_tail ... list_head --- head ... tail
111 void list_splice_before_head(LIST * list, LIST * head)
112 {
113 if (!list_is_empty( list ))
114 {
115 __list_splice( list, head->prev, head );
116 INIT_LIST( list );
117 }
118 }
119
120 void list_replace(LIST *old, LIST *new)
121 {
122 new->next = old->next;
123 new->next->prev = new;
124 new->prev = old->prev;
125 new->prev->next = new;
126 INIT_LIST( old );
127 }
128
129 // head --- entry --- ... --- tail
130 void list_move_after_head(LIST *entry, LIST *head)
131 {
132 __list_del( entry, head );
133 list_add_after_head( entry, head );
134 }
135
136 // head --- ... --- tail --- entry
137 void list_move_before_head(LIST *entry, LIST *head)
138 {
139 __list_del( entry, head );
140 list_add_before_head( entry, head );
141 }
142
143 void list_init(LIST *list)
144 {
145 list->next = list;
146 list->prev = list;
147 }
148
149 void list_item_add(LIST_HEAD * head, LIST * item)
150 {
151 // head --> 0 --> 1 --> 2 --> 3 --> head
152 list_add_before_head( item, & ( head->first ) );
153 head->count++;
154 }
155
156 void list_item_del(LIST_HEAD * head, LIST * item)
157 {
158 list_del( item );
159 head->count--;
160 }
161
162 #define LIST_ITEM_COUNT ( 3 )
163 void list_demo(void)
164 {
165 typedef struct ITEM
166 {
167 LIST list;
168 int a;
169 } ITEM;
170
171 LIST_HEAD head;
172 ITEM items [ LIST_ITEM_COUNT ];
173
174 head.count = 0;
175 INIT_LIST( &head.first );
176
177 // head --> 0 --> 1 --> 2 --> 3 --> head
178 for (unsigned int i = 0; i < LIST_ITEM_COUNT; i++)
179 {
180 list_item_add( &head, &items [ i ].list );
181 }
182
183 unsigned int i = 0;
184 for (LIST * entry = head.first.next; entry != &head.first; entry =
185 entry->next)
186 {
187 LIST_ITEM_PTR(entry, ITEM, list) ->a = i++;
188 //LIST_ITEM_PTR_CAST(entry, ITEM) ->a = i++;
189 }
190
191 list_item_del( &head, &items [ LIST_ITEM_COUNT - 2 ].list );
192 list_item_del( &head, &items [ LIST_ITEM_COUNT - 1 ].list );
193 list_item_del( &head, &items [ 0 ].list );
194 }