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.