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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
|
program tarray11;
{$mode objfpc}
type
TLongIntArray = array of LongInt;
ITest = interface
end;
TITestArray = array of ITest;
TTest = class(TInterfacedObject, ITest)
private
fValue: LongInt;
public
constructor Create(aValue: LongInt);
destructor Destroy; override;
end;
var
freed: array of LongInt;
constructor TTest.Create(aValue: LongInt);
begin
fValue := aValue;
end;
destructor TTest.Destroy;
begin
SetLength(freed, Length(freed) + 1);
freed[High(freed)] := fValue;
inherited;
end;
procedure CheckArray(a, b: array of LongInt; err: LongInt);
var
i: LongInt;
begin
if Length(a) <> Length(b) then
Halt(err);
for i := Low(a) to High(a) do begin
if a[i] <> b[i] then
Halt(err + 1);
end;
end;
function CreateArray(len: LongInt): TLongIntArray;
var
i: LongInt;
begin
SetLength(Result, len);
for i := 0 to len - 1 do
Result[i] := i;
end;
procedure CreateArrayTest(len: LongInt; out arr: TITestArray);
var
i: LongInt;
begin
SetLength(arr, len);
for i := 0 to len - 1 do
arr[i] := TTest.Create(i);
end;
procedure CheckFreedArray(arr: array of LongInt; err: LongInt);
var
l, f: LongInt;
found: Boolean;
begin
if Length(freed) <> Length(arr) then
Halt(err);
for f in freed do begin
found := false;
for l in arr do
if l = f then begin
found := true;
break;
end;
if not found then
Halt(err + 1);
end;
end;
{procedure PrintArray(a: array of LongInt);
var
i: LongInt;
begin
Writeln('Length: ', Length(a));
Write('Data: ');
for i := Low(a) to High(a) do begin
if i > Low(a) then
Write(', ');
Write(a[i]);
end;
Writeln;
end;}
var
code: LongInt;
function next: LongInt;
begin
code := code + 2;
next := code;
end;
var
a, b: TLongIntArray;
c, d: TITestArray;
begin
code := 0;
{ remove from the middle }
a := CreateArray(10);
Delete(a, 2, 4);
CheckArray(a, [0, 1, 6, 7, 8, 9], next);
{ remove from the beginning }
a := CreateArray(10);
Delete(a, 0, 4);
CheckArray(a, [4, 5, 6, 7, 8, 9], next);
{ remove from the end }
a := CreateArray(10);
Delete(a, 6, 4);
CheckArray(a, [0, 1, 2, 3, 4, 5], next);
{ delete whole array }
a := CreateArray(10);
Delete(a, 0, 10);
CheckArray(a, [], next);
{ out of bounds start and count are ignored }
a := CreateArray(5);
Delete(a, -1, 0);
CheckArray(a, [0, 1, 2, 3, 4], next);
a := CreateArray(5);
Delete(a, -1, 2);
CheckArray(a, [0, 1, 2, 3, 4], next);
a := CreateArray(5);
Delete(a, -1, -1);
CheckArray(a, [0, 1, 2, 3, 4], next);
a := CreateArray(5);
Delete(a, 2, -1);
CheckArray(a, [0, 1, 2, 3, 4], next);
a := CreateArray(5);
Delete(a, 5, 1);
CheckArray(a, [0, 1, 2, 3, 4], next);
a := CreateArray(5);
{ count is capped to the array's end }
a := CreateArray(5);
Delete(a, 3, 4);
CheckArray(a, [0, 1, 2], next);
{ check that Delete does not influence copies }
a := CreateArray(5);
b := a;
Delete(a, 2, 2);
CheckArray(a, [0, 1, 4], next);
CheckArray(b, [0, 1, 2, 3, 4], next);
Delete(b, 1, 3);
CheckArray(a, [0, 1, 4], next);
CheckArray(b, [0, 4], next);
{ ensure that reference counted types are freed correctly }
CreateArrayTest(5, c);
Delete(c, 2, 2);
CheckFreedArray([2, 3], next);
freed := nil;
c := nil;
CheckFreedArray([0, 1, 4], next);
freed := nil;
{ ensure that reference counted types are not destroyed if there's still a
reference to them }
CreateArrayTest(5, c);
d := c;
Delete(c, 2, 2);
CheckFreedArray([], next);
freed := nil;
c := nil;
CheckFreedArray([], next);
freed := nil;
d := nil;
CheckFreedArray([0, 1, 2, 3, 4], next);
end.
|