On Sat, Nov 2, 2019 at 11:51 AM Ryan Joseph via fpc-pascal < fpc-pascal@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.
_______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal