mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 00:48:37 +02:00
189 lines
3.6 KiB
ObjectPascal
189 lines
3.6 KiB
ObjectPascal
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.
|