[fpc-pascal] Generic type conflicts

Ben Grasset operator97 at gmail.com
Tue Nov 5 18:15:50 CET 2019


On Sat, Nov 2, 2019 at 11:51 AM Ryan Joseph via fpc-pascal <
fpc-pascal at lists.freepascal.org> wrote:

> Are there any solutions for this currently? I feel like generics need to
> support some compiler directives so different blocks of code can specialize
> different depending on the type.
>

There's one, that works *exactly* like you want (although it's not
currently present in trunk FPC) which is to apply the (still-working) patch
Sven posted in this mailing list thread a few years ago:
https://www.mail-archive.com/fpc-pascal@lists.freepascal.org/msg41336.html

It introduces a const-evaluated "ternary if" of the form "Variable := if
Expression else Expression;" where only the true branch is taken into
consideration by the compiler at all.

Combining it with handy compiler intrinsics like GetTypeKind makes stuff
like the following modified version of your code possible:

{$mode objfpc}
{$modeswitch advancedrecords}

program generic_vector_2;

type
  generic TVec2<TScalar> = record
    X, Y: TScalar;
    class function Create(const AX, AY: TScalar): TVec2; static; inline;
    class operator / (const Left, Right: TVec2): TVec2; inline;
  end;

  class function TVec2.Create(const AX, AY: TScalar): TVec2;
  begin
    with Result do begin
      X := AX;
      Y := AY;
    end;
  end;

  class operator TVec2./(const Left, Right: TVec2): TVec2;
  begin
    // GetTypeKind is evaluated at compile time, so the following works
perfectly with "ternary if".
    Result :=
      if GetTypeKind(TScalar) = tkFloat then
        TVec2.Create(Left.X / Right.X, Left.Y / Right.Y)
      else
        TVec2.Create(Left.X div Right.X, Left.Y div Right.Y);
  end;

type
  TVec2f = specialize TVec2<Single>;
  TVec2i = specialize TVec2<Integer>;

begin
end.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20191105/0ae6bead/attachment.html>


More information about the fpc-pascal mailing list