michael@0: /****************************************************************************** michael@0: * michael@0: * Copyright (C) 2002 Jason Evans . michael@0: * All rights reserved. michael@0: * michael@0: * Redistribution and use in source and binary forms, with or without michael@0: * modification, are permitted provided that the following conditions michael@0: * are met: michael@0: * 1. Redistributions of source code must retain the above copyright michael@0: * notice(s), this list of conditions and the following disclaimer michael@0: * unmodified other than the allowable addition of one or more michael@0: * copyright notices. michael@0: * 2. Redistributions in binary form must reproduce the above copyright michael@0: * notice(s), this list of conditions and the following disclaimer in michael@0: * the documentation and/or other materials provided with the michael@0: * distribution. michael@0: * michael@0: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY michael@0: * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE michael@0: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR michael@0: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE michael@0: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR michael@0: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF michael@0: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR michael@0: * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, michael@0: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE michael@0: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, michael@0: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: * michael@0: ******************************************************************************/ michael@0: michael@0: /* Ring definitions. */ michael@0: #define qr(a_type) \ michael@0: struct { \ michael@0: a_type *qre_next; \ michael@0: a_type *qre_prev; \ michael@0: } michael@0: michael@0: /* Ring functions. */ michael@0: #define qr_new(a_qr, a_field) do { \ michael@0: (a_qr)->a_field.qre_next = (a_qr); \ michael@0: (a_qr)->a_field.qre_prev = (a_qr); \ michael@0: } while (0) michael@0: michael@0: #define qr_next(a_qr, a_field) ((a_qr)->a_field.qre_next) michael@0: michael@0: #define qr_prev(a_qr, a_field) ((a_qr)->a_field.qre_prev) michael@0: michael@0: #define qr_before_insert(a_qrelm, a_qr, a_field) do { \ michael@0: (a_qr)->a_field.qre_prev = (a_qrelm)->a_field.qre_prev; \ michael@0: (a_qr)->a_field.qre_next = (a_qrelm); \ michael@0: (a_qr)->a_field.qre_prev->a_field.qre_next = (a_qr); \ michael@0: (a_qrelm)->a_field.qre_prev = (a_qr); \ michael@0: } while (0) michael@0: michael@0: #define qr_after_insert(a_qrelm, a_qr, a_field) \ michael@0: do \ michael@0: { \ michael@0: (a_qr)->a_field.qre_next = (a_qrelm)->a_field.qre_next; \ michael@0: (a_qr)->a_field.qre_prev = (a_qrelm); \ michael@0: (a_qr)->a_field.qre_next->a_field.qre_prev = (a_qr); \ michael@0: (a_qrelm)->a_field.qre_next = (a_qr); \ michael@0: } while (0) michael@0: michael@0: #define qr_meld(a_qr_a, a_qr_b, a_field) do { \ michael@0: void *t; \ michael@0: (a_qr_a)->a_field.qre_prev->a_field.qre_next = (a_qr_b); \ michael@0: (a_qr_b)->a_field.qre_prev->a_field.qre_next = (a_qr_a); \ michael@0: t = (a_qr_a)->a_field.qre_prev; \ michael@0: (a_qr_a)->a_field.qre_prev = (a_qr_b)->a_field.qre_prev; \ michael@0: (a_qr_b)->a_field.qre_prev = t; \ michael@0: } while (0) michael@0: michael@0: /* qr_meld() and qr_split() are functionally equivalent, so there's no need to michael@0: * have two copies of the code. */ michael@0: #define qr_split(a_qr_a, a_qr_b, a_field) \ michael@0: qr_meld((a_qr_a), (a_qr_b), a_field) michael@0: michael@0: #define qr_remove(a_qr, a_field) do { \ michael@0: (a_qr)->a_field.qre_prev->a_field.qre_next \ michael@0: = (a_qr)->a_field.qre_next; \ michael@0: (a_qr)->a_field.qre_next->a_field.qre_prev \ michael@0: = (a_qr)->a_field.qre_prev; \ michael@0: (a_qr)->a_field.qre_next = (a_qr); \ michael@0: (a_qr)->a_field.qre_prev = (a_qr); \ michael@0: } while (0) michael@0: michael@0: #define qr_foreach(var, a_qr, a_field) \ michael@0: for ((var) = (a_qr); \ michael@0: (var) != NULL; \ michael@0: (var) = (((var)->a_field.qre_next != (a_qr)) \ michael@0: ? (var)->a_field.qre_next : NULL)) michael@0: michael@0: #define qr_reverse_foreach(var, a_qr, a_field) \ michael@0: for ((var) = ((a_qr) != NULL) ? qr_prev(a_qr, a_field) : NULL; \ michael@0: (var) != NULL; \ michael@0: (var) = (((var) != (a_qr)) \ michael@0: ? (var)->a_field.qre_prev : NULL))