<div dir="auto"><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Ben Grasset via fpc-pascal <<a href="mailto:fpc-pascal@lists.freepascal.org">fpc-pascal@lists.freepascal.org</a>> schrieb am Di., 5. Nov. 2019, 19:11:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div dir="ltr">On Sat, Nov 2, 2019 at 11:51 AM Ryan Joseph via fpc-pascal <<a href="mailto:fpc-pascal@lists.freepascal.org" target="_blank" rel="noreferrer">fpc-pascal@lists.freepascal.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">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.<br></blockquote><div><br></div><div>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:</div><div><a href="https://www.mail-archive.com/fpc-pascal@lists.freepascal.org/msg41336.html" target="_blank" rel="noreferrer">https://www.mail-archive.com/fpc-pascal@lists.freepascal.org/msg41336.html</a></div><div><br></div><div>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.</div><div><br></div><div>Combining it with handy compiler intrinsics like GetTypeKind makes stuff like the following modified version of your code possible: <br></div><div><br></div><div>{$mode objfpc}<br>{$modeswitch advancedrecords}<br><br>program generic_vector_2;<br><br>type<br>  generic TVec2<TScalar> = record<br>    X, Y: TScalar;<br>    class function Create(const AX, AY: TScalar): TVec2; static; inline;<br>    class operator / (const Left, Right: TVec2): TVec2; inline;<br>  end;<br><br>  class function TVec2.Create(const AX, AY: TScalar): TVec2;<br>  begin<br>    with Result do begin<br>      X := AX;<br>      Y := AY;<br>    end;<br>  end;<br><br>  class operator TVec2./(const Left, Right: TVec2): TVec2;<br>  begin<br>    // GetTypeKind is evaluated at compile time, so the following works perfectly with "ternary if".<br>    Result :=<br>      if GetTypeKind(TScalar) = tkFloat then<br>        TVec2.Create(Left.X / Right.X, Left.Y / Right.Y)<br>      else<br>        TVec2.Create(Left.X div Right.X, Left.Y div Right.Y);<br>  end;<br><br>type<br>  TVec2f = specialize TVec2<Single>;<br>  TVec2i = specialize TVec2<Integer>;<br><br>begin<br>end.</div></div></div></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Does this really work? Cause the compiler should nevertheless typecheck the code in the other branch and thus without casts that shouldn't compile. </div><div dir="auto">Also if it should indeed work, it would also work without the if-expression, but with an if-statement. </div><div dir="auto"><br></div><div dir="auto">Regards, </div><div dir="auto">Sven </div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
</blockquote></div></div></div>