On Thu, 7 Nov 2019, Ben Grasset via fpc-pascal wrote:
On Thu, Nov 7, 2019 at 10:23 AM Michael Van Canneyt <mich...@freepascal.org>
wrote:
If I understood Sven's example correct, then the compiler does exactly this
already.
It does in the sense of *code generation* for things that are specifically
compiler intrinsics (which I was aware of), but not in a sense that makes
the issue Ryan was posting about here avoidable. Maybe this will explain
what I'm trying to get at a bit better:
program Example;
{$mode ObjFPC}
// Without actually specializing and using GDiv,
// this program compiles fine.
generic function GDiv<T>(const A, B: T): T; inline;
begin
if GetTypeKind(T) in [tkInteger, tkInt64, tkQWord] then
Result := A div B
else if GetTypeKind(T) = tkFloat then
Result := A / B
else
Result := Default(T);
end;
// However, once we do specialize it...
procedure UseGDiv;
begin
// Example.pas(13,17) Error: Incompatible types: got "Double" expected
"Int64"
WriteLn(specialize GDiv<Int64>(1, 2));
// Example.pas(11,17) Error: Operator is not overloaded: "Double" div
"Double"
WriteLn(specialize GDiv<Double>(1, 2));
end;
Thanks for the explanation. All is clear.
As an aside:
In my opinion (keep in mind I am not a big fan of generics) the above code
would be a prime example where one should not be using generics, but simple
overloads.
If you need to use GetTypeKind in a generic, I think you're on the wrong path.
Use of IsManagedType() in a generic is stretching it, but GetTypeKind() is over the line.
Michael.
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal