[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:

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;

  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;

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

  class operator TVec2./(const Left, Right: TVec2): TVec2;
    // 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)
        TVec2.Create(Left.X div Right.X, Left.Y div Right.Y);

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

-------------- 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