1 1.1 christos /* $NetBSD: list.h,v 1.1.1.1 2009/04/12 15:33:33 christos Exp $ */ 2 1.1 christos 3 1.1 christos /* 4 1.1 christos * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 5 1.1 christos * Copyright (c) 1997,1999 by Internet Software Consortium. 6 1.1 christos * 7 1.1 christos * Permission to use, copy, modify, and distribute this software for any 8 1.1 christos * purpose with or without fee is hereby granted, provided that the above 9 1.1 christos * copyright notice and this permission notice appear in all copies. 10 1.1 christos * 11 1.1 christos * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 12 1.1 christos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 1.1 christos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 14 1.1 christos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 1.1 christos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 1.1 christos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 17 1.1 christos * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 1.1 christos */ 19 1.1 christos 20 1.1 christos #ifndef LIST_H 21 1.1 christos #define LIST_H 1 22 1.1 christos #include <isc/assertions.h> 23 1.1 christos 24 1.1 christos #define LIST(type) struct { type *head, *tail; } 25 1.1 christos #define INIT_LIST(list) \ 26 1.1 christos do { (list).head = NULL; (list).tail = NULL; } while (0) 27 1.1 christos 28 1.1 christos #define LINK(type) struct { type *prev, *next; } 29 1.1 christos #define INIT_LINK_TYPE(elt, link, type) \ 30 1.1 christos do { \ 31 1.1 christos (elt)->link.prev = (type *)(-1); \ 32 1.1 christos (elt)->link.next = (type *)(-1); \ 33 1.1 christos } while (0) 34 1.1 christos #define INIT_LINK(elt, link) \ 35 1.1 christos INIT_LINK_TYPE(elt, link, void) 36 1.1 christos #define LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1) && \ 37 1.1 christos (void *)((elt)->link.next) != (void *)(-1)) 38 1.1 christos 39 1.1 christos #define HEAD(list) ((list).head) 40 1.1 christos #define TAIL(list) ((list).tail) 41 1.1 christos #define EMPTY(list) ((list).head == NULL) 42 1.1 christos 43 1.1 christos #define PREPEND(list, elt, link) \ 44 1.1 christos do { \ 45 1.1 christos INSIST(!LINKED(elt, link));\ 46 1.1 christos if ((list).head != NULL) \ 47 1.1 christos (list).head->link.prev = (elt); \ 48 1.1 christos else \ 49 1.1 christos (list).tail = (elt); \ 50 1.1 christos (elt)->link.prev = NULL; \ 51 1.1 christos (elt)->link.next = (list).head; \ 52 1.1 christos (list).head = (elt); \ 53 1.1 christos } while (0) 54 1.1 christos 55 1.1 christos #define APPEND(list, elt, link) \ 56 1.1 christos do { \ 57 1.1 christos INSIST(!LINKED(elt, link));\ 58 1.1 christos if ((list).tail != NULL) \ 59 1.1 christos (list).tail->link.next = (elt); \ 60 1.1 christos else \ 61 1.1 christos (list).head = (elt); \ 62 1.1 christos (elt)->link.prev = (list).tail; \ 63 1.1 christos (elt)->link.next = NULL; \ 64 1.1 christos (list).tail = (elt); \ 65 1.1 christos } while (0) 66 1.1 christos 67 1.1 christos #define UNLINK_TYPE(list, elt, link, type) \ 68 1.1 christos do { \ 69 1.1 christos INSIST(LINKED(elt, link));\ 70 1.1 christos if ((elt)->link.next != NULL) \ 71 1.1 christos (elt)->link.next->link.prev = (elt)->link.prev; \ 72 1.1 christos else { \ 73 1.1 christos INSIST((list).tail == (elt)); \ 74 1.1 christos (list).tail = (elt)->link.prev; \ 75 1.1 christos } \ 76 1.1 christos if ((elt)->link.prev != NULL) \ 77 1.1 christos (elt)->link.prev->link.next = (elt)->link.next; \ 78 1.1 christos else { \ 79 1.1 christos INSIST((list).head == (elt)); \ 80 1.1 christos (list).head = (elt)->link.next; \ 81 1.1 christos } \ 82 1.1 christos INIT_LINK_TYPE(elt, link, type); \ 83 1.1 christos } while (0) 84 1.1 christos #define UNLINK(list, elt, link) \ 85 1.1 christos UNLINK_TYPE(list, elt, link, void) 86 1.1 christos 87 1.1 christos #define PREV(elt, link) ((elt)->link.prev) 88 1.1 christos #define NEXT(elt, link) ((elt)->link.next) 89 1.1 christos 90 1.1 christos #define INSERT_BEFORE(list, before, elt, link) \ 91 1.1 christos do { \ 92 1.1 christos INSIST(!LINKED(elt, link));\ 93 1.1 christos if ((before)->link.prev == NULL) \ 94 1.1 christos PREPEND(list, elt, link); \ 95 1.1 christos else { \ 96 1.1 christos (elt)->link.prev = (before)->link.prev; \ 97 1.1 christos (before)->link.prev = (elt); \ 98 1.1 christos (elt)->link.prev->link.next = (elt); \ 99 1.1 christos (elt)->link.next = (before); \ 100 1.1 christos } \ 101 1.1 christos } while (0) 102 1.1 christos 103 1.1 christos #define INSERT_AFTER(list, after, elt, link) \ 104 1.1 christos do { \ 105 1.1 christos INSIST(!LINKED(elt, link));\ 106 1.1 christos if ((after)->link.next == NULL) \ 107 1.1 christos APPEND(list, elt, link); \ 108 1.1 christos else { \ 109 1.1 christos (elt)->link.next = (after)->link.next; \ 110 1.1 christos (after)->link.next = (elt); \ 111 1.1 christos (elt)->link.next->link.prev = (elt); \ 112 1.1 christos (elt)->link.prev = (after); \ 113 1.1 christos } \ 114 1.1 christos } while (0) 115 1.1 christos 116 1.1 christos #define ENQUEUE(list, elt, link) APPEND(list, elt, link) 117 1.1 christos #define DEQUEUE(list, elt, link) UNLINK(list, elt, link) 118 1.1 christos 119 1.1 christos #endif /* LIST_H */ 120 1.1 christos /*! \file */ 121