<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body smarttemplateinserted="true">
    <div id="smartTemplate4-template">Hi,<br>
      <br>
      <p>perhaps it could be used to merge specializations (if fpc
        cannot do that on its own):<br>
      </p>
    </div>
    <div>Like when you have a hashmap THashMap<Key,Value>, and
      need three specializations:</div>
    <div><br>
    </div>
    <div>THashMap<string, pointer></div>
    <div><br>
    </div>
    <div>THashMap<string, TObject></div>
    <div><br>
    </div>
    <div>THashMap<string, sizeint></div>
    <div><br>
    </div>
    <div>It is basically three times the same hashmap, but if fpc does
      not detect that, it might generate three times the same assembly
      code, which waste a lot of space.</div>
    <div><br>
    </div>
    <div><br>
    </div>
    <div>But with constants it can be merged to TBaseHashMap<Key,
      ValueSize: integer> and then you only have one map in the
      assembly code, and three wrappers to remove the casting:<br>
    </div>
    <div><br>
    </div>
    <div>
      <div>THashMap<string, pointer> = TBaseHashMap<string,
        sizeof(pointer) > = TBaseHashMap<string, 8 >  </div>
      <div><br>
      </div>
      <div>THashMap<string, TObject> = TBaseHashMap<string,
        sizeof(TObject) > = TBaseHashMap<string, 8 > <br>
      </div>
      <div><br>
      </div>
      <div>THashMap<string, sizeint> = TBaseHashMap<string,
        sizeof(sizeint) > = TBaseHashMap<string, 8 > <br>
      </div>
      <div><br>
      </div>
    </div>
    <div><br>
    </div>
    <div><br>
    </div>
    <div>Cheers,<br>
      Benito </div>
    <div class="moz-cite-prefix">On 26.04.20 11:48, Sven Barth via
      fpc-devel wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:a63bfc34-bdca-8715-eae3-ed63fab7b12d@googlemail.com">Am
      26.04.2020 um 09:38 schrieb Michael Van Canneyt:
      <br>
      <blockquote type="cite">
        <br>
        <br>
        On Sun, 26 Apr 2020, Ryan Joseph via fpc-devel wrote:
        <br>
        <br>
        <blockquote type="cite">
          <br>
          <br>
          <blockquote type="cite">On Apr 26, 2020, at 5:13 AM, Sven
            Barth via fpc-devel <a class="moz-txt-link-rfc2396E" href="mailto:fpc-devel@lists.freepascal.org"><fpc-devel@lists.freepascal.org></a>
            wrote:
            <br>
            <br>
            The Free Pascal team is happy to announce the addition of a
            new language feature: constant parameters for generics.
            <br>
          </blockquote>
          <br>
          Excellent! Thanks for getting this merged. It was a long
          battle but it's finally over. ;)
          <br>
        </blockquote>
        <br>
        As the original author, can you say something about the intended
        use of this feature ?
        <br>
        <br>
        Sven gave some examples, and they show how it works, but from
        his examples I don't see the point
        <br>
        of this feature.
        <br>
      </blockquote>
      <br>
      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:
      <br>
      <br>
      === code begin ===
      <br>
      <br>
      program tgpio;
      <br>
      <br>
      {$mode objfpc}
      <br>
      {$modeswitch advancedrecords}
      <br>
      <br>
      type
      <br>
       generic TSomeMicroGPIO<const Base: PtrUInt> = record
      <br>
       private
      <br>
         procedure SetPin(aIndex: SizeInt; aEnable: Boolean); inline;
      <br>
         function GetPin(aIndex: SizeInt): Boolean; inline;
      <br>
       public
      <br>
         property Pin[Index: SizeInt]: Boolean read GetPin write SetPin;
      <br>
       end;
      <br>
      <br>
      procedure TSomeMicroGPIO.SetPin(aIndex: SizeInt; aEnable:
      Boolean);
      <br>
      begin
      <br>
        if aEnable then
      <br>
          PLongWord(Base)[2] := PLongWord(Base)[2] or (1 shl aIndex)
      <br>
        else
      <br>
          PLongWord(Base)[2] := PLongWord(Base)[2] and not (1 shl
      aIndex);
      <br>
      end;
      <br>
      <br>
      function TSomeMicroGPIO.GetPin(aIndex: SizeInt): Boolean;
      <br>
      begin
      <br>
        Result := (PLongWord(Base)[2] and (1 shl aIndex)) <> 0
      <br>
      end;
      <br>
      <br>
      var
      <br>
        GPIOA: specialize TSomeMicroGPIO<$8000F000>;
      <br>
        GPIOB: specialize TSomeMicroGPIO<$8000F100>;
      <br>
        GPIOC: specialize TSomeMicroGPIO<$8000F200>;
      <br>
      <br>
      begin
      <br>
        GPIOA.Pin[2] := True;
      <br>
      end.
      <br>
      <br>
      === code end ===
      <br>
      <br>
      As the compiler can inline all this, the writing of maintainable,
      hardware agnostic frameworks for embedded controllers becomes
      easier.
      <br>
      <br>
      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.
      <br>
      <br>
      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.
      <br>
      <br>
      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:
      <br>
      <br>
      === code begin ===
      <br>
      <br>
      program ConstMatrixExampleObjFPC;
      <br>
      <br>
      {$mode ObjFPC}
      <br>
      {$modeswitch AdvancedRecords}
      <br>
      <br>
      type
      <br>
        String3 = String[3];
      <br>
      <br>
        generic TRawMatrix<T; const N: SizeUInt> = array[0..N-1]
      of array[0..N-1] of T;
      <br>
      <br>
        generic TMatrix<T; const N: SizeUInt> = record
      <br>
        private type
      <br>
          ArrayType = specialize TRawMatrix<T, N>;
      <br>
        private
      <br>
          Data: ArrayType;
      <br>
        public
      <br>
          class operator :=(constref Arr: ArrayType): TMatrix; inline;
      <br>
          procedure Display;
      <br>
        end;
      <br>
      <br>
        class operator TMatrix.:=(constref Arr: ArrayType): TMatrix;
      <br>
        begin
      <br>
          Result.Data := Arr;
      <br>
        end;
      <br>
      <br>
        procedure TMatrix.Display;
      <br>
        var I, J: SizeInt;
      <br>
        begin
      <br>
          WriteLn('[');
      <br>
          for I := 0 to N - 1 do begin
      <br>
            Write(' [');
      <br>
            for J := 0 to N - 2 do
      <br>
              Write(Data[I, J], ', ');
      <br>
            Write(Data[I, N - 1]);
      <br>
            Writeln('] ');
      <br>
          end;
      <br>
          Write(']');
      <br>
        end;
      <br>
      <br>
      const RawMat: specialize TRawMatrix<String3, 4> = (
      <br>
        ('AAA', 'BBB', 'CCC', 'DDD'),
      <br>
        ('EEE', 'FFF', 'GGG', 'HHH'),
      <br>
        ('III', 'JJJ', 'KKK', 'LLL'),
      <br>
        ('MMM', 'NNN', 'OOO', 'PPP')
      <br>
      );
      <br>
      <br>
      var Mat: specialize TMatrix<String3, 4>;
      <br>
      <br>
      begin
      <br>
        Mat := RawMat;
      <br>
        Mat.Display();
      <br>
      end.
      <br>
      <br>
      === code end ===
      <br>
      <br>
      I'm sure the future will show more potential examples. Or one
      could look at C++ examples that allow constants as well.
      <br>
      <br>
      Regards,
      <br>
      Sven
      <br>
      _______________________________________________
      <br>
      fpc-devel maillist  -  <a class="moz-txt-link-abbreviated" href="mailto:fpc-devel@lists.freepascal.org">fpc-devel@lists.freepascal.org</a>
      <br>
      <a class="moz-txt-link-freetext" href="https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel">https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel</a>
      <br>
    </blockquote>
  </body>
</html>