Recent

Author Topic: Generics and type <T> determination?  (Read 586 times)

trn76

  • New Member
  • *
  • Posts: 31
Generics and type <T> determination?
« on: November 04, 2019, 09:48:41 am »
In a generic class, how can I determine if the type T is a ordinal/integer or float? Just like SizeOf() that determines the size when compiling, and not runtime.
This is just an example, as you see in the function divXY - if <T> is ordinal use "div", if <T> is a float then use "/".... and so on.


Code: Pascal  [Select]
  1. unit ugenerictest;
  2.  
  3. {$MODE objfpc}{$H+}
  4. {$MODESWITCH AdvancedRecords}
  5. {$IFDEF FPC}
  6.   {$PACKRECORDS C}
  7. {$ENDIF}
  8. {$INLINE ON}
  9.  
  10. interface
  11.  
  12. type
  13.  
  14.   generic TGGenericPoint<T> = packed record
  15.     public
  16.       x, y        : T;
  17.       procedure   flip; inline;
  18.       procedure   invert; inline;
  19.       function    longest: T;
  20.       function    shortest: T;
  21.       function    divXY: T;
  22.   end;
  23.  
  24. implementation
  25.  
  26. procedure TGGenericPoint.flip;
  27. var a: T;
  28. begin
  29.   a := x;
  30.   x := y;
  31.   y := a;
  32. end;
  33.  
  34. procedure TGGenericPoint.invert;
  35. begin
  36.   x := -x;
  37.   y := -y;
  38. end;
  39.  
  40. function TGGenericPoint.longest: T;
  41. begin
  42.   if x >= y
  43.     then Result := x
  44.     else Result := y;
  45. end;
  46.  
  47. function TGGenericPoint.shortest: T;
  48. begin
  49.   if x <= y
  50.     then Result := x
  51.     else Result := y;
  52. end;
  53.  
  54. function TGGenericPoint.divXY: T;
  55. begin
  56.   Result := x / y;  // <--- how can the compiler determine if we are dealing with integer or float?
  57. end;
  58.  
  59.  
  60.  

Mr.Madguy

  • Sr. Member
  • ****
  • Posts: 457
Re: Generics and type <T> determination?
« Reply #1 on: November 04, 2019, 10:22:27 am »
If you have to determine <T> type at runtime, than generics isn't right way to do your job, cuz they're intended to be universal. Use standard OOP features instead.

Not sure, if Lazarus supports this operation. Latest Lazarus versions should allow it. But you can just specialize your generic for certain type.

For example (Delphi syntax, as I'm not familiar to Lazarus one):
Code: Pascal  [Select]
  1. type
  2.   TBaseClass<T> = class
  3.     function DoSomething(const A, B:T):T;virtual;abstract;
  4.   end;
  5.  
  6.   TIntegerClass = class(TBaseClass<Integer>)
  7.     function DoSomething(const A, B:Integer):Integer;override;  
  8.   end;
  9.  
DynamicData 3.0 is released!
Since now development is frozen - only optimization passes will be made at some point.
Lack of multiple inheritance turns it into abomination.

Thaddy

  • Hero Member
  • *****
  • Posts: 9278
Re: Generics and type <T> determination?
« Reply #2 on: November 04, 2019, 11:46:06 am »
Simply check the type kind by using GetTypeKind.
Small example:
Code: Pascal  [Select]
  1. {$mode delphi}{$H+}
  2. function WhatAmI<T>(const value:T):string;
  3. begin
  4.   writestr(Result,gettypekind(Value));
  5. end;
  6.  
  7. var
  8.  i:integer = 0;
  9.  d:double = 0.0;
  10. begin
  11.   writeln(WhatAmI<Integer>(i));
  12.   writeln(WhatAmI<Double>(d));
  13. end.

Since typekind itself is an ordinal, you can make a set of types that behave a certain way, like ordinals and floats.
so:
Code: Pascal  [Select]
  1. uses typinfo;// for ttypekinds set
  2. type
  3.   TBaseClass<T> = class
  4.     function DoSomething(const A, B:T):T;virtual;abstract;
  5.     function WhatAmI:TTypeKind;
  6.   end;
  7.  
  8.     function TBaseClass.WhatAmI:TTypeKind;
  9.     begin
  10.       Result := GetTypeKind(T);
  11.    end;
« Last Edit: November 04, 2019, 11:54:46 am by Thaddy »
also related to equus asinus.

trn76

  • New Member
  • *
  • Posts: 31
Re: Generics and type <T> determination?
« Reply #3 on: November 08, 2019, 02:11:21 pm »
Ok, thanks people.. Would be nice if there was a compile-time way, generics are really useful and powerful.

Thaddy

  • Hero Member
  • *****
  • Posts: 9278
Re: Generics and type <T> determination?
« Reply #4 on: November 08, 2019, 03:29:03 pm »
Ok, thanks people.. Would be nice if there was a compile-time way, generics are really useful and powerful.
The compile time way is the programmer.... I know that is not always a very satisfactory solution...
also related to equus asinus.

PascalDragon

  • Hero Member
  • *****
  • Posts: 705
  • Compiler Developer
Re: Generics and type <T> determination?
« Reply #5 on: November 09, 2019, 10:52:18 am »
Ok, thanks people.. Would be nice if there was a compile-time way, generics are really useful and powerful.
You can take a look at this solution I posted on the mailing list last night that deals with a similar problem. Maybe you can make use of that. Please note however that GetTypeKind requires FPC 3.2 or newer.