This is a new site that's currently running on alpha code. There are going to be bugs. If you discover any, please report them on the site's issues page (GitHub account required). Thanks.
Warning: Many URLs are going to change. Refer to the README file to discover which library project's documentation has been completed.
Project: Array Utilities Unit
Unit: DelphiDabbler.Lib.ArrayUtils
Record: TArrayUtils
Applies to: ~>0.1
type
TCallback<T> = reference to procedure (const AElem: T);
class procedure DeleteAndRelease<T>(var A: TArray<T>; const AIndex: Integer;
const AReleaser: TCallback<T>);
overload; static;
class procedure DeleteAndRelease<T>(var A: TArray<T>;
const AIndices: array of Integer; const AReleaser: TCallback<T>);
overload; static;
Deletes the element or elements at one or more indices in an array and releases any resources associated with the deleted elements.
Parameters:
A - Array from which the elements are to be deleted. The array is updated in place.
AIndex - Index of a single element to be deleted. (First overload only.)
If A is empty, if AIndex < 0
or if AIndex ≥ Length(A)
then no deletion takes place and A is unchanged.
AIndices - An integer array of indices of elements to be deleted. (Second overload only.)
If any index < 0
or ≥ Length(A)
then that index is ignored.
Duplicate indices are ignored.
If A is empty then no deletion takes place and A is unchanged.
AReleaser - Callback procedure called for each deleted element. Must release any resource associated with the element.
Parameter(s):
Both examples below use a custom TMockResource record that emulates a resource that must be released. The record keeps track of the total number of instantiations. It is defined as follows:
type
TMockResource = record
public
constructor Create(const AField: Integer);
procedure Release;
var Field: Integer;
class var InstanceCount: Cardinal;
end;
{ TMockResource }
constructor TMockResource.Create(const AField: Integer);
begin
Field := AField;
Inc(InstanceCount);
end;
procedure TMockResource.Release;
begin
Dec(InstanceCount);
end;
This example illustrates how a single element deleted from an array has its associated resource deleted.
procedure DeleteAndRelease_Eg1;
var
R, R0, R1, R2, R3: TMockResource;
RA, Expected: TArray<TMockResource>;
begin
// create array of 4 "resources"
R0 := TMockResource.Create(0);
R1 := TMockResource.Create(1);
R2 := TMockResource.Create(2);
R3 := TMockResource.Create(3);
RA := TArray<TMockResource>.Create(R0, R1, R2, R3);
Assert(Length(RA) = 4, '4 element array expected');
Assert(TMockResource.InstanceCount = 4, 'Expected 4 "resources" allocated');
// delete and release element @ index 2
TArrayUtils.DeleteAndRelease<TMockResource>(
RA,
2,
procedure (const AElem: TMockResource) begin AElem.Release end
);
// check array size reduced and one resource released
Assert(Length(RA) = 3, '3 element array expected following deletion');
Assert(TMockResource.InstanceCount = 3, 'Expected 3 "resources" allocated');
Expected := TArray<TMockResource>.Create(R0, R1, R3);
Assert(TArrayUtils.Equal<TMockResource>(Expected, RA),
'updated array content not as expected');
// clear up remaining allocations
for R in RA do R.Release;
Assert(TMockResource.InstanceCount = 0, 'Expected all "resources" released');
end;
This example illustrates how several elements deleted from an array have associated resources deleted.
procedure DeleteAndRelease_Eg2;
var
R, R0, R1, R2, R3, R4: TMockResource;
RA, Expected: TArray<TMockResource>;
begin
// create array of 5 "resources"
R0 := TMockResource.Create(0);
R1 := TMockResource.Create(1);
R2 := TMockResource.Create(2);
R3 := TMockResource.Create(3);
R4 := TMockResource.Create(4);
RA := TArray<TMockResource>.Create(R0, R1, R2, R3, R4);
Assert(Length(RA) = 5, '5 element array expected');
Assert(TMockResource.InstanceCount = 5, 'Expected 5 "resources" allocated');
// delete and release elements @ indices 0, 2, 3
TArrayUtils.DeleteAndRelease<TMockResource>(
RA,
[2, 3, 0],
procedure (const AElem: TMockResource) begin AElem.Release end
);
// check array size reduced and three resources released
Assert(Length(RA) = 2, '2 element array expected following deletion');
Assert(TMockResource.InstanceCount = 2, 'Expected 2 "resources" allocated');
Expected := TArray<TMockResource>.Create(R1, R4);
Assert(TArrayUtils.Equal<TMockResource>(Expected, RA),
'updated array content not as expected');
// clear up remaining allocations
for R in RA do R.Release;
Assert(TMockResource.InstanceCount = 0, 'Expected all "resources" released');
end;