2 * Copyright (c) 2005 Massachusetts Institute of Technology
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 #ifndef _KHIMAIRA_KHLIST_H
29 #define _KHIMAIRA_KHLIST_H
31 /* Note that most of these are "unsafe" macros. Not for general use */
41 (pe)->prev = NULL; } while(0)
43 #define LPUSH(pph,pe) \
47 if(*(pph)) (*(pph))->prev = (pe); \
48 (*(pph)) = (pe); } while(0)
50 #define LPOP(pph,ppe) \
53 if(*(pph)) *(pph) = (*(pph))->next; \
54 if(*(pph)) (*(pph))->prev = NULL; \
55 if(*(ppe)) (*(ppe))->next = NULL; \
58 #define LDELETE(pph,pe) \
60 if((pe)->prev) (pe)->prev->next = (pe)->next; \
61 if((pe)->next) (pe)->next->prev = (pe)->prev; \
62 if(*(pph) == (pe)) *(pph) = (pe)->next; \
63 (pe)->next = (pe)->prev = NULL; \
66 #define LEMPTY(pph) (*(pph) == NULL)
68 #define LNEXT(pe) ((pe)?(pe)->next:NULL)
70 #define LPREV(pe) ((pe)?(pe)->prev:NULL)
72 /* Trees with LIFO child lists */
80 (pe)->children = NULL; \
81 (pe)->parent = NULL; } while(0)
83 #define TADDCHILD(pt,pe) \
85 LPUSH(&((pt)->children),(pe)); \
86 (pe)->parent = (pt); } while(0)
88 #define TFIRSTCHILD(pt) ((pt)?(pt)->children:NULL)
90 #define TPOPCHILD(pt, ppe) \
92 LPOP(&((pt)->children), ppe); \
93 if(*(ppe)) (*(ppe))->parent = NULL; \
96 #define TDELCHILD(pt, pe) \
98 LDELETE(&((pt)->children), (pe)); \
99 (pe)->parent = NULL; } while(0)
101 #define TPARENT(pe) ((pe)?(pe)->parent:NULL)
110 (pq)->head = (pq)->tail = NULL; \
113 #define QPUT(pq, pe) \
115 LPUSH(&(pq)->tail, (pe)); \
116 if(!(pq)->head) (pq)->head = (pe); \
119 #define QGET(pq, ppe) \
121 *(ppe) = (pq)->head; \
123 (pq)->head = (*(ppe))->prev; \
124 if( (*(ppe))->prev ) (*(ppe))->prev->next = NULL; \
125 (*(ppe))->prev = NULL; \
126 if( (pq)->tail == *(ppe)) (pq)->tail = NULL; \
130 #define QDEL(pq, pe) \
132 if((pq)->head == (pe)) (pq)->head = LPREV(pe); \
133 LDELETE(&((pq)->tail), (pe)); \
137 #define QGETT(pq,ppe) \
139 *(ppe) = (pq)->tail; \
141 (pq)->tail = (*(ppe))->next; \
142 if( (*(ppe))->next ) (*(ppe))->next->prev = NULL; \
143 (*(ppe))->next = NULL; \
144 if( (pq)->head == *(ppe)) (pq)->head = NULL; \
148 #define QTOP(pq) ((pq)->head)
149 #define QBOTTOM(pq) ((pq)->tail)
150 #define QNEXT(pe) ((pe)->prev)
151 #define QPREV(pe) ((pe)->next)
153 /* Trees with FIFO child lists */
154 #define TQDCL(type) \
162 (pe)->parent = NULL; } while(0)
164 #define TQADDCHILD(pt,pe) \
167 (pe)->parent = (pt); } while(0)
169 #define TQFIRSTCHILD(pt) ((pt)?QTOP(pt):NULL)
171 #define TQPARENT(pe) ((pe)?(pe)->parent:NULL)