1*76404edcSAsim Jamshed #pragma once
2*76404edcSAsim Jamshed 
3*76404edcSAsim Jamshed #include <assert.h>
4*76404edcSAsim Jamshed 
5*76404edcSAsim Jamshed #define _TREE_NODE(type, qual) \
6*76404edcSAsim Jamshed struct { \
7*76404edcSAsim Jamshed 	qual type *tn_parent;   /* parent */ \
8*76404edcSAsim Jamshed 	qual type *tn_first;    /* first child */ \
9*76404edcSAsim Jamshed 	qual type *tn_last;     /* last child */ \
10*76404edcSAsim Jamshed 	qual type *tn_younger;  /* younger sibling */ \
11*76404edcSAsim Jamshed 	qual type *tn_older;    /* older sibling */ \
12*76404edcSAsim Jamshed }
13*76404edcSAsim Jamshed #define TREE_NODE(type) _TREE_NODE(struct type,)
14*76404edcSAsim Jamshed 
15*76404edcSAsim Jamshed #define _TREE_SCRATCH(type, qual, size) \
16*76404edcSAsim Jamshed union { \
17*76404edcSAsim Jamshed 	struct { \
18*76404edcSAsim Jamshed 		qual type *stack[(size)]; \
19*76404edcSAsim Jamshed 		qual type **sp; \
20*76404edcSAsim Jamshed 	}; \
21*76404edcSAsim Jamshed 	struct { \
22*76404edcSAsim Jamshed 		qual type *queue[(size)]; \
23*76404edcSAsim Jamshed 		qual type **head; \
24*76404edcSAsim Jamshed 		qual type **tail; \
25*76404edcSAsim Jamshed 	}; \
26*76404edcSAsim Jamshed }
27*76404edcSAsim Jamshed #define TREE_SCRATCH(type, size) _TREE_SCRATCH(struct type, , size)
28*76404edcSAsim Jamshed 
29*76404edcSAsim Jamshed #define TREE_INIT_NODE(elm, field) do { \
30*76404edcSAsim Jamshed 	(elm)->field.tn_parent = NULL; \
31*76404edcSAsim Jamshed 	(elm)->field.tn_first = NULL; \
32*76404edcSAsim Jamshed 	(elm)->field.tn_last = NULL; \
33*76404edcSAsim Jamshed 	(elm)->field.tn_younger = NULL; \
34*76404edcSAsim Jamshed 	(elm)->field.tn_older = NULL; \
35*76404edcSAsim Jamshed } while (0)
36*76404edcSAsim Jamshed 
37*76404edcSAsim Jamshed #define TREE_INSERT_CHILD(treeelm, elm, field) do { \
38*76404edcSAsim Jamshed 	(elm)->field.tn_parent = (treeelm); \
39*76404edcSAsim Jamshed 	if ((treeelm)->field.tn_last != NULL) { \
40*76404edcSAsim Jamshed 		(treeelm)->field.tn_last->field.tn_younger = (elm); \
41*76404edcSAsim Jamshed 		(elm)->field.tn_older = (treeelm)->field.tn_last; \
42*76404edcSAsim Jamshed 	} \
43*76404edcSAsim Jamshed 	(treeelm)->field.tn_last = (elm); \
44*76404edcSAsim Jamshed 	if ((treeelm)->field.tn_first == NULL) \
45*76404edcSAsim Jamshed 		(treeelm)->field.tn_first = (elm); \
46*76404edcSAsim Jamshed } while (0)
47*76404edcSAsim Jamshed 
48*76404edcSAsim Jamshed #define TREE_INSERT_YOUNGER(treeelm, elm, field) do { \
49*76404edcSAsim Jamshed 	(elm)->field.tn_parent = (treeelm)->field.tn_parent; \
50*76404edcSAsim Jamshed 	if ((treeelm)->field.tn_younger != NULL) { \
51*76404edcSAsim Jamshed 		(elm)->field.tn_younger = (treeelm)->field.tn_younger; \
52*76404edcSAsim Jamshed 		(elm)->field.tn_younger->field.tn_older = (elm); \
53*76404edcSAsim Jamshed 	} \
54*76404edcSAsim Jamshed 	else if ((treeelm)->field.tn_parent != NULL) \
55*76404edcSAsim Jamshed 		(treeelm)->field.tn_parent->field.tn_last = (elm); \
56*76404edcSAsim Jamshed 	(treeelm)->field.tn_younger = (elm); \
57*76404edcSAsim Jamshed 	(elm)->field.tn_older = (treeelm); \
58*76404edcSAsim Jamshed } while (0)
59*76404edcSAsim Jamshed 
60*76404edcSAsim Jamshed #define TREE_INSERT_OLDER(treeelm, elm, field) do { \
61*76404edcSAsim Jamshed 	(elm)->field.tn_parent = (treeelm)->field.tn_parent; \
62*76404edcSAsim Jamshed 	if ((treeelm)->field.tn_older != NULL) { \
63*76404edcSAsim Jamshed 		(elm)->field.tn_older = (treeelm)->field.tn_older; \
64*76404edcSAsim Jamshed 		(elm)->field.tn_older->field.tn_younger = (elm); \
65*76404edcSAsim Jamshed 	} \
66*76404edcSAsim Jamshed 	else if ((treeelm)->field.tn_parent != NULL) \
67*76404edcSAsim Jamshed 		(treeelm)->field.tn_parent->field.tn_first = (elm); \
68*76404edcSAsim Jamshed 	(treeelm)->field.tn_older = (elm); \
69*76404edcSAsim Jamshed 	(elm)->field.tn_younger = (treeelm); \
70*76404edcSAsim Jamshed } while (0)
71*76404edcSAsim Jamshed 
72*76404edcSAsim Jamshed #define TREE_DETACH(elm, field) do { \
73*76404edcSAsim Jamshed 	if ((elm)->field.tn_parent) { \
74*76404edcSAsim Jamshed 		if ((elm)->field.tn_parent->field.tn_first == (elm)) \
75*76404edcSAsim Jamshed 			(elm)->field.tn_parent->field.tn_first = (elm)->field.tn_younger; \
76*76404edcSAsim Jamshed 		if ((elm)->field.tn_parent->field.tn_last == (elm)) \
77*76404edcSAsim Jamshed 			(elm)->field.tn_parent->field.tn_last = (elm)->field.tn_older; \
78*76404edcSAsim Jamshed 	} \
79*76404edcSAsim Jamshed 	if ((elm)->field.tn_younger) \
80*76404edcSAsim Jamshed 		(elm)->field.tn_younger->field.tn_older = (elm)->field.tn_older; \
81*76404edcSAsim Jamshed 	if ((elm)->field.tn_older) \
82*76404edcSAsim Jamshed 		(elm)->field.tn_older->field.tn_younger = (elm)->field.tn_younger; \
83*76404edcSAsim Jamshed 	(elm)->field.tn_older = (elm)->field.tn_younger = NULL; \
84*76404edcSAsim Jamshed 	(elm)->field.tn_parent = NULL; \
85*76404edcSAsim Jamshed } while (0)
86*76404edcSAsim Jamshed 
87*76404edcSAsim Jamshed #define __TREE_DFS_PUSH(scratch, var) \
88*76404edcSAsim Jamshed 	(assert(&(scratch)->stack[sizeof((scratch)->stack)] > (scratch)->sp), \
89*76404edcSAsim Jamshed 	 *(++((scratch)->sp)) = (var))
90*76404edcSAsim Jamshed #define __TREE_DFS_POP(scratch) \
91*76404edcSAsim Jamshed 	(*(((scratch)->sp)--))
92*76404edcSAsim Jamshed 
93*76404edcSAsim Jamshed #define TREE_DFS_FOREACH(var, root, scratch, field) \
94*76404edcSAsim Jamshed 	for ((scratch)->stack[0] = NULL, (scratch)->sp = (scratch)->stack, \
95*76404edcSAsim Jamshed 		(var) = (root); (var); \
96*76404edcSAsim Jamshed 		(var) = (var)->field.tn_first \
97*76404edcSAsim Jamshed 		? ((((var)->field.tn_younger && (var) != (root)) \
98*76404edcSAsim Jamshed 			? __TREE_DFS_PUSH(scratch, (var)->field.tn_younger) : 0), \
99*76404edcSAsim Jamshed 		   (var)->field.tn_first) \
100*76404edcSAsim Jamshed 		: ((var)->field.tn_younger && (var) != (root)) \
101*76404edcSAsim Jamshed 			? (var)->field.tn_younger : __TREE_DFS_POP(scratch))
102*76404edcSAsim Jamshed 
103*76404edcSAsim Jamshed #define TREE_DFS_FOREACH_SELECTIVE(var, root, scratch, field, sel) \
104*76404edcSAsim Jamshed 	for ((scratch)->stack[0] = NULL, (scratch)->sp = (scratch)->stack, \
105*76404edcSAsim Jamshed 		(var) = (root); (sel = true, var); \
106*76404edcSAsim Jamshed 		(var) = ((sel) && (var)->field.tn_first) \
107*76404edcSAsim Jamshed 		? ((((var)->field.tn_younger && (var) != (root)) \
108*76404edcSAsim Jamshed 			? __TREE_DFS_PUSH(scratch, (var)->field.tn_younger) : 0), \
109*76404edcSAsim Jamshed 		   (var)->field.tn_first) \
110*76404edcSAsim Jamshed 		: ((var)->field.tn_younger && (var) != (root)) \
111*76404edcSAsim Jamshed 			? (var)->field.tn_younger : __TREE_DFS_POP(scratch))
112*76404edcSAsim Jamshed 
113*76404edcSAsim Jamshed #define __TREE_BFS_ENQUEUE(scratch, var) \
114*76404edcSAsim Jamshed 	(*(((scratch)->tail)++) = (var))
115*76404edcSAsim Jamshed #define __TREE_BFS_DEQUEUE(scratch) \
116*76404edcSAsim Jamshed 	(*(((scratch)->head)++))
117*76404edcSAsim Jamshed 
118*76404edcSAsim Jamshed #define TREE_BFS_FOREACH(var, root, scratch, field) \
119*76404edcSAsim Jamshed 	for ((scratch)->head = (scratch)->tail = (scratch)->queue, \
120*76404edcSAsim Jamshed 		(var) = (root); (var); \
121*76404edcSAsim Jamshed 		(var) = (var)->field.tn_first \
122*76404edcSAsim Jamshed 		? (var)->field.tn_younger \
123*76404edcSAsim Jamshed 			? /* enqueue, the younger */ \
124*76404edcSAsim Jamshed 			  (__TREE_BFS_ENQUEUE(scratch, (var)->field.tn_first), \
125*76404edcSAsim Jamshed 			   (var)->field.tn_younger) \
126*76404edcSAsim Jamshed 			: (scratch)->head != (scratch)->tail \
127*76404edcSAsim Jamshed 				? /* enqueue, dequeue */ \
128*76404edcSAsim Jamshed 				  (__TREE_BFS_ENQUEUE(scratch, (var)->field.tn_first), \
129*76404edcSAsim Jamshed 				   __TREE_BFS_DEQUEUE(scratch)) \
130*76404edcSAsim Jamshed 				: /* the first */ \
131*76404edcSAsim Jamshed 				  (var)->field.tn_first \
132*76404edcSAsim Jamshed 		: (var)->field.tn_younger \
133*76404edcSAsim Jamshed 			? /* the younger */ \
134*76404edcSAsim Jamshed 			  (var)->field.tn_younger \
135*76404edcSAsim Jamshed 			: (scratch)->head != (scratch)->tail \
136*76404edcSAsim Jamshed 				? /* dequeue */ \
137*76404edcSAsim Jamshed 				  __TREE_BFS_DEQUEUE(scratch) \
138*76404edcSAsim Jamshed 				: NULL)
139*76404edcSAsim Jamshed 
140*76404edcSAsim Jamshed #define TREE_BFS_FOREACH_SELECTIVE(var, root, scratch, field, sel) \
141*76404edcSAsim Jamshed 	for ((scratch)->head = (scratch)->tail = (scratch)->queue, \
142*76404edcSAsim Jamshed 		(var) = (root); (sel = true, var); \
143*76404edcSAsim Jamshed 		(var) = ((sel) && (var)->field.tn_first) \
144*76404edcSAsim Jamshed 		? (var)->field.tn_younger \
145*76404edcSAsim Jamshed 			? /* enqueue, the younger */ \
146*76404edcSAsim Jamshed 			  (__TREE_BFS_ENQUEUE(scratch, (var)->field.tn_first), \
147*76404edcSAsim Jamshed 			   (var)->field.tn_younger) \
148*76404edcSAsim Jamshed 			: (scratch)->head != (scratch)->tail \
149*76404edcSAsim Jamshed 				? /* enqueue, dequeue */ \
150*76404edcSAsim Jamshed 				  (__TREE_BFS_ENQUEUE(scratch, (var)->field.tn_first), \
151*76404edcSAsim Jamshed 				   __TREE_BFS_DEQUEUE(scratch)) \
152*76404edcSAsim Jamshed 				: /* the first */ \
153*76404edcSAsim Jamshed 				  (var)->field.tn_first \
154*76404edcSAsim Jamshed 		: (var)->field.tn_younger \
155*76404edcSAsim Jamshed 			? /* the younger */ \
156*76404edcSAsim Jamshed 			  (var)->field.tn_younger \
157*76404edcSAsim Jamshed 			: (scratch)->head != (scratch)->tail \
158*76404edcSAsim Jamshed 				? /* dequeue */ \
159*76404edcSAsim Jamshed 				  __TREE_BFS_DEQUEUE(scratch) \
160*76404edcSAsim Jamshed 				: NULL)
161*76404edcSAsim Jamshed 
162*76404edcSAsim Jamshed #define TREE_FIRSTBORN(ent, field) ((ent)->field.tn_first)
163*76404edcSAsim Jamshed #define TREE_LASTBORN(ent, field)  ((ent)->field.tn_last)
164*76404edcSAsim Jamshed #define TREE_YOUNGER(ent, field)   ((ent)->field.tn_younger)
165*76404edcSAsim Jamshed #define TREE_OLDER(ent, field)     ((ent)->field.tn_older)
166*76404edcSAsim Jamshed #define TREE_PARENT(ent, field)    ((ent)->field.tn_parent)
167*76404edcSAsim Jamshed 
168