Browse Source

* Needed for classes unit

michael 6 years ago
parent
commit
ee110fbed3
1 changed files with 131 additions and 0 deletions
  1. 131 0
      packages/rtl/simplelinkedlist.pas

+ 131 - 0
packages/rtl/simplelinkedlist.pas

@@ -0,0 +1,131 @@
+unit simplelinkedlist;
+
+{$mode objfpc}
+
+interface
+
+Type
+  TLinkedListItem = Class
+  Public
+    Next : TLinkedListItem;
+  end;
+  TLinkedListItemClass = Class of TLinkedListItem;
+
+  { TLinkedListVisitor }
+
+  TLinkedListVisitor = Class
+    Function Visit(Item : TLinkedListItem) : Boolean; virtual; abstract;
+  end;
+  { TLinkedList }
+
+  TLinkedList = Class
+  private
+    FItemClass: TLinkedListItemClass;
+    FRoot: TLinkedListItem;
+    function GetCount: Integer;
+  Public
+    Constructor Create(AnItemClass : TLinkedListItemClass); virtual;
+    Destructor Destroy; override;
+    Procedure Clear;
+    Function Add : TLinkedListItem;
+    Procedure ForEach(Visitor: TLinkedListVisitor);
+    Procedure RemoveItem(Item : TLinkedListItem; FreeItem : Boolean = False);
+    Property Root : TLinkedListItem Read FRoot;
+    Property ItemClass : TLinkedListItemClass Read FItemClass;
+    Property Count : Integer Read GetCount;
+  end;
+
+implementation
+
+uses sysutils;
+
+{ TLinkedList }
+
+function TLinkedList.GetCount: Integer;
+
+Var
+  I : TLinkedListItem;
+
+begin
+  I:=FRoot;
+  Result:=0;
+  While I<>Nil do
+    begin
+    I:=I.Next;
+    Inc(Result);
+    end;
+end;
+
+constructor TLinkedList.Create(AnItemClass: TLinkedListItemClass);
+begin
+  FItemClass:=AnItemClass;
+end;
+
+destructor TLinkedList.Destroy;
+begin
+  Clear;
+  inherited Destroy;
+end;
+
+procedure TLinkedList.Clear;
+
+Var
+   I : TLinkedListItem;
+
+begin
+  // Can't use visitor, because it'd kill the next pointer...
+  I:=FRoot;
+  While I<>Nil do
+    begin
+    FRoot:=I;
+    I:=I.Next;
+    FRoot.Next:=Nil;
+    FreeAndNil(FRoot);
+    end;
+end;
+
+function TLinkedList.Add: TLinkedListItem;
+begin
+  Result:=FItemClass.Create;
+  Result.Next:=FRoot;
+  FRoot:=Result;
+end;
+
+procedure TLinkedList.ForEach(Visitor : TLinkedListVisitor);
+
+Var
+  I : TLinkedListItem;
+
+begin
+  I:=FRoot;
+  While (I<>Nil) and Visitor.Visit(I) do
+    I:=I.Next;
+end;
+
+procedure TLinkedList.RemoveItem(Item: TLinkedListItem; FreeItem : Boolean = False);
+
+Var
+  I : TLinkedListItem;
+
+begin
+  If (Item<>Nil) and (FRoot<>Nil) then
+    begin
+    If (Item=FRoot) then
+      FRoot:=Item.Next
+    else
+      begin
+      I:=FRoot;
+      While (I.Next<>Nil) and (I.Next<>Item) do
+        I:=I.Next;
+      If (I.Next=Item) then
+        I.Next:=Item.Next;
+      end;
+    If FreeItem Then
+      Item.Free;
+    end;
+end;
+
+
+
+end.
+