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