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