]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/linkedlist.qh
Merge branch 'master' into TimePath/items
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / linkedlist.qh
1 #ifndef LINKEDLIST_H
2 #define LINKEDLIST_H
3
4 CLASS(LinkedListNode, Object)
5     ATTRIB(LinkedListNode, ll_data, entity, NULL)
6     ATTRIB(LinkedListNode, ll_prev, LinkedListNode, NULL)
7     ATTRIB(LinkedListNode, ll_next, LinkedListNode, NULL)
8 ENDCLASS(LinkedListNode)
9
10 CLASS(LinkedList, Object)
11     ATTRIB(LinkedList, ll_head, LinkedListNode, NULL);
12     ATTRIB(LinkedList, ll_tail, LinkedListNode, NULL);
13 ENDCLASS(LinkedList)
14
15 #define LL_NEW() NEW(LinkedList)
16
17 /**
18  * Push to tail
19  */
20 entity LL_PUSH(LinkedList this, entity e) {
21     LinkedListNode n = NEW(LinkedListNode);
22     n.ll_data = e;
23     n.ll_prev = this.ll_tail;
24     LinkedListNode tail = this.ll_tail;
25     if (tail) {
26         tail.ll_next = n;
27     } else {
28         this.ll_head = this.ll_tail = n;
29     }
30     return e;
31 }
32
33 /**
34  * Pop from tail
35  */
36 entity LL_POP(LinkedList this) {
37     if (!this.ll_tail) return NULL;
38     LinkedListNode n = this.ll_tail;
39     entity e = n.ll_data;
40     LinkedListNode prev = n.ll_prev;
41     if (prev) {
42         prev.ll_next = NULL;
43     } else {
44         this.ll_head = this.ll_tail = NULL;
45     }
46     return e;
47 }
48
49 #define LL_EACH(list, cond, body) do {                                  \
50     noref int i = 0;                                                    \
51     for (entity _it = list.ll_head; _it; (_it = _it.ll_next, ++i)) {    \
52         noref entity it = _it.ll_data;                                  \
53         if (cond) { body }                                              \
54     }                                                                   \
55 } while(0)
56
57 #endif