Am 26.04.2020 um 09:38 schrieb Michael Van Canneyt:


On Sun, 26 Apr 2020, Ryan Joseph via fpc-devel wrote:



On Apr 26, 2020, at 5:13 AM, Sven Barth via fpc-devel <fpc-devel@lists.freepascal.org> wrote:

The Free Pascal team is happy to announce the addition of a new language feature: constant parameters for generics.

Excellent! Thanks for getting this merged. It was a long battle but it's finally over. ;)

As the original author, can you say something about the intended use of this feature ?

Sven gave some examples, and they show how it works, but from his examples I don't see the point
of this feature.

Jeppe had provided a potential usecase on the core mailing list in October '18. His example is not useable as-is, but to give you an idea:

=== code begin ===

program tgpio;

{$mode objfpc}
{$modeswitch advancedrecords}

type
 generic TSomeMicroGPIO<const Base: PtrUInt> = record
 private
   procedure SetPin(aIndex: SizeInt; aEnable: Boolean); inline;
   function GetPin(aIndex: SizeInt): Boolean; inline;
 public
   property Pin[Index: SizeInt]: Boolean read GetPin write SetPin;
 end;

procedure TSomeMicroGPIO.SetPin(aIndex: SizeInt; aEnable: Boolean);
begin
  if aEnable then
    PLongWord(Base)[2] := PLongWord(Base)[2] or (1 shl aIndex)
  else
    PLongWord(Base)[2] := PLongWord(Base)[2] and not (1 shl aIndex);
end;

function TSomeMicroGPIO.GetPin(aIndex: SizeInt): Boolean;
begin
  Result := (PLongWord(Base)[2] and (1 shl aIndex)) <> 0
end;

var
  GPIOA: specialize TSomeMicroGPIO<$8000F000>;
  GPIOB: specialize TSomeMicroGPIO<$8000F100>;
  GPIOC: specialize TSomeMicroGPIO<$8000F200>;

begin
  GPIOA.Pin[2] := True;
end.

=== code end ===

As the compiler can inline all this, the writing of maintainable, hardware agnostic frameworks for embedded controllers becomes easier.

In general I agree with you that the use of constants as generic parameters is less wide. But there cases where one might want them.

A further example could be to determine the size of a hash table: Determining that at compile time instead of runtime might allow for better code. At the same time the user of that code would still be able to influence it.

In the bug report there was a further example by Akira1364. At its core it's about static arrays again, but it shows what can be done with this:

=== code begin ===

program ConstMatrixExampleObjFPC;

{$mode ObjFPC}
{$modeswitch AdvancedRecords}

type
  String3 = String[3];

  generic TRawMatrix<T; const N: SizeUInt> = array[0..N-1] of array[0..N-1] of T;

  generic TMatrix<T; const N: SizeUInt> = record
  private type
    ArrayType = specialize TRawMatrix<T, N>;
  private
    Data: ArrayType;
  public
    class operator :=(constref Arr: ArrayType): TMatrix; inline;
    procedure Display;
  end;

  class operator TMatrix.:=(constref Arr: ArrayType): TMatrix;
  begin
    Result.Data := Arr;
  end;

  procedure TMatrix.Display;
  var I, J: SizeInt;
  begin
    WriteLn('[');
    for I := 0 to N - 1 do begin
      Write(' [');
      for J := 0 to N - 2 do
        Write(Data[I, J], ', ');
      Write(Data[I, N - 1]);
      Writeln('] ');
    end;
    Write(']');
  end;

const RawMat: specialize TRawMatrix<String3, 4> = (
  ('AAA', 'BBB', 'CCC', 'DDD'),
  ('EEE', 'FFF', 'GGG', 'HHH'),
  ('III', 'JJJ', 'KKK', 'LLL'),
  ('MMM', 'NNN', 'OOO', 'PPP')
);

var Mat: specialize TMatrix<String3, 4>;

begin
  Mat := RawMat;
  Mat.Display();
end.

=== code end ===

I'm sure the future will show more potential examples. Or one could look at C++ examples that allow constants as well.

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

Reply via email to