[fpc-pascal] Generic type conflicts

Sven Barth pascaldragon at googlemail.com
Tue Nov 5 23:24:19 CET 2019


Ben Grasset via fpc-pascal <fpc-pascal at lists.freepascal.org> schrieb am
Di., 5. Nov. 2019, 19:11:

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

Does this really work? Cause the compiler should nevertheless typecheck the
code in the other branch and thus without casts that shouldn't compile.
Also if it should indeed work, it would also work without the
if-expression, but with an if-statement.

Regards,
Sven

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


More information about the fpc-pascal mailing list