blob: c23f065d608c57dce12f42ad62d5733f002c8137 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
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;
{ 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;
|