]>
Commit | Line | Data |
---|---|---|
970d7e83 | 1 | /* Ring definitions. */ |
1a4d82fc | 2 | #define qr(a_type) \ |
970d7e83 LB |
3 | struct { \ |
4 | a_type *qre_next; \ | |
5 | a_type *qre_prev; \ | |
6 | } | |
7 | ||
8 | /* Ring functions. */ | |
1a4d82fc | 9 | #define qr_new(a_qr, a_field) do { \ |
970d7e83 LB |
10 | (a_qr)->a_field.qre_next = (a_qr); \ |
11 | (a_qr)->a_field.qre_prev = (a_qr); \ | |
12 | } while (0) | |
13 | ||
1a4d82fc | 14 | #define qr_next(a_qr, a_field) ((a_qr)->a_field.qre_next) |
970d7e83 | 15 | |
1a4d82fc | 16 | #define qr_prev(a_qr, a_field) ((a_qr)->a_field.qre_prev) |
970d7e83 | 17 | |
1a4d82fc | 18 | #define qr_before_insert(a_qrelm, a_qr, a_field) do { \ |
970d7e83 LB |
19 | (a_qr)->a_field.qre_prev = (a_qrelm)->a_field.qre_prev; \ |
20 | (a_qr)->a_field.qre_next = (a_qrelm); \ | |
21 | (a_qr)->a_field.qre_prev->a_field.qre_next = (a_qr); \ | |
22 | (a_qrelm)->a_field.qre_prev = (a_qr); \ | |
23 | } while (0) | |
24 | ||
1a4d82fc | 25 | #define qr_after_insert(a_qrelm, a_qr, a_field) \ |
970d7e83 LB |
26 | do \ |
27 | { \ | |
28 | (a_qr)->a_field.qre_next = (a_qrelm)->a_field.qre_next; \ | |
29 | (a_qr)->a_field.qre_prev = (a_qrelm); \ | |
30 | (a_qr)->a_field.qre_next->a_field.qre_prev = (a_qr); \ | |
31 | (a_qrelm)->a_field.qre_next = (a_qr); \ | |
32 | } while (0) | |
33 | ||
1a4d82fc | 34 | #define qr_meld(a_qr_a, a_qr_b, a_field) do { \ |
970d7e83 LB |
35 | void *t; \ |
36 | (a_qr_a)->a_field.qre_prev->a_field.qre_next = (a_qr_b); \ | |
37 | (a_qr_b)->a_field.qre_prev->a_field.qre_next = (a_qr_a); \ | |
38 | t = (a_qr_a)->a_field.qre_prev; \ | |
39 | (a_qr_a)->a_field.qre_prev = (a_qr_b)->a_field.qre_prev; \ | |
40 | (a_qr_b)->a_field.qre_prev = t; \ | |
41 | } while (0) | |
42 | ||
54a0048b SL |
43 | /* |
44 | * qr_meld() and qr_split() are functionally equivalent, so there's no need to | |
45 | * have two copies of the code. | |
46 | */ | |
1a4d82fc | 47 | #define qr_split(a_qr_a, a_qr_b, a_field) \ |
970d7e83 LB |
48 | qr_meld((a_qr_a), (a_qr_b), a_field) |
49 | ||
1a4d82fc | 50 | #define qr_remove(a_qr, a_field) do { \ |
970d7e83 LB |
51 | (a_qr)->a_field.qre_prev->a_field.qre_next \ |
52 | = (a_qr)->a_field.qre_next; \ | |
53 | (a_qr)->a_field.qre_next->a_field.qre_prev \ | |
54 | = (a_qr)->a_field.qre_prev; \ | |
55 | (a_qr)->a_field.qre_next = (a_qr); \ | |
56 | (a_qr)->a_field.qre_prev = (a_qr); \ | |
57 | } while (0) | |
58 | ||
1a4d82fc | 59 | #define qr_foreach(var, a_qr, a_field) \ |
970d7e83 LB |
60 | for ((var) = (a_qr); \ |
61 | (var) != NULL; \ | |
62 | (var) = (((var)->a_field.qre_next != (a_qr)) \ | |
63 | ? (var)->a_field.qre_next : NULL)) | |
64 | ||
1a4d82fc | 65 | #define qr_reverse_foreach(var, a_qr, a_field) \ |
970d7e83 LB |
66 | for ((var) = ((a_qr) != NULL) ? qr_prev(a_qr, a_field) : NULL; \ |
67 | (var) != NULL; \ | |
68 | (var) = (((var) != (a_qr)) \ | |
69 | ? (var)->a_field.qre_prev : NULL)) |