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.

ShiftAndRelease<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 ShiftAndRelease<T>(var A: TArray<T>;
  const AReleaser: TCallback<T>);
  static;

Description

Deletes the first 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:

Preconditions:

Note

  1. If it is not necessary release a resource associated with an element that is shifted off an array then Shift<T> should be used instead of ShiftAndRelease<T>.

  2. There is no corresponding version of UnShift<T> for use with ShiftAndRelease<T>. This is not necessary since un-shifting an element with an associated resource requires no special handling. Just use UnShift<T>.

Example

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 ShiftAndRelease_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.First<TMockResource>(RA).Field = 0, '0 1st elem expected');

  // pop and release element at end of array
  TArrayUtils.ShiftAndRelease<TMockResource>(
    RA,
    procedure (const AElem: TMockResource) begin AElem.Release end
  );

  // check array after popping
  Assert(TArrayUtils.First<TMockResource>(RA).Field = 1, '1 1st elem expected');
  Assert(Length(RA) = 2, '2 element array expected following deletion');
  Assert(TMockResource.InstanceCount = 2, 'Expected 2 "resources" allocated');
  Expected := TArray<TMockResource>.Create(R1, R2);
  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