[fpc-devel] Thoughts on being able to declare "pointer-to-type" parameters directly in method signatures?

Sven Barth pascaldragon at googlemail.com
Fri Jun 7 21:50:06 CEST 2019


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



More information about the fpc-devel mailing list