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.

Copy<T> class method

Project: Array Utilities Unit

Unit: DelphiDabbler.Lib.ArrayUtils

Record: TArrayUtils

Applies to: ~>0.1

type
  TCloner<T> = reference to function (const AElem: T): T;

class function Copy<T>(const A: array of T): TArray<T>;
  overload; static;

class function Copy<T>(const A: array of T;
  const ACloner: TCloner<T>): TArray<T>;
  overload; static;

Description

Returns a copy of a given array.

The two overloaded methods enable either a shallow copy or a deep copy to be returned.

Parameters:

Returns:

Note

When making deep copies that involve allocating memory, particular care must be taken to ensure that the memory is deallocated when no longer required.

Examples

Example #1

Creating a shallow copy:

procedure Copy_Eg1;
var
  A, B: TArray<Integer>;
  C, D: TArray<TStrings>;
  O1, O2, O3: TStrings;
  Idx: Integer;
begin
  A := TArray<Integer>.Create(1, 2, 3);
  B := TArrayUtils.Copy<Integer>(A);
  Assert(TArrayUtils.Equal<Integer>(A, B));

  O1 := TStringList.Create;
  O2 := TStringList.Create;
  O3 := TStringList.Create;
  O1.Add('a');
  O2.Add('b'); O2.Add('c');
  O3.Add('d');

  C := TArray<TStrings>.Create(O1, O2, O3);
  D := TArrayUtils.Copy<TStrings>(C);

  for Idx := Low(C) to High(C) do
    // these array elements refer to the same object references
    Assert(Pointer(C[Idx]) = Pointer(D[Idx]));

  Assert(D[0].Text = C[0].Text);
  C[0].Add('x');    // also updates D[0];
  Assert(D[0].Text = C[0].Text);

  for Idx := Low(C) to High(C) do
    C[Idx].Free;    // also frees D[Idx]
end;

Example #2

Creating a deep copy:

procedure Copy_Eg2;
var
  C, D: TArray<TStrings>;
  O1, O2, O3: TStrings;
  Idx: Integer;
  Cloner: TArrayUtils.TCloner<TStrings>;
begin
  O1 := TStringList.Create;
  O2 := TStringList.Create;
  O3 := TStringList.Create;
  O1.Add('a');
  O2.Add('b'); O2.Add('c');
  O3.Add('d');

  Cloner := function(const AElem: TStrings): TStrings
    var
      S: string;
    begin
      Result := TStringList.Create;
      for S in AElem do
        Result.Add(S);
    end;

  C := TArray<TStrings>.Create(O1, O2, O3);
  D := TArrayUtils.Copy<TStrings>(C, Cloner);

  for Idx := Low(C) to High(C) do
    // these array elements refer to different object references
    Assert(Pointer(C[Idx]) <> Pointer(D[Idx]));

  Assert(D[0].Text = C[0].Text);
  C[0].Add('x');    // does not update D[0];
  Assert(D[0].Text <> C[0].Text);

  for Idx := Low(C) to High(C) do
    C[Idx].Free;
  for Idx := Low(D) to High(D) do
    D[Idx].Free;    // these are separate objects to those in C
end;

See Also