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 PopAndRelease<T>(var A: TArray<T>;
const AReleaser: TCallback<T>);
static;
Deletes the last element of a non-empty array and releases any resources associated with the deleted element.
The length of the array is reduced by one.
Parameters:
A - Array from which the element is to be removed and its associated resource released. The array is updated in place.
AReleaser - Procedure called for the deleted element that must release any resource associated with the element.
Parameter(s):
Preconditions:
If it is not necessary release a resource associated with an element that is popped off an array then Pop<T> should be used instead of PopAndRelease<T>.
There is no corresponding version of Push<T> for use with PopAndRelease<T>. This is not necessary since pushing an element with an associated resource requires no special handling. Just use Push<T>.
The example below use a custom TMockResource record that emulates a resource that must be released. The record keeps track of the number of records currently instantiated.
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;
procedure PopAndRelease_Eg;
var
R, R0, R1, R2: TMockResource;
RA, Expected: TArray<TMockResource>;
begin
// create array of 3 "resources"
R0 := TMockResource.Create(0);
R1 := TMockResource.Create(1);
R2 := TMockResource.Create(2);
RA := TArray<TMockResource>.Create(R0, R1, R2);
Assert(Length(RA) = 3, '3 element array expected');
Assert(TMockResource.InstanceCount = 3, 'Expected 3 "resources" allocated');
Assert(TArrayUtils.Last<TMockResource>(RA).Field = 2, '2 expected @ TOS');
// pop and release element at end of array
TArrayUtils.PopAndRelease<TMockResource>(
RA,
procedure (const AElem: TMockResource) begin AElem.Release end
);
// check array after popping
Assert(TArrayUtils.Last<TMockResource>(RA).Field = 1, '1 expected @ TOS');
Assert(Length(RA) = 2, '2 element array expected following deletion');
Assert(TMockResource.InstanceCount = 2, 'Expected 2 "resources" allocated');
Expected := TArray<TMockResource>.Create(R0, R1);
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;