Welcome to the new DelphiDabbler Code Library Documentation.

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.

DeleteAndReleaseRange<T> class method

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 DeleteAndReleaseRange<T>(var A: TArray<T>;
  AStartIndex, AEndIndex: Integer; const AReleaser: TCallback<T>);
  overload; static;

class procedure DeleteAndReleaseRange<T>(var A: TArray<T>;
  AStartIndex: Integer; const AReleaser: TCallback<T>);
  overload; static;

Description

Deletes a range of one or more elements from an array and releases any resources associated with the deleted elements.

The length of the array is reduced by the number of elements deleted.

Parameters:

Notes

If you want to delete and release associated resources of all the elements of an array with indices ≥ AStartIndex then there is no need to provide AEndIndex.

To delete and release the associated resource of a single element set both AStartIndex and AEndIndex to the same index. Alternatively use DeleteAndRelease<T>.

Example

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;

Example #1

This first example uses the overload of DeleteAndReleaseRange<T> that takes both the start and end indices of a range as parameters.

procedure DeleteAndReleaseRange_Eg1;
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 in range 1..3
  TArrayUtils.DeleteAndReleaseRange<TMockResource>(
    RA,
    1,
    3,
    procedure (const AElem: TMockResource) begin AElem.Release end
  );
  // check array size reduced and one resource released
  Assert(Length(RA) = 2, '2 element array expected following deletion');
  Assert(TMockResource.InstanceCount = 2, 'Expected 2 "resources" allocated');
  Expected := TArray<TMockResource>.Create(R0, 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;

Example #2

The second example uses the overload of DeleteAndReleaseRange<T> that takes only the start index of a range as a parameter.

procedure DeleteAndReleaseRange_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 2..end of array
  TArrayUtils.DeleteAndReleaseRange<TMockResource>(
    RA,
    2,
    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(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;

See Also