| 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.
|
|---|