[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