blob: b28ad5da87d30c753e89481400773dd43cc28291 [file] [log] [blame]
/**************************************************************/
/* ********************************************************** */
/* * * */
/* * LISTS * */
/* * * */
/* * $Module: LIST * */
/* * * */
/* * Copyright (C) 1996, 1997, 1998, 1999, 2000 * */
/* * MPI fuer Informatik * */
/* * * */
/* * This program is free software; you can redistribute * */
/* * it and/or modify it under the terms of the GNU * */
/* * General Public License as published by the Free * */
/* * Software Foundation; either version 2 of the License, * */
/* * or (at your option) any later version. * */
/* * * */
/* * This program is distributed in the hope that it will * */
/* * be useful, but WITHOUT ANY WARRANTY; without even * */
/* * the implied warranty of MERCHANTABILITY or FITNESS * */
/* * FOR A PARTICULAR PURPOSE. See the GNU General Public * */
/* * License for more details. * */
/* * * */
/* * You should have received a copy of the GNU General * */
/* * Public License along with this program; if not, write * */
/* * to the Free Software Foundation, Inc., 59 Temple * */
/* * Place, Suite 330, Boston, MA 02111-1307 USA * */
/* * * */
/* * * */
/* $Revision$ * */
/* $State$ * */
/* $Date$ * */
/* $Author$ * */
/* * * */
/* * Contact: * */
/* * Christoph Weidenbach * */
/* * MPI fuer Informatik * */
/* * Stuhlsatzenhausweg 85 * */
/* * 66123 Saarbruecken * */
/* * Email: weidenb@mpi-sb.mpg.de * */
/* * Germany * */
/* * * */
/* ********************************************************** */
/**************************************************************/
/* $RCSfile$ */
#ifndef _LIST_
#define _LIST_
/**************************************************************/
/* Includes */
/**************************************************************/
#include "memory.h"
#include "misc.h"
/**************************************************************/
/* Structures */
/**************************************************************/
typedef struct LIST_HELP {
struct LIST_HELP *cdr;
POINTER car;
} LIST_NODE;
typedef LIST_NODE *LIST;
/**************************************************************/
/* Macros */
/**************************************************************/
static __inline__ void list_Free(LIST L)
{
memory_Free(L, sizeof(LIST_NODE));
}
static __inline__ LIST list_Nil(void)
{
return NULL;
}
static __inline__ BOOL list_Empty(LIST L)
{
return L == NULL;
}
static __inline__ BOOL list_Exist(LIST L)
{
return L != NULL;
}
static __inline__ POINTER list_Car(LIST L)
{
return L->car;
}
static __inline__ POINTER list_NCar(LIST *L)
{
POINTER Result;
LIST Help;
Result = (*L)->car;
Help = (*L)->cdr;
list_Free(*L);
*L = Help;
return Result;
}
static __inline__ LIST list_Cdr(LIST L)
{
return L->cdr;
}
static __inline__ POINTER list_First(LIST L)
{
return list_Car(L);
}
static __inline__ POINTER list_Second(LIST L)
{
return list_Car(list_Cdr(L));
}
static __inline__ POINTER list_Third(LIST L)
{
return list_Car(list_Cdr(list_Cdr(L)));
}
static __inline__ POINTER list_Fourth(LIST L)
{
return(list_Third(list_Cdr(L)));
}
static __inline__ POINTER list_Fifth(LIST L)
{
return(list_Fourth(list_Cdr(L)));
}
static __inline__ void list_Rplacd(LIST L1, LIST L2)
{
L1->cdr = L2;
}
static __inline__ void list_Rplaca(LIST L, POINTER P)
{
L->car = P;
}
static __inline__ void list_RplacSecond(LIST L, POINTER P)
{
list_Rplaca(list_Cdr(L), P);
}
/**************************************************************/
/* Functions */
/**************************************************************/
LIST list_Copy(const LIST);
LIST list_CopyWithElement(const LIST, POINTER (*)(POINTER));
void list_InsertNext(LIST, POINTER);
void list_NMapCar(LIST, POINTER (*)(POINTER));
void list_Apply(void (*)(POINTER), LIST);
LIST list_Reverse(const LIST);
LIST list_NReverse(LIST);
void list_Split(LIST, LIST *, LIST *);
LIST list_PointerSort(LIST);
LIST list_Merge(LIST, LIST, BOOL (*)(POINTER, POINTER));
LIST list_MergeSort(LIST, BOOL (*)(POINTER, POINTER));
LIST list_InsertionSort(LIST, BOOL (*)(POINTER, POINTER));
LIST list_Sort(LIST, BOOL (*)(POINTER, POINTER));
BOOL list_SortedInOrder(LIST, BOOL (*)(POINTER, POINTER));
LIST list_NumberSort(LIST , NAT (*)(POINTER));
LIST list_GreaterNumberSort(LIST , NAT (*)(POINTER));
LIST list_NNumberMerge(LIST , LIST, NAT (*)(POINTER));
POINTER list_DequeueNext(LIST);
POINTER list_NthElement(LIST, NAT);
void list_DeleteWithElement(LIST, void (*)(POINTER));
NAT list_DeleteWithElementCount(LIST, void (*)(POINTER));
LIST list_DeleteElement(LIST, POINTER, BOOL (*)(POINTER, POINTER));
LIST list_DeleteElementIf(LIST, BOOL (*)(POINTER));
LIST list_DeleteElementIfFree(LIST, BOOL (*)(POINTER), void (*)(POINTER));
LIST list_DeleteElementFree(LIST, POINTER, BOOL (*)(POINTER, POINTER), void (*)(POINTER));
LIST list_DeleteOneElement(LIST, POINTER, BOOL (*)(POINTER, POINTER));
LIST list_PointerDeleteElement(LIST, POINTER);
LIST list_PointerDeleteElementFree(LIST, POINTER, void (*)(POINTER));
LIST list_PointerDeleteOneElement(LIST, POINTER);
BOOL list_DeleteFromList(LIST*, POINTER);
BOOL list_DeleteOneFromList(LIST*, POINTER);
LIST list_DeleteDuplicates(LIST, BOOL (*)(POINTER, POINTER));
LIST list_DeleteDuplicatesFree(LIST, BOOL (*)(POINTER, POINTER), void (*)(POINTER));
LIST list_PointerDeleteDuplicates(LIST);
BOOL list_IsSetOfPointers(LIST);
LIST list_NPointerUnion(LIST, LIST);
LIST list_NUnion(LIST, LIST, BOOL (*)(POINTER, POINTER));
LIST list_NListTimes(LIST, LIST);
LIST list_NIntersect(LIST, LIST, BOOL (*)(POINTER, POINTER));
void list_NInsert(LIST, LIST);
LIST list_NPointerIntersect(LIST, LIST);
BOOL list_HasIntersection(LIST, LIST);
LIST list_NPointerDifference(LIST, LIST);
LIST list_NDifference(LIST, LIST, BOOL (*)(POINTER, POINTER));
LIST list_NMultisetDifference(LIST, LIST, BOOL (*)(POINTER, POINTER));
BOOL list_PointerReplaceMember(LIST, POINTER, POINTER);
void list_DeleteAssocListWithValues(LIST, void (*)(POINTER));
POINTER list_AssocListValue(LIST, POINTER);
LIST list_AssocListPair(LIST, POINTER);
LIST list_MultisetDistribution(LIST);
int list_CompareMultisetsByElementDistribution(LIST, LIST);
NAT list_Length(LIST);
NAT list_Bytes(LIST);
/**************************************************************/
/* Functional Inline Functions */
/**************************************************************/
static __inline__ LIST list_Cons(POINTER Ptr, const LIST List)
{
LIST Cell;
Cell = (LIST)memory_Malloc(sizeof(LIST_NODE));
Cell->car = Ptr;
Cell->cdr = List;
return Cell;
}
static __inline__ LIST list_Nconc(LIST List1, LIST List2)
{
LIST Result;
if (list_Empty(List1))
return List2;
if (list_Empty(List2))
return List1;
Result = List1;
for (List1 = Result; !list_Empty(list_Cdr(List1)); List1 = list_Cdr(List1))
/* empty */;
List1->cdr = List2;
return Result;
}
static __inline__ LIST list_List(POINTER P)
{
return list_Cons(P,list_Nil());
}
static __inline__ LIST list_Append(LIST List1, LIST List2)
{
LIST Result;
if (list_Empty(List1))
return List2;
if (list_Empty(List2))
return list_Copy(List1);
Result = list_Copy(List1);
for (List1 = Result; !list_Empty(list_Cdr(List1)); List1 = list_Cdr(List1))
/* empty */;
List1->cdr = List2;
return Result;
}
static __inline__ void list_Delete(LIST L)
{
LIST Current;
Current = L;
while (!list_Empty(Current)) {
L = list_Cdr(L);
list_Free(Current);
Current = L;
}
}
static __inline__ BOOL list_Member(LIST List, POINTER Element,
BOOL (*Test)(POINTER, POINTER))
/**************************************************************
INPUT: A list and an element pointer and an equality test for two elements.
RETURNS: TRUE iff Element is in List with respect to Test
***************************************************************/
{
while (!list_Empty(List)) {
if (Test(Element, list_Car(List)))
return TRUE;
List = list_Cdr(List);
}
return FALSE;
}
static __inline__ BOOL list_PointerMember(LIST List, POINTER Element)
/**************************************************************
INPUT: A list and an element pointer.
RETURNS: TRUE iff Element is in List with respect to pointer equality.
***************************************************************/
{
while (!list_Empty(List)) {
if (Element == list_Car(List))
return TRUE;
List = list_Cdr(List);
}
return FALSE;
}
/**************************************************************/
/* Stack Macros */
/**************************************************************/
static __inline__ LIST list_StackBottom(void)
{
return list_Nil();
}
static __inline__ BOOL list_StackEmpty(LIST S)
{
return list_Empty(S);
}
static __inline__ LIST list_Push(POINTER I, LIST L)
{
return list_Cons(I, L);
}
static __inline__ POINTER list_Top(LIST L)
{
return list_Car(L);
}
static __inline__ LIST list_Pop(LIST L)
{
LIST Aux = L;
L = list_Cdr(L);
list_Free(Aux);
return L;
}
static __inline__ void list_RplacTop(LIST L, POINTER P)
{
list_Rplaca(L, P);
}
static __inline__ LIST list_StackFree(LIST L)
{
while (!list_StackEmpty(L))
L = list_Pop(L);
return list_Nil();
}
/**************************************************************/
/* Pair Macros */
/**************************************************************/
static __inline__ LIST list_PairNull(void)
{
return list_Nil();
}
static __inline__ LIST list_PairCreate(POINTER P1, POINTER P2)
{
return list_Cons(P1, P2);
}
static __inline__ void list_PairFree(LIST L)
{
list_Free(L);
}
static __inline__ POINTER list_PairFirst(LIST L)
{
return list_Car(L);
}
static __inline__ POINTER list_PairSecond(LIST L)
{
return (POINTER)list_Cdr(L);
}
static __inline__ void list_PairRplacSecond(LIST L, POINTER P)
{
list_Rplacd(L,P);
}
static __inline__ void list_DeletePairList(LIST L)
/* Delete a list of pairs */
{
list_DeleteWithElement(L, (void (*)(POINTER))list_PairFree);
}
static __inline__ void list_DeleteDistribution(LIST L)
{
list_DeletePairList(L);
}
/**************************************************************/
/* Assoc Lists */
/**************************************************************/
static __inline__ LIST list_AssocCons(LIST L, POINTER Key, POINTER Value)
{
return list_Cons(list_PairCreate(Key, Value), L);
}
#endif