/* * Copyright (c) 2006 Teodor Sigaev * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS * 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 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. */ #ifndef __GLIST_H__ #define __GLIST_H__ typedef struct GListCell { void *data; struct GListCell *next; struct GListCell *prev; } GListCell; #define GLCELL_DATA(c) ((c)->data) #define GLCELL_NEXT(c) ((c)->next) #define GLCELL_PREV(c) ((c)->prev) typedef int (*GListCellComparator)(const void *, const void *); typedef int (*GListDataFreeFunc)(const void *); typedef struct GList { GListCell *head; GListCell *tail; int length; GListCellComparator cmpFunc; GListDataFreeFunc freeFunc; } GList; #define GLIST_HEAD(l) ((l) ? (l)->head : NULL) #define GLIST_TAIL(l) ((l) ? (l)->tail : NULL) #define GLIST_LENGTH(l) ((l) ? (l)->length : 0) GListCell* GListPop(GList *l); GList* GListPush(GList *l, void *ptr); GList* GListPushCell(GList *l, GListCell* c); GListCell* GListShift(GList *l); GList* GListUnshift(GList *l, void *ptr); GList* GListUnshiftCell(GList *l, GListCell* c); GList* GListInsert(GList *l, GListCell *prev, void *ptr); GList* GListDelete(GList *l, GListCell *c); GListCell* GListGet(GList *l, int n); GListCell* GListFind(GList *l, void *ptr); GList* GListSort(GList *l); GList* GListUniq(GList *l); void GListFree(GList *l); void GListFreeCell(GList *l, GListCell* c); GList* GListTruncate(GList *l, int n); GList* GListCopy(GList *l); GList* GListConcat(GList *l1, GList *l2); GList* GListDifference(GList *l1, GList *l2); GList* GListUnion(GList *l1, GList *l2); GList* GListIntersect(GList *l1, GList *l2); #define GListForeach(cell, l) \ for ((cell) = GLIST_HEAD(l); (cell) != NULL; (cell) = GLCELL_NEXT(cell)) #define GListForeachBack(cell, l) \ for ((cell) = GLIST_TAIL(l); (cell) != NULL; (cell) = GLCELL_PREV(cell)) #define GListForeachCell(cell, initcell) \ for ((cell) = (initcell); (cell) != NULL; (cell) = GLCELL_NEXT(cell)) #define GListForeachCellBack(cell, initcell) \ for ((cell) = (initcell); (cell) != NULL; (cell) = GLCELL_PREV(cell)) #endif