1*388550b0Srillig /* $NetBSD: list.h,v 1.6 2022/04/19 20:32:15 rillig Exp $ */ 289abd492Schristos 389abd492Schristos /* 489abd492Schristos * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 589abd492Schristos * Copyright (c) 1997,1999 by Internet Software Consortium. 689abd492Schristos * 789abd492Schristos * Permission to use, copy, modify, and distribute this software for any 889abd492Schristos * purpose with or without fee is hereby granted, provided that the above 989abd492Schristos * copyright notice and this permission notice appear in all copies. 1089abd492Schristos * 1189abd492Schristos * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 1289abd492Schristos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1389abd492Schristos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 1489abd492Schristos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1589abd492Schristos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1689abd492Schristos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 1789abd492Schristos * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1889abd492Schristos */ 1989abd492Schristos 2089abd492Schristos #ifndef LIST_H 2189abd492Schristos #define LIST_H 1 2289abd492Schristos #include <isc/assertions.h> 2389abd492Schristos 2489abd492Schristos #define LIST(type) struct { type *head, *tail; } 2589abd492Schristos #define INIT_LIST(list) \ 26*388550b0Srillig do { (list).head = NULL; (list).tail = NULL; } while (0) 2789abd492Schristos 2889abd492Schristos #define LINK(type) struct { type *prev, *next; } 2989abd492Schristos #define INIT_LINK_TYPE(elt, link, type) \ 3089abd492Schristos do { \ 3189abd492Schristos (elt)->link.prev = (type *)(-1); \ 3289abd492Schristos (elt)->link.next = (type *)(-1); \ 33*388550b0Srillig } while (0) 3489abd492Schristos #define INIT_LINK(elt, link) \ 3589abd492Schristos INIT_LINK_TYPE(elt, link, void) 3659a755a4Schristos #define LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1) && \ 3759a755a4Schristos (void *)((elt)->link.next) != (void *)(-1)) 3889abd492Schristos 3989abd492Schristos #define HEAD(list) ((list).head) 4089abd492Schristos #define TAIL(list) ((list).tail) 4189abd492Schristos #define EMPTY(list) ((list).head == NULL) 4289abd492Schristos 4389abd492Schristos #define PREPEND(list, elt, link) \ 4489abd492Schristos do { \ 4589abd492Schristos INSIST(!LINKED(elt, link));\ 4689abd492Schristos if ((list).head != NULL) \ 4789abd492Schristos (list).head->link.prev = (elt); \ 4889abd492Schristos else \ 4989abd492Schristos (list).tail = (elt); \ 5089abd492Schristos (elt)->link.prev = NULL; \ 5189abd492Schristos (elt)->link.next = (list).head; \ 5289abd492Schristos (list).head = (elt); \ 53*388550b0Srillig } while (0) 5489abd492Schristos 5589abd492Schristos #define APPEND(list, elt, link) \ 5689abd492Schristos do { \ 5789abd492Schristos INSIST(!LINKED(elt, link));\ 5889abd492Schristos if ((list).tail != NULL) \ 5989abd492Schristos (list).tail->link.next = (elt); \ 6089abd492Schristos else \ 6189abd492Schristos (list).head = (elt); \ 6289abd492Schristos (elt)->link.prev = (list).tail; \ 6389abd492Schristos (elt)->link.next = NULL; \ 6489abd492Schristos (list).tail = (elt); \ 65*388550b0Srillig } while (0) 6689abd492Schristos 6789abd492Schristos #define UNLINK_TYPE(list, elt, link, type) \ 6889abd492Schristos do { \ 6989abd492Schristos INSIST(LINKED(elt, link));\ 7089abd492Schristos if ((elt)->link.next != NULL) \ 7189abd492Schristos (elt)->link.next->link.prev = (elt)->link.prev; \ 72d73eb73dSchristos else { \ 73d73eb73dSchristos INSIST((list).tail == (elt)); \ 7489abd492Schristos (list).tail = (elt)->link.prev; \ 75d73eb73dSchristos } \ 7689abd492Schristos if ((elt)->link.prev != NULL) \ 7789abd492Schristos (elt)->link.prev->link.next = (elt)->link.next; \ 78d73eb73dSchristos else { \ 79d73eb73dSchristos INSIST((list).head == (elt)); \ 8089abd492Schristos (list).head = (elt)->link.next; \ 81d73eb73dSchristos } \ 8289abd492Schristos INIT_LINK_TYPE(elt, link, type); \ 83*388550b0Srillig } while (0) 8489abd492Schristos #define UNLINK(list, elt, link) \ 8589abd492Schristos UNLINK_TYPE(list, elt, link, void) 8689abd492Schristos 8789abd492Schristos #define PREV(elt, link) ((elt)->link.prev) 8889abd492Schristos #define NEXT(elt, link) ((elt)->link.next) 8989abd492Schristos 9089abd492Schristos #define INSERT_BEFORE(list, before, elt, link) \ 9189abd492Schristos do { \ 9289abd492Schristos INSIST(!LINKED(elt, link));\ 9389abd492Schristos if ((before)->link.prev == NULL) \ 9489abd492Schristos PREPEND(list, elt, link); \ 9589abd492Schristos else { \ 9689abd492Schristos (elt)->link.prev = (before)->link.prev; \ 9789abd492Schristos (before)->link.prev = (elt); \ 9889abd492Schristos (elt)->link.prev->link.next = (elt); \ 9989abd492Schristos (elt)->link.next = (before); \ 10089abd492Schristos } \ 101*388550b0Srillig } while (0) 10289abd492Schristos 10389abd492Schristos #define INSERT_AFTER(list, after, elt, link) \ 10489abd492Schristos do { \ 10589abd492Schristos INSIST(!LINKED(elt, link));\ 10689abd492Schristos if ((after)->link.next == NULL) \ 10789abd492Schristos APPEND(list, elt, link); \ 10889abd492Schristos else { \ 10989abd492Schristos (elt)->link.next = (after)->link.next; \ 11089abd492Schristos (after)->link.next = (elt); \ 11189abd492Schristos (elt)->link.next->link.prev = (elt); \ 11289abd492Schristos (elt)->link.prev = (after); \ 11389abd492Schristos } \ 114*388550b0Srillig } while (0) 11589abd492Schristos 11689abd492Schristos #define ENQUEUE(list, elt, link) APPEND(list, elt, link) 11789abd492Schristos #define DEQUEUE(list, elt, link) UNLINK(list, elt, link) 11889abd492Schristos 11989abd492Schristos #endif /* LIST_H */ 120d73eb73dSchristos /*! \file */ 121