1dbc09553SPetr Hosek //===-- Macros defined in sys/queue.h header file -------------------------===// 2dbc09553SPetr Hosek // 3dbc09553SPetr Hosek // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4dbc09553SPetr Hosek // See https://llvm.org/LICENSE.txt for license information. 5dbc09553SPetr Hosek // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6dbc09553SPetr Hosek // 7dbc09553SPetr Hosek //===----------------------------------------------------------------------===// 8dbc09553SPetr Hosek 9330793c9SNick Desaulniers #ifndef LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H 10330793c9SNick Desaulniers #define LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H 11dbc09553SPetr Hosek 12*88a0a318Slntue #include "containerof-macro.h" 13*88a0a318Slntue #include "null-macro.h" 14dbc09553SPetr Hosek 15dbc09553SPetr Hosek #ifdef __cplusplus 16dbc09553SPetr Hosek #define QUEUE_TYPEOF(type) type 17dbc09553SPetr Hosek #else 18dbc09553SPetr Hosek #define QUEUE_TYPEOF(type) struct type 19dbc09553SPetr Hosek #endif 20dbc09553SPetr Hosek 21dbc09553SPetr Hosek // Singly-linked list definitions. 22dbc09553SPetr Hosek 23dbc09553SPetr Hosek #define SLIST_HEAD(name, type) \ 24dbc09553SPetr Hosek struct name { \ 255bd0c44bSPetr Hosek struct type *slh_first; \ 26dbc09553SPetr Hosek } 27dbc09553SPetr Hosek 28dbc09553SPetr Hosek #define SLIST_CLASS_HEAD(name, type) \ 29dbc09553SPetr Hosek struct name { \ 305bd0c44bSPetr Hosek class type *slh_first; \ 31dbc09553SPetr Hosek } 32dbc09553SPetr Hosek 33dbc09553SPetr Hosek #define SLIST_HEAD_INITIALIZER(head) \ 34dbc09553SPetr Hosek { NULL } 35dbc09553SPetr Hosek 36dbc09553SPetr Hosek #define SLIST_ENTRY(type) \ 37dbc09553SPetr Hosek struct { \ 38dbc09553SPetr Hosek struct type *next; \ 39dbc09553SPetr Hosek } 40dbc09553SPetr Hosek 41dbc09553SPetr Hosek #define SLIST_CLASS_ENTRY(type) \ 42dbc09553SPetr Hosek struct { \ 43dbc09553SPetr Hosek class type *next; \ 44dbc09553SPetr Hosek } 45dbc09553SPetr Hosek 46dbc09553SPetr Hosek // Singly-linked list access methods. 47dbc09553SPetr Hosek 485bd0c44bSPetr Hosek #define SLIST_EMPTY(head) ((head)->slh_first == NULL) 495bd0c44bSPetr Hosek #define SLIST_FIRST(head) ((head)->slh_first) 50dbc09553SPetr Hosek #define SLIST_NEXT(elem, field) ((elem)->field.next) 51dbc09553SPetr Hosek 52dbc09553SPetr Hosek #define SLIST_FOREACH(var, head, field) \ 53dbc09553SPetr Hosek for ((var) = SLIST_FIRST(head); (var); (var) = SLIST_NEXT(var, field)) 54dbc09553SPetr Hosek 55dbc09553SPetr Hosek #define SLIST_FOREACH_FROM(var, head, field) \ 56dbc09553SPetr Hosek if (!(var)) \ 57dbc09553SPetr Hosek (var) = SLIST_FIRST(head); \ 58dbc09553SPetr Hosek for (; (var); (var) = SLIST_NEXT(var, field)) 59dbc09553SPetr Hosek 60dbc09553SPetr Hosek #define SLIST_FOREACH_SAFE(var, head, field, tvar) \ 61dbc09553SPetr Hosek for ((var) = SLIST_FIRST(head); \ 62dbc09553SPetr Hosek (var) && ((tvar) = SLIST_NEXT(var, field), 1); (var) = (tvar)) 63dbc09553SPetr Hosek 64dbc09553SPetr Hosek #define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ 65dbc09553SPetr Hosek if (!(var)) \ 66dbc09553SPetr Hosek (var) = SLIST_FIRST(head); \ 67dbc09553SPetr Hosek for (; (var) && ((tvar) = SLIST_NEXT(var, field), 1); (var) = (tvar)) 68dbc09553SPetr Hosek 69dbc09553SPetr Hosek // Singly-linked list functions. 70dbc09553SPetr Hosek 71dbc09553SPetr Hosek #define SLIST_CONCAT(head1, head2, type, field) \ 72dbc09553SPetr Hosek do { \ 73dbc09553SPetr Hosek if (SLIST_EMPTY(head1)) { \ 74dbc09553SPetr Hosek if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != NULL) \ 75dbc09553SPetr Hosek SLIST_INIT(head2); \ 76dbc09553SPetr Hosek } else if (!SLIST_EMPTY(head2)) { \ 77dbc09553SPetr Hosek QUEUE_TYPEOF(type) *cur = SLIST_FIRST(head1); \ 78dbc09553SPetr Hosek while (SLIST_NEXT(cur, field) != NULL) \ 79dbc09553SPetr Hosek cur = SLIST_NEXT(cur, field); \ 80dbc09553SPetr Hosek SLIST_NEXT(cur, field) = SLIST_FIRST(head2); \ 81dbc09553SPetr Hosek SLIST_INIT(head2); \ 82dbc09553SPetr Hosek } \ 83dbc09553SPetr Hosek } while (0) 84dbc09553SPetr Hosek 85dbc09553SPetr Hosek #define SLIST_INIT(head) \ 86dbc09553SPetr Hosek do { \ 87dbc09553SPetr Hosek SLIST_FIRST(head) = NULL; \ 88dbc09553SPetr Hosek } while (0) 89dbc09553SPetr Hosek 90dbc09553SPetr Hosek #define SLIST_INSERT_AFTER(slistelem, elem, field) \ 91dbc09553SPetr Hosek do { \ 92dbc09553SPetr Hosek SLIST_NEXT(elem, field) = SLIST_NEXT(slistelem, field); \ 93dbc09553SPetr Hosek SLIST_NEXT(slistelem, field) = (elem); \ 94dbc09553SPetr Hosek } while (0) 95dbc09553SPetr Hosek 96dbc09553SPetr Hosek #define SLIST_INSERT_HEAD(head, elem, field) \ 97dbc09553SPetr Hosek do { \ 98dbc09553SPetr Hosek SLIST_NEXT(elem, field) = SLIST_FIRST(head); \ 99dbc09553SPetr Hosek SLIST_FIRST(head) = (elem); \ 100dbc09553SPetr Hosek } while (0) 101dbc09553SPetr Hosek 102dbc09553SPetr Hosek #define SLIST_REMOVE(head, elem, type, field) \ 103dbc09553SPetr Hosek do { \ 104dbc09553SPetr Hosek if (SLIST_FIRST(head) == (elem)) { \ 105dbc09553SPetr Hosek SLIST_REMOVE_HEAD(head, field); \ 106dbc09553SPetr Hosek } else { \ 107dbc09553SPetr Hosek QUEUE_TYPEOF(type) *cur = SLIST_FIRST(head); \ 108dbc09553SPetr Hosek while (SLIST_NEXT(cur, field) != (elem)) \ 109dbc09553SPetr Hosek cur = SLIST_NEXT(cur, field); \ 110dbc09553SPetr Hosek SLIST_REMOVE_AFTER(cur, field); \ 111dbc09553SPetr Hosek } \ 112dbc09553SPetr Hosek } while (0) 113dbc09553SPetr Hosek 114dbc09553SPetr Hosek #define SLIST_REMOVE_AFTER(elem, field) \ 115dbc09553SPetr Hosek do { \ 116dbc09553SPetr Hosek SLIST_NEXT(elem, field) = SLIST_NEXT(SLIST_NEXT(elem, field), field); \ 117dbc09553SPetr Hosek } while (0) 118dbc09553SPetr Hosek 119dbc09553SPetr Hosek #define SLIST_REMOVE_HEAD(head, field) \ 120dbc09553SPetr Hosek do { \ 121dbc09553SPetr Hosek SLIST_FIRST(head) = SLIST_NEXT(SLIST_FIRST(head), field); \ 122dbc09553SPetr Hosek } while (0) 123dbc09553SPetr Hosek 124dbc09553SPetr Hosek #define SLIST_SWAP(head1, head2, type) \ 125dbc09553SPetr Hosek do { \ 126dbc09553SPetr Hosek QUEUE_TYPEOF(type) *first = SLIST_FIRST(head1); \ 127dbc09553SPetr Hosek SLIST_FIRST(head1) = SLIST_FIRST(head2); \ 128dbc09553SPetr Hosek SLIST_FIRST(head2) = first; \ 129dbc09553SPetr Hosek } while (0) 130dbc09553SPetr Hosek 131dbc09553SPetr Hosek // Singly-linked tail queue definitions. 132dbc09553SPetr Hosek 133dbc09553SPetr Hosek #define STAILQ_HEAD(name, type) \ 134dbc09553SPetr Hosek struct name { \ 1355bd0c44bSPetr Hosek struct type *stqh_first; \ 1365bd0c44bSPetr Hosek struct type **stqh_last; \ 137dbc09553SPetr Hosek } 138dbc09553SPetr Hosek 139dbc09553SPetr Hosek #define STAILQ_CLASS_HEAD(name, type) \ 140dbc09553SPetr Hosek struct name { \ 1415bd0c44bSPetr Hosek class type *stqh_first; \ 1425bd0c44bSPetr Hosek class type **stqh_last; \ 143dbc09553SPetr Hosek } 144dbc09553SPetr Hosek 145dbc09553SPetr Hosek #define STAILQ_HEAD_INITIALIZER(head) \ 1465bd0c44bSPetr Hosek { NULL, &(head).stqh_first } 147dbc09553SPetr Hosek 148dbc09553SPetr Hosek #define STAILQ_ENTRY(type) \ 149dbc09553SPetr Hosek struct { \ 150dbc09553SPetr Hosek struct type *next; \ 151dbc09553SPetr Hosek } 152dbc09553SPetr Hosek 153dbc09553SPetr Hosek #define STAILQ_CLASS_ENTRY(type) \ 154dbc09553SPetr Hosek struct { \ 155dbc09553SPetr Hosek class type *next; \ 156dbc09553SPetr Hosek } 157dbc09553SPetr Hosek 158dbc09553SPetr Hosek // Singly-linked tail queue access methods. 159dbc09553SPetr Hosek 1605bd0c44bSPetr Hosek #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) 1615bd0c44bSPetr Hosek #define STAILQ_FIRST(head) ((head)->stqh_first) 162dbc09553SPetr Hosek #define STAILQ_LAST(head, type, field) \ 163c0a74ad9SPetr Hosek (STAILQ_EMPTY(head) \ 164c0a74ad9SPetr Hosek ? NULL \ 1655bd0c44bSPetr Hosek : __containerof((head)->stqh_last, QUEUE_TYPEOF(type), field.next)) 166dbc09553SPetr Hosek #define STAILQ_NEXT(elem, field) ((elem)->field.next) 167dbc09553SPetr Hosek 168dbc09553SPetr Hosek #define STAILQ_FOREACH(var, head, field) \ 169dbc09553SPetr Hosek for ((var) = STAILQ_FIRST(head); (var); (var) = STAILQ_NEXT(var, field)) 170dbc09553SPetr Hosek 171dbc09553SPetr Hosek #define STAILQ_FOREACH_FROM(var, head, field) \ 172dbc09553SPetr Hosek if (!(var)) \ 173dbc09553SPetr Hosek (var) = STAILQ_FIRST(head); \ 174dbc09553SPetr Hosek for (; (var); (var) = STAILQ_NEXT(var, field)) 175dbc09553SPetr Hosek 176dbc09553SPetr Hosek #define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ 177dbc09553SPetr Hosek for ((var) = STAILQ_FIRST(head); \ 178dbc09553SPetr Hosek (var) && ((tvar) = STAILQ_NEXT(var, field), 1); (var) = (tvar)) 179dbc09553SPetr Hosek 180dbc09553SPetr Hosek #define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ 181dbc09553SPetr Hosek if (!(var)) \ 182dbc09553SPetr Hosek (var) = STAILQ_FIRST(head); \ 183dbc09553SPetr Hosek for (; (var) && ((tvar) = STAILQ_NEXT(var, field), 1); (var) = (tvar)) 184dbc09553SPetr Hosek 185dbc09553SPetr Hosek // Singly-linked tail queue functions. 186dbc09553SPetr Hosek 187dbc09553SPetr Hosek #define STAILQ_CONCAT(head1, head2, type, field) \ 188dbc09553SPetr Hosek do { \ 189dbc09553SPetr Hosek if (!STAILQ_EMPTY(head2)) { \ 1905bd0c44bSPetr Hosek *(head1)->stqh_last = (head2)->stqh_first; \ 1915bd0c44bSPetr Hosek (head1)->stqh_last = (head2)->stqh_last; \ 192dbc09553SPetr Hosek STAILQ_INIT(head2); \ 193dbc09553SPetr Hosek } \ 194dbc09553SPetr Hosek } while (0) 195dbc09553SPetr Hosek 196dbc09553SPetr Hosek #define STAILQ_INIT(head) \ 197dbc09553SPetr Hosek do { \ 198dbc09553SPetr Hosek STAILQ_FIRST(head) = NULL; \ 1995bd0c44bSPetr Hosek (head)->stqh_last = &STAILQ_FIRST(head); \ 200dbc09553SPetr Hosek } while (0) 201dbc09553SPetr Hosek 202dbc09553SPetr Hosek #define STAILQ_INSERT_AFTER(head, listelem, elem, field) \ 203dbc09553SPetr Hosek do { \ 204dbc09553SPetr Hosek if ((STAILQ_NEXT(elem, field) = STAILQ_NEXT(listelem, field)) == NULL) \ 2055bd0c44bSPetr Hosek (head)->stqh_last = &STAILQ_NEXT(elem, field); \ 206dbc09553SPetr Hosek STAILQ_NEXT(listelem, field) = (elem); \ 207dbc09553SPetr Hosek } while (0) 208dbc09553SPetr Hosek 209dbc09553SPetr Hosek #define STAILQ_INSERT_HEAD(head, elem, field) \ 210dbc09553SPetr Hosek do { \ 211dbc09553SPetr Hosek if ((STAILQ_NEXT(elem, field) = STAILQ_FIRST(head)) == NULL) \ 2125bd0c44bSPetr Hosek (head)->stqh_last = &STAILQ_NEXT(elem, field); \ 213dbc09553SPetr Hosek STAILQ_FIRST(head) = (elem); \ 214dbc09553SPetr Hosek } while (0) 215dbc09553SPetr Hosek 216dbc09553SPetr Hosek #define STAILQ_INSERT_TAIL(head, elem, field) \ 217dbc09553SPetr Hosek do { \ 218dbc09553SPetr Hosek STAILQ_NEXT(elem, field) = NULL; \ 2195bd0c44bSPetr Hosek *(head)->stqh_last = (elem); \ 2205bd0c44bSPetr Hosek (head)->stqh_last = &STAILQ_NEXT(elem, field); \ 221dbc09553SPetr Hosek } while (0) 222dbc09553SPetr Hosek 223dbc09553SPetr Hosek #define STAILQ_REMOVE(head, elem, type, field) \ 224dbc09553SPetr Hosek do { \ 225dbc09553SPetr Hosek if (STAILQ_FIRST(head) == (elem)) { \ 226dbc09553SPetr Hosek STAILQ_REMOVE_HEAD(head, field); \ 227dbc09553SPetr Hosek } else { \ 228dbc09553SPetr Hosek QUEUE_TYPEOF(type) *cur = STAILQ_FIRST(head); \ 229dbc09553SPetr Hosek while (STAILQ_NEXT(cur, field) != (elem)) \ 230dbc09553SPetr Hosek cur = STAILQ_NEXT(cur, field); \ 231dbc09553SPetr Hosek STAILQ_REMOVE_AFTER(head, cur, field); \ 232dbc09553SPetr Hosek } \ 233dbc09553SPetr Hosek } while (0) 234dbc09553SPetr Hosek 235dbc09553SPetr Hosek #define STAILQ_REMOVE_AFTER(head, elem, field) \ 236dbc09553SPetr Hosek do { \ 237dbc09553SPetr Hosek if ((STAILQ_NEXT(elem, field) = \ 238dbc09553SPetr Hosek STAILQ_NEXT(STAILQ_NEXT(elem, field), field)) == NULL) \ 2395bd0c44bSPetr Hosek (head)->stqh_last = &STAILQ_NEXT(elem, field); \ 240dbc09553SPetr Hosek } while (0) 241dbc09553SPetr Hosek 242dbc09553SPetr Hosek #define STAILQ_REMOVE_HEAD(head, field) \ 243dbc09553SPetr Hosek do { \ 244dbc09553SPetr Hosek if ((STAILQ_FIRST(head) = STAILQ_NEXT(STAILQ_FIRST(head), field)) == NULL) \ 2455bd0c44bSPetr Hosek (head)->stqh_last = &STAILQ_FIRST(head); \ 246dbc09553SPetr Hosek } while (0) 247dbc09553SPetr Hosek 248dbc09553SPetr Hosek #define STAILQ_SWAP(head1, head2, type) \ 249dbc09553SPetr Hosek do { \ 250dbc09553SPetr Hosek QUEUE_TYPEOF(type) *first = STAILQ_FIRST(head1); \ 2515bd0c44bSPetr Hosek QUEUE_TYPEOF(type) **last = (head1)->stqh_last; \ 252dbc09553SPetr Hosek STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ 2535bd0c44bSPetr Hosek (head1)->stqh_last = (head2)->stqh_last; \ 254dbc09553SPetr Hosek STAILQ_FIRST(head2) = first; \ 2555bd0c44bSPetr Hosek (head2)->stqh_last = last; \ 256dbc09553SPetr Hosek if (STAILQ_EMPTY(head1)) \ 2575bd0c44bSPetr Hosek (head1)->stqh_last = &STAILQ_FIRST(head1); \ 258dbc09553SPetr Hosek if (STAILQ_EMPTY(head2)) \ 2595bd0c44bSPetr Hosek (head2)->stqh_last = &STAILQ_FIRST(head2); \ 260dbc09553SPetr Hosek } while (0) 261dbc09553SPetr Hosek 262330793c9SNick Desaulniers #endif // LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H 263