/* 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" #include"Result.h" #define ListInit(List) List = nullptr #define ListAppend(List,Elem,Link,ElemType) \ { \ ElemType *current = (List); \ ElemType *previous = nullptr; \ while(current) \ { \ previous = current; \ current = current->Link; \ } \ if(previous) \ previous->Link = Elem; \ else \ (List) = Elem; \ (Elem)->Link = nullptr; \ } /** * @brief appends element to list * @param list list to append element to * @param ele element to append * @tparam ElemType type of the element */ template void ListAppendT(ElemType*& list, ElemType* ele){ ElemType* current = list; ElemType* previous = nullptr; while(current){ previous = current; current = current->next; } if(previous){ previous->next = ele; } else{ list = ele; } ele->next = nullptr; } #define ListFree(List,Link,ElemType) \ { \ ElemType *current = List; \ ElemType *previous = nullptr; \ while(current) \ { \ if(previous) \ mfree(previous); \ previous = current; \ current = current->Link; \ } \ if(previous) \ mfree(previous); \ (List) = nullptr; \ } #define ListDetach(List,Elem,Link,ElemType) \ { \ ElemType *current = List; \ ElemType *previous = nullptr; \ 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 = nullptr; \ } \ } /** * @brief removes element from list * @param list list to remove element from * @param ele element to remove * @tparam ElemType type of the element * @return removed element * @note Removed element should be same as ele input. */ template ElemType* ListDetachT(ElemType*& list, ElemType* ele){ ElemType* current = list; ElemType* previous = nullptr; while(current){ if(current == ele){ break; } previous = current; current = current->next; } if(current){ if(previous){ previous->next = current->next; } else{ list = current->next; } ele->next = nullptr; } return ele; } #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))) : nullptr)) /* Elem handling routines */ #define ListElemAlloc(G,Elem,ElemType) \ { \ if(!(Elem)) \ { \ (Elem) = pymol::malloc(1); \ ErrChkPtr(G,Elem); \ } \ } #define ListElemCalloc(G,Elem,ElemType) \ { \ if(!(Elem)) \ { \ (Elem) = pymol::calloc(1); \ ErrChkPtr(G,Elem); \ } \ } #define ListElemFree(Elem) { mfree(Elem); Elem = nullptr; } /** * Retrives position of element in list * @param ele target element * @return position in list */ template pymol::Result ListGetPosition(ElemType*& list, ElemType* ele) { ElemType* current = list; std::size_t i = 0; for (; current; i++, current = current->next) { if (current == ele) { return i; } } return pymol::make_error("Element not found"); } /** * Inserts an element at given position * @param ele target element * @param pos position in list */ template pymol::Result<> ListInsertAt(ElemType*& list, ElemType* ele, std::size_t pos) { ElemType* current = list; ElemType* previous = nullptr; std::size_t i = 0; while (current) { if (i++ == pos) { ele->next = current; if (previous) { previous->next = ele; } return {}; } previous = current; current = current->next; } if (i == pos) { previous->next = ele; return {}; } return pymol::make_error("Invalid pos"); } #endif /* _H_ListMacros */