Am 07.06.2019 um 18:37 schrieb Ben Grasset:
For example, consider the following code, that implements a generic "memcpy"-style procedure using a static advanced-record method:

program Example;

{$mode Delphi}

type
  TMem<T> = record
  public type
    PT = ^T;
  public
    class procedure Copy(Dest: PT; Src: PT; Len: PtrUInt); static; inline;
  end;

  class procedure TMem<T>.Copy(Dest: PT; Src: PT; Len: PtrUInt);
  begin
    while Len > 0 do begin
      Dest^ := Src^;
      Inc(Dest);
      Inc(Src);
      Dec(Len);
    end;
  end;

type
  String4 = String[4];

var
  X: TArray<String4> = ['AAAA', 'BBBB', 'CCCC', 'DDDD', 'EEEE'];
  Y: TArray<String4> = ['', '', '', '', ''];
  S: String4;

begin
  TMem<String4>.Copy(@Y[0], @X[0], 5);
  for S in Y do WriteLn(S);
end.

The only reason the record is necessary at all is to be able to declare "PT" as a pointer type alias to the record's overall "T".

Personally, I'd much rather simply write the following, if it was possible:

procedure MemCopy<T>(Dest: ^T; Src: ^T; Len: PtrUInt);
begin
  while Len > 0 do begin
    Dest^ := Src^;
    Inc(Dest);
    Inc(Src);
    Dec(Len);
  end;
end;

You can do it like this (yes, works in mode Delphi as well):

=== code begin ===

{$mode objfpc}
{$modeswitch advancedrecords}

type
  generic TPointerType<T> = record
  public type
    PT = ^T;
  end;

  generic procedure MemCopy<T>(Dest, Src: specialize TPointerType<T>.PT; Len: PtrUInt);
  begin
    while Len > 0 do begin
      Dest^ := Src^;
      Inc(Dest);
      Inc(Src);
      Dec(Len);
    end;
  end;

type
  String4 = String[4];

var
  X: specialize TArray<String4> = ('AAAA', 'BBBB', 'CCCC', 'DDDD', 'EEEE');
  Y: specialize TArray<String4> = ('', '', '', '', '');
  S: String4;

begin
  specialize MemCopy<String4>(@Y[0], @X[0], 5);
  for S in Y do WriteLn(S);
end.

=== code end ===

Regards,
Sven
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to