layer0/ListMacros.h (160 lines of code) (raw):

/* A* ------------------------------------------------------------------- B* This file contains source code for the PyMOL computer program C* Copyright (c) Schrodinger, LLC. D* ------------------------------------------------------------------- E* It is unlawful to modify or remove this copyright notice. F* ------------------------------------------------------------------- G* Please see the accompanying LICENSE file for further information. H* ------------------------------------------------------------------- I* Additional authors of this source file include: -* -* -* Z* ------------------------------------------------------------------- */ #ifndef _H_ListMacros #define _H_ListMacros /* simplest possible single-linked list */ #include"MemoryDebug.h" #include"Err.h" #define ListInit(List) List = NULL #define ListAppend(List,Elem,Link,ElemType) \ { \ ElemType *current = (List); \ ElemType *previous = NULL; \ while(current) \ { \ previous = current; \ current = current->Link; \ } \ if(previous) \ previous->Link = Elem; \ else \ (List) = Elem; \ (Elem)->Link = NULL; \ } #define ListPrepend(List,Elem,Link) \ { \ (Elem)->Link = List; \ (List) = Elem; \ } #define ListInsert(List,Elem,After,Link,ElemType) \ { \ ElemType *current = List; \ ElemType *previous = NULL; \ while(current) \ { \ if(previous == (After)) \ break; \ previous = current; \ current = current->Link; \ } \ if(previous) \ { \ (Elem)->Link = current; \ previous->Link = Elem; \ } \ else \ { \ (Elem)->Link = List; \ (List) = Elem; \ } \ } #define ListFree(List,Link,ElemType) \ { \ ElemType *current = List; \ ElemType *previous = NULL; \ while(current) \ { \ if(previous) \ mfree(previous); \ previous = current; \ current = current->Link; \ } \ if(previous) \ mfree(previous); \ (List) = NULL; \ } #define ListDetach(List,Elem,Link,ElemType) \ { \ ElemType *current = List; \ ElemType *previous = NULL; \ while(current) \ { \ if(current == (Elem)) \ break; \ previous = current; \ current = current->Link; \ } \ if(current) \ { \ if(previous) \ previous->Link = current->Link; \ else \ (List) = current->Link; \ (Elem)->Link = NULL; \ } \ } #define ListDelete(List,Elem,Link,ElemType) \ { \ ElemType *copy = (Elem); \ ListDetach(List,copy,Link,ElemType); \ mfree(copy); \ } #define ListIterate(List,Counter,Link) \ ( (Counter) = ((List) ? (((Counter) ? (Counter)->Link : (List))) : NULL)) /* Elem handling routines */ #define ListElemAlloc(G,Elem,ElemType) \ { \ if(!(Elem)) \ { \ (Elem) = (ElemType*)mmalloc(sizeof(ElemType)); \ ErrChkPtr(G,Elem); \ } \ } #define ListElemCalloc(G,Elem,ElemType) \ { \ if(!(Elem)) \ { \ (Elem) = (ElemType*)mcalloc(sizeof(ElemType),1); \ ErrChkPtr(G,Elem); \ } \ } #define ListElemInit(List,Link) (List)->Link = NULL #define ListElemFree(Elem) { mfree(Elem); Elem = NULL; } #define GetListLength(VAR, List,Link,ElemType) \ { \ ElemType *current = (List); \ int length = 0; \ while(current) \ { \ current = current->Link; \ length++; \ } \ VAR = length; \ } /* -- JV * Doubly linked list macros * -- JV */ /* Create the circular, doubly linked list w/a sentinel node */ #define DListInit(List, Pre, Post, ElemType) \ do { \ List = (ElemType*)malloc(sizeof(ElemType)); \ (List)->Pre = (List)->Post = List; \ } while(0) /* DListInsert -- Insert Elem at head of list * List -- any structure with previous and next pointers (a doubly linked list) * Elem -- the Element to add * Pre -- pointer to previous element in list * Post -- pointer to next element in list */ #define DListInsert(List,Elem,Pre,Post) \ do {\ (Elem)->Post = List; \ (Elem)->Pre = (List)->Pre; \ (List)->Pre = (Elem); \ (Elem)->Pre->Post = (Elem); \ } while(0) /* DListRemove -- remove Element from the list, do not delete it * Elem -- the element to remove * Pre -- the link to the previous element * Post -- the link to the next element */ #define DListRemove(Elem,Pre,Post) \ do { \ if ((Elem)->Pre && (Elem)->Post) { \ (Elem)->Pre->Post = (Elem)->Post; \ (Elem)->Post->Pre = (Elem)->Pre; \ } \ (Elem)->Pre = (Elem)->Post = NULL; \ } while (0) /* DListIterate -- Iterate Elem across all items in List using Post as the link to next */ #define DListIterate(List,Elem,Post) \ for((Elem) = (List)->Post; (Elem) != (List); (Elem) = (Elem)->Post) /* Can similarly do reverse iteration w/Post=Pre */ /* For all these ElemAlloc macros, it calls if(!Elem) * indicating that all blank incoming Elem's must be initialized * to NULL. Just calling :ElemType* foo;" won't do. */ #define DListElemAlloc(G,Elem,ElemType) \ do { \ if(!(Elem)) \ { \ (Elem) = (ElemType*)mmalloc(sizeof(ElemType)); \ ErrChkPtr(G,Elem); \ } \ } while (0) #define DListElemCalloc(G,Elem,ElemType) \ do { \ if(!(Elem)) \ { \ (Elem) = (ElemType*)mcalloc(sizeof(ElemType),1); \ ErrChkPtr(G,Elem); \ } \ } while (0) #define DListElemInit(Elem,Pre,Post) (Elem)->Pre = (Elem)->Post = NULL #define DListElemFree(Elem) { mfree(Elem); Elem = NULL; } #endif /* _H_ListMacros */