unit llist;

interface

{ List item object }
{ by Emil Mikulic  }

type PItem=^TItem;
     TItem=object
       next:PItem;
       { Initialise item and add next }
       constructor init(nxt:PItem);
       { Insert an item between the current and the next }
       procedure insert(nxt:PItem);
       { Add an item on to the end of the list }
       procedure add(nxt:PItem);
       { Do something for every item }
       procedure foreach; virtual;
       { Do something for current item }
       procedure custom; virtual;
       { Get some value }
       function get:integer; virtual;
       { Destroy current item and all items after it }
       destructor done;
       end;

implementation

constructor TItem.init(nxt:PItem);
begin
 { Assign next item }
 next:=nxt;
end;

procedure TItem.insert(nxt:PItem);
var temp:PItem;
begin
 { Special case: no insert because we're the end of the list }
 if next=nil then
   { Set current next pointer to inserted item }
   next:=nxt

 else begin

 { Keep a temporary reference }
 temp:=next;
 { Set current next pointer to inserted item }
 next:=nxt;
 { Pass the buck }
 nxt^.insert(temp);
 end;
end;

procedure TItem.add(nxt:PItem);
begin
 { If at end of list, add the item }
 if next=nil then next:=nxt
 { If not, pass the buck }
 else next^.add(nxt);
end;

procedure TItem.foreach;
begin
end;

procedure TItem.custom;
begin
end;

function TItem.get:integer;
begin
end;

destructor TItem.done;
begin
 { If there is a next item }
 if next<>nil then
   { then dispose of it - it'll continue dismantling the list }
   dispose(next,done);
 { If not then your work is done }
end;

end.

{ ---------------------------------CUT------------------------------- }

LINKED LIST (LLIST)
Unit Documentation

by Emil Mikulic

The comments for the TItem object should explain how this works:

type PItem=^TItem;
     TItem=object
       next:PItem;
       { Initialise item and add next }
       constructor init(nxt:PItem);
       { Insert an item between the current and the next }
       procedure insert(nxt:PItem);
       { Add an item on to the end of the list }
       procedure add(nxt:PItem);
       { Do something for every item }
       procedure foreach; virtual;
       { Do something for current item }
       procedure custom; virtual;
       { Get some value }
       function get:integer; virtual;
       { Destroy current item and all items after it }
       destructor done;
       end;

Now, this linked list object is useless. All it can do is
add more items to itself and properly clean up by
disposing of all the items in order.

Here's how a linked list may look in the memory:
LEGEND
Letters = items
Lines (- / \ |) = links

A
 \                     - -E
   \    - -C - - - D /     \
    B /                      \-F


Now, here's what it would look like if we ADDED an item: 

A                                    X
 \                     - -E        /
   \    - -C - - - D /     \     /
    B /                      \-F

Now, let's take a simpler list:

A - - B - - C - - D

Here's what that list would look like if I was to INSERT an item
on to B:

A - - B           C - - D
        \       /
          \   /
            X

The items don't move around - just the links.

The linked list is useless unless you create an object BASED on
TItem. An excellent example of this is MENU.PAS which uses 
TItem as a base for its TMenuItem list.

Also, due to the limits of Turbo Pascal when it comes to
polymorphic objects, it may be very hard to use TItem unless
you do some custom modifications to it. If this is the case
then make sure you make a copy of LLIST.PAS and work on
the copy because MENU uses LLIST.

If you understood most of this document then you have
either just learned or already know:
        * Object-oriented programming
        * Database structuring
        * Polymorphism
        * Virtual functions


