Recent

Author Topic: Intrinsic for type of integer  (Read 1687 times)

Okoba

  • Hero Member
  • *****
  • Posts: 555
Intrinsic for type of integer
« on: October 01, 2023, 05:28:33 pm »
Hello,

I know I can use GetTypeKind Intrinsic to get the type of a variant, but it returns tkInteger for many integer types. I can use SizeOf Intrinsic to detect the size, so I can find out the difference of Integer and Byte for example.
But how can I detect the difference between Byte and Shortint? Their both size is 1.
I want Intrinsic as I like my function to solve in compile time.
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3.   {$mode delphi}
  4.  
  5.   procedure Test<T>(V: T);
  6.   begin
  7.     if GetTypeKind(V) = tkInteger then
  8.       case SizeOf(V) of
  9.         1: WriteLn('Byte or Shortint?');
  10.         4: WriteLn('Integer');
  11.       end;
  12.   end;
  13.  
  14. begin
  15.   Test<Integer>(1);
  16.   Test<Byte>(1);
  17.   Test<Shortint>(-1);
  18.   ReadLn;
  19. end.        

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: Intrinsic for type of integer
« Reply #1 on: October 01, 2023, 06:49:44 pm »
I don't know what you are trying to do but you always have the "TValueType" enum to play with.
The only true wisdom is knowing you know nothing

Okoba

  • Hero Member
  • *****
  • Posts: 555
Re: Intrinsic for type of integer
« Reply #2 on: October 01, 2023, 06:55:07 pm »
What is "TValueType"?

cdbc

  • Hero Member
  • *****
  • Posts: 1678
    • http://www.cdbc.dk
Re: Intrinsic for type of integer
« Reply #3 on: October 01, 2023, 07:23:03 pm »
Hi
I think @jamie: means "system.TTypeKind"...
...and for that you can use "system.TypeInfo()", it returns a record with Name & Type = PTypeInfo; { uses typinfo; }
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Okoba

  • Hero Member
  • *****
  • Posts: 555
Re: Intrinsic for type of integer
« Reply #4 on: October 01, 2023, 07:27:35 pm »
TTypeKind is what I am already using. But it does not let you know if that is for example a Byte or a Shortint!

Kays

  • Hero Member
  • *****
  • Posts: 613
  • Whasup!?
    • KaiBurghardt.de
Re: Intrinsic for type of integer
« Reply #5 on: October 01, 2023, 07:30:46 pm »
[…] But how can I detect the difference between Byte and Shortint? Their both size is 1. […]
You cannot determine it at compile-time. You do it dynamically. The signed ranges are preferred. So a one byte integer quantity that has a value ≤ +127 is an int8, otherwise a Byte.
Code: Pascal  [Select][+][-]
  1.         4: WriteLn('Integer');
It’s longInt or longWord.
Yours Sincerely
Kai Burghardt

cdbc

  • Hero Member
  • *****
  • Posts: 1678
    • http://www.cdbc.dk
Re: Intrinsic for type of integer
« Reply #6 on: October 01, 2023, 07:30:54 pm »
Hi
Sorry mate, sloppy of me  %)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Okoba

  • Hero Member
  • *****
  • Posts: 555
Re: Intrinsic for type of integer
« Reply #7 on: October 01, 2023, 07:33:45 pm »
No problem @cdbc, and thank you.
Thank you @Kays.

That is a shame for a type safe language, that it does not even exposes the types properly.

bytebites

  • Hero Member
  • *****
  • Posts: 685
Re: Intrinsic for type of integer
« Reply #8 on: October 01, 2023, 08:01:27 pm »
High(V) tells if it is signed or not

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: Intrinsic for type of integer
« Reply #9 on: October 01, 2023, 09:37:09 pm »
I suppose you have looked at TVarData ? That uses Variants and requires the variants unit to be used.

TVarData does have all of those as types.

But of course, you won't like using them because of the size of record.  For me, Its a great when using them via reference.
The only true wisdom is knowing you know nothing

Warfley

  • Hero Member
  • *****
  • Posts: 1767
Re: Intrinsic for type of integer
« Reply #10 on: October 02, 2023, 11:01:23 am »
The problem is, you are attempting to do meta programming on those types by mixing runtime code (if-thrn-else) on compiletime information. This is not that well supported in FPC, as usually compiletime and runtime information are quite seperated

What you can do is to resolve type information fully at compiletime using compile time polymorphism through function overloading:
Code: Pascal  [Select][+][-]
  1. TIntType = (u8, s8, ...);
  2.  
  3. function IntType(AInt: Byte): TIntType; overload; inline;
  4. begin
  5.   Result := TIntType.u8;
  6. end;
  7.  
  8. function IntType(AInt: SmallInt): TIntType; overload; inline;
  9. begin
  10.   Result := TIntType.s8;
  11. end;
  12.  
  13. // use
  14. var
  15.   B: Byte;
  16. begin
  17.   WriteLn(IntType(b)); // shows u8

Here the compiler will map your types to results through resolving the overloaded function. Through inlining no extra code should be generated

Okoba

  • Hero Member
  • *****
  • Posts: 555
Re: Intrinsic for type of integer
« Reply #11 on: October 02, 2023, 12:44:09 pm »
@Warfley your way seems great! Thank you.
Mixing if then with compile time code is not well supported, yes. But for type oriented task like generic functions, it is very useful.

Wallaby

  • Full Member
  • ***
  • Posts: 104
Re: Intrinsic for type of integer
« Reply #12 on: October 02, 2023, 01:23:33 pm »
Use TypeInfo and check against the types you want. Sample:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3.   {$mode delphi}
  4.  
  5.   procedure Test<T>(V: T);
  6.   begin
  7.     if TypeInfo(V) = TypeInfo(Integer) then
  8.       WriteLn('Integer')
  9.     else
  10.     if TypeInfo(V) = TypeInfo(Byte) then
  11.       WriteLn('Byte')
  12.     else
  13.     if TypeInfo(V) = TypeInfo(Shortint) then
  14.       WriteLn('Shortint')
  15.     else
  16.       WriteLn('Something else');
  17.   end;
  18.  
  19. begin
  20.   Test<Integer>(1);
  21.   Test<Byte>(1);
  22.   Test<Shortint>(-1);
  23.   Test<LongWord>(-1);
  24.   ReadLn;
  25. end.

This will print

Code: Text  [Select][+][-]
  1. Integer
  2. Byte
  3. Shortint
  4. Something else

Okoba

  • Hero Member
  • *****
  • Posts: 555
Re: Intrinsic for type of integer
« Reply #13 on: October 02, 2023, 02:33:37 pm »
@Wallaby that is an even better way! Thank you.
Although Test needs inline otherwise it will not resolve on compile time.

 

TinyPortal © 2005-2018