Index: ossp-pkg/act/act_chain.h RCS File: /v/ossp/cvs/ossp-pkg/act/act_chain.h,v co -q -kk -p'1.1' '/v/ossp/cvs/ossp-pkg/act/act_chain.h,v' | diff -u /dev/null - -L'ossp-pkg/act/act_chain.h' 2>/dev/null --- ossp-pkg/act/act_chain.h +++ - 2024-05-20 00:22:31.921708425 +0200 @@ -0,0 +1,193 @@ +/* +** Act - Abstract Container Type Library +** Copyright (c) 1999-2002 Ralf S. Engelschall +** +** This file is part of Act, a library for dealing with Abstract +** Container Types which can be found at http://www.ossp.org/pkg/act/. +** +** Permission to use, copy, modify, and distribute this software for +** any purpose with or without fee is hereby granted, provided that +** the above copyright notice and this permission notice appear in all +** copies. +** +** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED +** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +** +** act_chain.h: basic chained data structures (implementation) +*/ + +#ifndef __ACT_CHAIN_H__ +#define __ACT_CHAIN_H__ + +/* + * Macro set for implementing single-linked lists. + */ + +/* declaration: + * typedef struct { + * ACT_LIST_ELEM(foo_t) next; + * } foo_t; + * ACT_LIST_HEAD(foo_t) head; + */ +#define ACT_LIST_HEAD(type)\ + struct { type *first; } +#define ACT_LIST_ELEM(type) \ + struct { type *next; } + +/* initialization */ +#define ACT_LIST_INITIALIZER \ + { NULL } +#define ACT_LIST_INIT(hp) \ + ACT_LIST_FIRST((hp)) = NULL +#define ACT_LIST_ELEM_INIT(ep, field) \ + ACT_LIST_NEXT((ep), field) = NULL + +/* direct access */ +#define ACT_LIST_FIRST(hp) \ + ((hp)->first) +#define ACT_LIST_NEXT(ep, field) \ + ((ep)->field.next) + +/* empty check */ +#define ACT_LIST_EMPTY(hp) \ + (ACT_LIST_FIRST((hp)) == NULL) + +/* insert */ +#define ACT_LIST_INSERT_HEAD(hp, ep, field) \ + do { ACT_LIST_NEXT((ep), field) = ACT_LIST_FIRST((hp)); \ + ACT_LIST_FIRST((hp)) = (ep); } while (0) +#define ACT_LIST_INSERT_AFTER(ap, ep, field) \ + do { ACT_LIST_NEXT((ep), field) = ACT_LIST_NEXT((ap), field); \ + ACT_LIST_NEXT((ap), field) = (ep); } while (0) + +/* remove */ +#define ACT_LIST_REMOVE_HEAD(hp, field) \ + ACT_LIST_FIRST((hp)) = \ + ACT_LIST_NEXT(ACT_LIST_FIRST((hp)), field) +#define ACT_LIST_REMOVE(hp, ep, field, type) \ + do { \ + if (ACT_LIST_FIRST((hp)) == (ep)) \ + ACT_LIST_REMOVE_HEAD((hp), field); \ + else { \ + type *cep = ACT_LIST_FIRST((hp)); \ + while (ACT_LIST_NEXT(cep, field) != (ep)) \ + cep = ACT_LIST_NEXT(cep, field); \ + ACT_LIST_NEXT(cep, field) = \ + ACT_LIST_NEXT(ACT_LIST_NEXT(cep, field), field); \ + } \ + } while (0) + +/* iteration */ +#define ACT_LIST_FOREACH(hp, ep, field) \ + for ((ep) = ACT_LIST_FIRST((hp)); \ + (ep) != NULL; \ + (ep) = ACT_LIST_NEXT((ep), field)) + +/* + * Macro set for implementing double-linked rings. + */ + +/* declaration */ +#define ACT_RING_HEAD(type) \ + struct { type *next; type *prev; } +#define ACT_RING_ELEM(type) \ + struct { type *next; type *prev; } + +/* initialization */ +#define ACT_RING_INITIALIZER \ + { NULL, NULL } +#define ACT_RING_SENTINEL(hp, type, field) \ + (type *)((char *)(hp) - ((size_t)(&((type *)0)->field))) +#define ACT_RING_INIT(hp, type, field) \ + do { ACT_RING_FIRST((hp)) = ACT_RING_SENTINEL((hp), type, field); \ + ACT_RING_LAST((hp)) = ACT_RING_SENTINEL((hp), type, field); } while (0) +#define ACT_RING_ELEM_INIT(ep, field) \ + do { ACT_RING_NEXT((ep), field) = (ep); \ + ACT_RING_PREV((ep), field) = (ep); } while (0) + +/* direct access */ +#define ACT_RING_FIRST(hp) \ + ((hp)->next) +#define ACT_RING_LAST(hp) \ + ((hp)->prev) +#define ACT_RING_NEXT(ep, field) \ + ((ep)->field.next) +#define ACT_RING_PREV(ep, field) \ + ((ep)->field.prev) + +/* empty check */ +#define ACT_RING_EMPTY(hp, type, field) \ + (ACT_RING_FIRST((hp)) == ACT_RING_SENTINEL((hp), type, field)) + +/* insert */ +#define ACT_RING_SPLICE_BEFORE(lep, ep1, epN, field) \ + do { \ + ACT_RING_NEXT((epN), field) = (lep); \ + ACT_RING_PREV((ep1), field) = ACT_RING_PREV((lep), field); \ + ACT_RING_NEXT(ACT_RING_PREV((lep), field), field) = (ep1); \ + ACT_RING_PREV((lep), field) = (epN); \ + } while (0) +#define ACT_RING_SPLICE_AFTER(lep, ep1, epN, field) \ + do { \ + ACT_RING_PREV((ep1), field) = (lep); \ + ACT_RING_NEXT((epN), field) = ACT_RING_NEXT((lep), field); \ + ACT_RING_PREV(ACT_RING_NEXT((lep), field), field) = (epN); \ + ACT_RING_NEXT((lep), field) = (ep1); \ + } while (0) +#define ACT_RING_SPLICE_HEAD(hp, ep1, epN, type, field) \ + ACT_RING_SPLICE_AFTER(ACT_RING_SENTINEL((hp), type, field), (ep1), (epN), field) +#define ACT_RING_SPLICE_TAIL(hp, ep1, epN, type, field) \ + ACT_RING_SPLICE_BEFORE(ACT_RING_SENTINEL((hp), type, field), (ep1), (epN), field) +#define ACT_RING_INSERT_BEFORE(lep, nep, field) \ + ACT_RING_SPLICE_BEFORE((lep), (nep), (nep), field) +#define ACT_RING_INSERT_AFTER(lep, nep, field) \ + ACT_RING_SPLICE_AFTER((lep), (nep), (nep), field) +#define ACT_RING_INSERT_HEAD(hp, nep, type, field) \ + ACT_RING_SPLICE_HEAD((hp), (nep), (nep), type, field) +#define ACT_RING_INSERT_TAIL(hp, nep, type, field) \ + ACT_RING_SPLICE_TAIL((hp), (nep), (nep), type, field) + +/* remove */ +#define ACT_RING_UNSPLICE(ep1, epN, field) \ + do { \ + ACT_RING_NEXT(ACT_RING_PREV((ep1), field), field) = \ + ACT_RING_NEXT((epN), field); \ + ACT_RING_PREV(ACT_RING_NEXT((epN), field), field) = \ + ACT_RING_PREV((ep1), field); \ + } while (0) +#define ACT_RING_REMOVE(ep, field) \ + ACT_RING_UNSPLICE((ep), (ep), field) + +/* concatenation */ +#define ACT_RING_CONCAT(h1, h2, type, field) \ + do { \ + if (!ACT_RING_EMPTY((h2), type, field)) { \ + ACT_RING_SPLICE_BEFORE(ACT_RING_SENTINEL((h1), type, field), \ + ACT_RING_FIRST((h2)), \ + ACT_RING_LAST((h2)), field); \ + ACT_RING_INIT((h2), type, field); \ + } \ + } while (0) + +/* iteration */ +#define ACT_RING_FOREACH(ep, hp, type, field) \ + for ((ep) = ACT_RING_FIRST((hp)); \ + (ep) != ACT_RING_SENTINEL((hp), type, field); \ + (ep) = ACT_RING_NEXT((ep), field)) +#define ACT_RING_FOREACH_REVERSE(ep, hp, type, field) \ + for ((ep) = ACT_RING_LAST((hp)); \ + (ep) != ACT_RING_SENTINEL((hp), type, field); \ + (ep) = ACT_RING_PREV((ep), field)) + +#endif /* __ACT_CHAIN_H__*/ +