[Back to POINTERS SWAG index] [Back to Main SWAG index] [Original]
UNIT LinkList;
{-------------------------------------------------
          Generic linked list object            -
-------------------------------------------------}
{***************************************************************}
                          INTERFACE
{***************************************************************}
TYPE
    { Generic Linked List Handler Definition }
  NodeValuePtr = ^NodeValue;
  NodeValue = OBJECT
    CONSTRUCTOR Init;
    DESTRUCTOR  Done; VIRTUAL;
  END;
  NodePtr = ^Node;
  Node = RECORD
    Retrieve : NodeValuePtr;
    Next     : NodePtr;
  END;
    { Specific Linked List Handler Definition }
  NodeListPtr = ^NodeList;
  NodeList = OBJECT
    Items : NodePtr;
    CONSTRUCTOR Init;
    DESTRUCTOR Done; VIRTUAL;
    PROCEDURE Add (A_Value : NodeValuePtr);
    (* Iterator Functions *)
    PROCEDURE StartIterator (VAR Ptr : NodePtr);
    PROCEDURE NextValue (VAR Ptr : NodePtr);
    FUNCTION AtEndOfList (Ptr : NodePtr) : Boolean;
  END;
{***************************************************************}
                         IMPLEMENTATION
{***************************************************************}
CONSTRUCTOR NodeValue.Init;
BEGIN
END;
DESTRUCTOR NodeValue.Done;
BEGIN
END;
CONSTRUCTOR NodeList.Init;
BEGIN
  Items := NIL;
END;
DESTRUCTOR NodeList.Done;
    VAR
         Temp : NodePtr;
BEGIN
    WHILE Items <> NIL DO
    BEGIN
         Temp := Items;
         IF Temp^.Retrieve <> NIL THEN
              Dispose (Temp^.Retrieve, Done);
         Items := Items^.Next;
         Dispose (Temp);
    END;
END;
PROCEDURE NodeList.Add (A_Value : NodeValuePtr);
    VAR
         Cell : NodePtr;
         Temp : NodePtr;
BEGIN
    (* Go TO the END OF the linked list. *)
    Cell := Items;
    IF Cell <> NIL THEN
         WHILE Cell^.Next <> NIL DO
              Cell := Cell^.Next;
    New (Temp);
    Temp^.Retrieve := A_Value;
    Temp^.Next := NIL;
    IF Items = NIL
    THEN
         Items := Temp
    ELSE
         Cell^.Next := Temp;
END;
PROCEDURE NodeList.StartIterator (VAR Ptr : NodePtr);
BEGIN
    Ptr := Items;
END;
PROCEDURE NodeList.NextValue (VAR Ptr : NodePtr);
BEGIN
    IF Ptr <> NIL THEN
    Ptr := Ptr^.Next;
END;
FUNCTION NodeList.AtEndOfList (Ptr : NodePtr) : Boolean;
BEGIN
  AtEndOfList := (Ptr = NIL);
END;
END.
{ DEMO PROGRAM }
PROGRAM LL_Demo;
USES LinkList;
{ Turbo Pascal Linked List Object Example }
TYPE
  DataValuePtr = ^DataValue;
  DataValue = OBJECT (NodeValue)
    Value : Real;
    CONSTRUCTOR Init (A_Value : Real);
    FUNCTION TheValue : Real;
  END;
  DataList = OBJECT (NodeList)
    FUNCTION CurrentValue (Ptr : NodePtr) : Real;
    PROCEDURE SetCurrentValue (Ptr : NodePtr; Value : Real);
  END;
VAR
    Itr : NodePtr;
    TestLink : DataList;
{------ Unique methods to create for your linked list type -----}
CONSTRUCTOR DataValue.Init (A_Value : Real);
BEGIN
    Value := A_Value;
END;
FUNCTION DataValue.TheValue : Real;
BEGIN
  TheValue := Value;
END;
FUNCTION DataList.CurrentValue (Ptr : NodePtr) : Real;
BEGIN
  CurrentValue := DataValuePtr (Ptr^.Retrieve)^.TheValue;
END;
PROCEDURE DataList.SetCurrentValue (Ptr : NodePtr; Value : Real);
BEGIN
  DataValuePtr (Ptr^.Retrieve)^.Value := Value;
END;
BEGIN
  TestLink.Init;        {Create the list then add 5 values to it}
  TestLink.Add (New (DataValuePtr, Init (1.0)));
  TestLink.Add (New (DataValuePtr, Init (2.0)));
  TestLink.Add (New (DataValuePtr, Init (3.0)));
  TestLink.Add (New (DataValuePtr, Init (4.0)));
  TestLink.Add (New (DataValuePtr, Init (5.0)));
  TestLink.StartIterator (Itr);      {Display the list on screen}
  WHILE NOT TestLink.AtEndOfList (Itr) DO BEGIN
    Write (TestLink.CurrentValue (Itr) : 5 : 1);
    TestLink.NextValue (Itr);
    END;
  WriteLn;
  TestLink.StartIterator (Itr);  {Change some values in the list}
  TestLink.SetCurrentValue (Itr, 0.0);
  TestLink.NextValue (Itr);
  TestLink.SetCurrentValue (Itr, -1.0);
  TestLink.StartIterator (Itr);       {Redisplay the list values}
  WHILE NOT TestLink.AtEndOfList (Itr) DO BEGIN
    Write (TestLink.CurrentValue (Itr) : 5 : 1);
    TestLink.NextValue (Itr);
  END;
  WriteLn;
  ReadLn;
END.
[Back to POINTERS SWAG index] [Back to Main SWAG index] [Original]