1 | unit Xvcl.Generics;
|
---|
2 |
|
---|
3 | interface
|
---|
4 |
|
---|
5 | uses
|
---|
6 | SysUtils;
|
---|
7 |
|
---|
8 | type
|
---|
9 | TList<T> = class
|
---|
10 | private
|
---|
11 | FCount: Integer;
|
---|
12 | FItems: array of T;
|
---|
13 | procedure SetCount(const Value: Integer);
|
---|
14 | function GetItem(Index: Integer): T;
|
---|
15 | procedure SetItem(Index: Integer; const Value: T);
|
---|
16 | public
|
---|
17 | type
|
---|
18 | TEnumerator = class
|
---|
19 | private
|
---|
20 | FList: TList<T>;
|
---|
21 | FIndex: Integer;
|
---|
22 | function GetCurrent: T;
|
---|
23 | public
|
---|
24 | function MoveNext: Boolean;
|
---|
25 | property Current: T read GetCurrent;
|
---|
26 | end;
|
---|
27 | function GetEnumerator: TEnumerator;
|
---|
28 | function Add(Item: T): Integer;
|
---|
29 | function Remove(Item: T): Integer;
|
---|
30 | procedure Delete(Index: Integer);
|
---|
31 | procedure Move(FromIndex, ToIndex: Integer);
|
---|
32 | function IndexOf(Item: T): Integer;
|
---|
33 | function Compare(Item1, Item2: T): Integer;
|
---|
34 | procedure Exchange(Index1, Index2: Integer);
|
---|
35 | property Count: Integer read FCount write SetCount;
|
---|
36 | property Items[Index: Integer]: T read GetItem write SetItem; default;
|
---|
37 | end;
|
---|
38 |
|
---|
39 | implementation
|
---|
40 |
|
---|
41 | { TList<T>.TEnumerator }
|
---|
42 |
|
---|
43 | function TList<T>.TEnumerator.GetCurrent: T;
|
---|
44 | begin
|
---|
45 | Result := FList.Items[FIndex];
|
---|
46 | end;
|
---|
47 |
|
---|
48 | function TList<T>.TEnumerator.MoveNext: Boolean;
|
---|
49 | begin
|
---|
50 | if FIndex < (FList.Count - 1) then begin
|
---|
51 | Inc(FIndex);
|
---|
52 | Result := True;
|
---|
53 | end else Result := False;
|
---|
54 | end;
|
---|
55 |
|
---|
56 | { TList<T> }
|
---|
57 |
|
---|
58 | function TList<T>.Add(Item: T): Integer;
|
---|
59 | begin
|
---|
60 | Count := Count + 1;
|
---|
61 | FItems[Count - 1] := Item;
|
---|
62 | Result := Count - 1;
|
---|
63 | end;
|
---|
64 |
|
---|
65 | function TList<T>.Compare(Item1, Item2: T): Integer;
|
---|
66 | begin
|
---|
67 | if CompareMem(Pointer(@Item1), Pointer(@Item2), SizeOf(T)) then Result := 0
|
---|
68 | else Result := -1;
|
---|
69 | end;
|
---|
70 |
|
---|
71 | procedure TList<T>.Delete(Index: Integer);
|
---|
72 | var
|
---|
73 | I: Integer;
|
---|
74 | begin
|
---|
75 | if (Index >= 0) and (Index < Count) then
|
---|
76 | for I := Index to Count - 2 do
|
---|
77 | Items[I] := Items[I + 1];
|
---|
78 | end;
|
---|
79 |
|
---|
80 | procedure TList<T>.Exchange(Index1, Index2: Integer);
|
---|
81 | var
|
---|
82 | Temp: T;
|
---|
83 | begin
|
---|
84 | Temp := Items[Index2];
|
---|
85 | Items[Index2] := Items[Index1];
|
---|
86 | Items[Index1] := Temp;
|
---|
87 | end;
|
---|
88 |
|
---|
89 | function TList<T>.GetEnumerator: TEnumerator;
|
---|
90 | begin
|
---|
91 | Result := TEnumerator.Create;
|
---|
92 | Result.FList := Self;
|
---|
93 | Result.FIndex := -1;
|
---|
94 | end;
|
---|
95 |
|
---|
96 | function TList<T>.GetItem(Index: Integer): T;
|
---|
97 | begin
|
---|
98 | Result := FItems[Index];
|
---|
99 | end;
|
---|
100 |
|
---|
101 | function TList<T>.IndexOf(Item: T): Integer;
|
---|
102 | var
|
---|
103 | I: Integer;
|
---|
104 | begin
|
---|
105 | I := 0;
|
---|
106 | while (I < Count) and (Compare(Items[I], Item) <> 0) do
|
---|
107 | Inc(I);
|
---|
108 | if I < Count then Result := I
|
---|
109 | else Result := -1;
|
---|
110 | end;
|
---|
111 |
|
---|
112 | procedure TList<T>.Move(FromIndex, ToIndex: Integer);
|
---|
113 | var
|
---|
114 | I: Integer;
|
---|
115 | Temp: T;
|
---|
116 | begin
|
---|
117 | if (FromIndex >= 0) and (FromIndex < Count) and
|
---|
118 | (ToIndex >= 0) and (ToIndex < Count) then begin
|
---|
119 | if FromIndex > ToIndex then begin
|
---|
120 | Temp := Items[ToIndex];
|
---|
121 | for I := ToIndex to FromIndex - 1 do
|
---|
122 | Items[I] := Items[I + 1];
|
---|
123 | Items[FromIndex] := Temp;
|
---|
124 | end else
|
---|
125 | if FromIndex < ToIndex then begin
|
---|
126 | Temp := Items[FromIndex];
|
---|
127 | for I := FromIndex to ToIndex - 1 do
|
---|
128 | Items[I] := Items[I + 1];
|
---|
129 | Items[ToIndex] := Temp;
|
---|
130 | end;
|
---|
131 | end;
|
---|
132 | end;
|
---|
133 |
|
---|
134 | function TList<T>.Remove(Item: T): Integer;
|
---|
135 | begin
|
---|
136 | Result := IndexOf(Item);
|
---|
137 | if Result >= 0 then Delete(Result);
|
---|
138 | end;
|
---|
139 |
|
---|
140 | procedure TList<T>.SetCount(const Value: Integer);
|
---|
141 | begin
|
---|
142 | FCount := Value;
|
---|
143 | SetLength(FItems, Value);
|
---|
144 | end;
|
---|
145 |
|
---|
146 | procedure TList<T>.SetItem(Index: Integer; const Value: T);
|
---|
147 | begin
|
---|
148 | FItems[Index] := Value;
|
---|
149 | end;
|
---|
150 |
|
---|
151 | end.
|
---|