-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnodetree.pas
104 lines (86 loc) · 2.29 KB
/
nodetree.pas
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
unit nodetree;
{$mode objfpc}{$h+}
{$modeswitch advancedrecords}
interface
procedure MyZeroMemory(var x; count: SizeInt); inline;
type
TSimpleAllocator = class
class function GetMem(Size: PtrUInt): Pointer; static; inline;
class procedure FreeMem(p: Pointer); static; inline;
end;
generic TNode<TNodeData, TNodeComparator, TAllocator> = record
type
PNode = ^TNode;
PNodeData = ^TNodeData;
public
Sibling: PNode;
Child: PNode;
NodeData: TNodeData;
procedure FreeReqursive;
class function NewNode: PNode; static; inline;
procedure AddChild(node: PNode); inline;
procedure AddSibling(node: PNode); inline;
function AddChild: PNode; inline;
function AddSibling: PNode; inline;
function FindChild(Data: Pointer): PNode; inline;
end;
implementation
procedure MyZeroMemory(var x; count: SizeInt); inline;
begin
if IsConstValue(count) then
begin
if count mod 8 = 0 then FillQWord(x, count div 8, 0)
else if count mod 4 = 0 then FillDWord(x, count div 4, 0)
else if count mod 2 = 0 then FillWord(x, count div 2, 0)
else FillChar(x, count, 0);
end else FillChar(x, count, 0);
end;
class function TSimpleAllocator.GetMem(Size: PtrUInt): Pointer;
begin
Result:=System.GetMem(Size);
MyZeroMemory(Result^, Size);
end;
class procedure TSimpleAllocator.FreeMem(p: Pointer);
begin
System.FreeMem(p);
end;
procedure TNode.FreeReqursive;
begin
if Assigned(Sibling) then Sibling^.FreeReqursive;
if Assigned(Child) then Child^.FreeReqursive;
TAllocator.FreeMem(@Self);
end;
class function TNode.NewNode: PNode;
begin
Result:=TAllocator.GetMem(SizeOf(TNode)); // Инициализацию памяти (обнуление) - должен делать аллокатор
end;
procedure TNode.AddChild(node: PNode);
begin
node^.Sibling:=Child;
Child:=node;
end;
procedure TNode.AddSibling(node: PNode);
begin
node^.Sibling:=Sibling;
Sibling:=node;
end;
function TNode.AddChild: PNode;
begin
Result:=NewNode;
AddChild(Result);
end;
function TNode.AddSibling: PNode;
begin
Result:=NewNode;
AddSibling(Result);
end;
function TNode.FindChild(Data: Pointer): PNode;
begin
Result:=Child;
while Assigned(Result) do
begin
if TNodeComparator.Compare(@Result^.NodeData, Data)=0 then Exit;
Result:=Result^.Sibling;
end;
end;
end.