-*- Mode: Modula-3 -*-
*
* For information about this program, contact Blair MacIntyre
* (bm@cs.columbia.edu) or Steven Feiner (feiner@cs.columbia.edu)
* at the Computer Science Dept., Columbia University,
* 1214 Amsterdam Ave. Mailstop 0401, New York, NY, 10027.
*
* Copyright (C) 1995, 1996 by The Trustees of Columbia University in the
* City of New York. Blair MacIntyre, Computer Science Department.
* See file COPYRIGHT-COLUMBIA for details.
*
* Author : Blair MacIntyre
* Created On : Wed Jul 19 10:55:27 1995
* Last Modified By: Blair MacIntyre
* Last Modified On: Fri Sep 5 19:18:23 1997
* Update Count : 14
*
* $Source: /usr/cvs/cm3/m3-libs/listfuncs/src/ListFuncs.mg,v $
* $Date: 2001-12-01 14:46:08 $
* $Author: wagner $
* $Revision: 1.2 $
*
* $Log: ListFuncs.mg,v $
* Revision 1.2 2001-12-01 14:46:08 wagner
* add copyright notes and fix overrides for cm3
*
* added: listfuncs/COPYRIGHT-COLUMBIA
* added: listfuncs/src/COPYRIGHT-COLUMBIA
* modified: listfuncs/src/ListFuncs.ig
* modified: listfuncs/src/ListFuncs.mg
* modified: listfuncs/src/m3overrides
*
* Revision 1.1.1.1 2001/12/01 14:42:18 wagner
* Blair MacIntyre's listfuncs library
*
* Revision 1.3 1997/10/22 14:20:59 bm
* added Count function
*
* Revision 1.2 1997/06/29 18:27:58 bm
* Fixed header
*
*
* HISTORY
GENERIC MODULE ListFuncs(Elem, List);
PROCEDURE DeleteD(VAR listHead: T; READONLY elem: Elem.T): T =
VAR list := listHead;
prev := list;
BEGIN
IF list = NIL THEN
RETURN NIL;
END;
IF Elem.Equal(list.head, elem) THEN
listHead := list.tail;
list.tail := NIL;
ELSE
list := list.tail;
WHILE list # NIL AND NOT Elem.Equal(list.head, elem) DO
prev := list;
list := list.tail;
END;
IF list # NIL THEN
prev.tail := list.tail;
list.tail := NIL;
END;
END;
RETURN list;
END DeleteD;
PROCEDURE DeleteAllD(VAR listHead: T; READONLY elem: Elem.T): T =
VAR temp: List.T;
list: List.T := listHead;
ret : List.T := NIL;
BEGIN
(* Pull out the ones at the beginning of the list. *)
WHILE list # NIL AND Elem.Equal(list.head, elem) DO
temp := ret;
ret := list;
list := list.tail;
ret.tail := temp;
END;
listHead := list;
IF list = NIL THEN
RETURN ret;
END;
WHILE list.tail # NIL DO
IF Elem.Equal(list.tail.head, elem) THEN
(* move the element to the return list. *)
temp := ret;
ret := list.tail;
list.tail := list.tail.tail;
ret.tail := temp;
ELSE
(* just advance to the next one. *)
list := list.tail;
END;
END;
RETURN ret;
END DeleteAllD;
PROCEDURE Count(l: T; READONLY e: Elem.T): INTEGER =
VAR c: INTEGER := 0;
BEGIN
WHILE l # NIL DO
IF Elem.Equal(l.head, e) THEN INC(c) END;
l := l.tail;
END;
RETURN c;
END Count;
VAR cache: T := NIL;
PROCEDURE New(READONLY elem: Elem.T): T =
VAR new: T;
BEGIN
IF cache # NIL THEN
new := cache;
cache := cache.tail;
ELSE
new := NEW(T);
END;
new.head := elem;
RETURN new;
END New;
PROCEDURE Free(list: T): T =
VAR ret := list.tail;
BEGIN
list.tail := cache;
cache := list;
RETURN ret;
END Free;
BEGIN
END ListFuncs.