[fpc-pascal] Constants in generics

Ben Grasset operator97 at gmail.com
Sun Jan 6 21:31:05 CET 2019


Just wanted to say, I've been playing around with Ryan's github branch that
contains this functionality and I'm loving it! It really opens up a ton of
interesting possibilities in general, and also a lot of potential for
optimization via constant folding for generic containers that wasn't really
possible previously. Here's a more "advanced" example I threw together of
the kinds of things you can actually do with this (I'm aware the final
syntax for the declarations is going to be slightly different, not that it
matters really):

program Example;

{$Mode ObjFPC}{$H+}{$J-}
{$ModeSwitch AdvancedRecords}
{$PointerMath On}

type
  generic TStaticList<T, const L: PtrUInt, const H: PtrUInt> = record
  public type
    TStaticListEnumerator = record
    public type PT = ^T;
    strict private
      FFirst, FLast, FCurrent: PT;
    public
      class function Create(var List: TStaticList): TStaticListEnumerator;
inline; static;
      function MoveNext: Boolean; inline;
      property Current: PT read FCurrent;
    end;
  strict private
    Items: array[L..H] of T;
  public
    function Low: PtrUInt; inline;
    function High: PtrUInt; inline;
    procedure Initialize; inline;
    function GetEnumerator: TStaticListEnumerator; inline;
  end;

  class function TStaticList.TStaticListEnumerator.Create(var List:
TStaticList): TStaticListEnumerator;
  begin
    with Result do begin
      FFirst := @List.Items[L];
      FLast := @List.Items[H];
      FCurrent := FFirst - 1;
    end;
  end;

  function TStaticList.TStaticListEnumerator.MoveNext: Boolean;
  begin
    Inc(FCurrent);
    Result := (FFirst <> FLast) and (FCurrent <= FLast);
  end;

  function TStaticList.Low: PtrUInt;
  begin
    Result := L;
  end;

  function TStaticList.High: PtrUInt;
  begin
    Result := H;
  end;

  procedure TStaticList.Initialize;
  var I: PtrUInt;
  begin
    for I := Low() to High() do Items[I] := T(I);
  end;

  function TStaticList.GetEnumerator: TStaticListEnumerator;
  begin
    Result := TStaticListEnumerator.Create(Self);
  end;

var
  AsciiList: specialize TStaticList<Char, 33, 126>;
  P: PChar;

begin
  AsciiList.Initialize();
  for P in AsciiList do Write(P^);
end.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20190106/4bc7d052/attachment.html>


More information about the fpc-pascal mailing list