Recent

Author Topic: [SOLVED] Getting size of a value in an Generic method  (Read 2546 times)

Okoba

  • Hero Member
  • *****
  • Posts: 528
[SOLVED] Getting size of a value in an Generic method
« on: November 19, 2020, 06:33:57 pm »
Is there a way to get a value size managed or unmanaged? I can write a function to GetTypeKind and check if it is string or integer and use Length or SizeOf for it, but is there any ready to use function?
Code: Pascal  [Select][+][-]
  1. It is useful in the generic methods:
  2.   procedure Test<T>(A: T);
  3.   begin
  4.     //Write the size of A
  5.   end;      
« Last Edit: November 22, 2020, 10:48:18 am by OkobaPatino »

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: Getting size of a value in an Generic method
« Reply #1 on: November 19, 2020, 07:20:16 pm »
You can use sizeof(T); directly, no need to check the type. Of course if T is class then sizeof(T) will be size of Pointer (i.e. 8 bytes on 64-bit platform).
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Okoba

  • Hero Member
  • *****
  • Posts: 528
Re: Getting size of a value in an Generic method
« Reply #2 on: November 20, 2020, 12:17:03 am »
What about string of array?

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Getting size of a value in an Generic method
« Reply #3 on: November 20, 2020, 12:35:39 am »
Hi!

Use length:
Code: Pascal  [Select][+][-]
  1.  
  2. NumBytes := Length('Hello');

should return 5.


Code: Pascal  [Select][+][-]
  1. NumElements := Length(MyStrangeArray);

returns the number of elements in your array.

Winni



Okoba

  • Hero Member
  • *****
  • Posts: 528
Re: Getting size of a value in an Generic method
« Reply #4 on: November 20, 2020, 12:37:31 am »
Please read my question again. I want to know if there is a function to give the size of A param in a generic function including eg integer and string .

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: Getting size of a value in an Generic method
« Reply #5 on: November 20, 2020, 01:17:54 am »
You must think this is some sort of scripting language, its not.

The compiler can only determine what it knows at compile time so using "SIZEOF" will return the size of the object at compile time.

referencing an array will only report the size of a pointer, that is, if the array is dynamic otherwise it will report the size of the static size array that is knows about at compile time.

 Of course the compiler has to compose all of this like a macro so this means you'll have several instances of the same method but with different types. I called that bloatware.

 if you want runtime flex like that then maybe you should be looking into variants.

 Variants is still a low level approach but with Runtime type info, since a variant is I think 16 bytes each with the management fields.

 Other than that, please don't suggest Fpc should behave like a high level language or script kiddy engine.
The only true wisdom is knowing you know nothing

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: Getting size of a value in an Generic method
« Reply #6 on: November 20, 2020, 04:53:48 am »
SizeOf and Length do something completely different things. SizeOf gives you the size of the object you have. A string for example is nothing more than a pointer, therefore it's size is 4 or 8 bytes. Length gives you information that this object contains. For the string this means reading a value from the data the pointer points to.

There is no unified interface for these two operations, because they are completely different. Take this example:
Code: Pascal  [Select][+][-]
  1. TTest = record
  2.   A: Integer;
  3.   B: String;
  4.   C: Float;
  5. end;
The "total" size of that record would be sizeOf(TTest) + Length(test.B). While the size of the object is trivial to get, computing the total size, like with using length, requires knowledge about the type. This is exactly what generics are not supposed to do, the idea behind generics is that you don't need to know details about the type.

May I ask what you want to do, maybe there is some other way

Okoba

  • Hero Member
  • *****
  • Posts: 528
Re: Getting size of a value in an Generic method
« Reply #7 on: November 20, 2020, 07:39:44 am »
I liked to see that if you can implement a function that get any type (except class and interface) and hex it.
If it is a integer, size is 4, givea me back 8 byte of hex. If string with a length of 100, givea me 200 bytes of hex and so on for record or array of these types.
So as you said, I like to see if there is a ready to use "TotalSize" function.
You are right about generic, but most of the code will be hex, getting the size will be the only diffent and this will prevent me to make many functions for each types of use a pointer based method.
« Last Edit: November 20, 2020, 07:43:53 am by OkobaPatino »

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Getting size of a value in an Generic method
« Reply #8 on: November 20, 2020, 12:47:45 pm »
Something like this?
Code: Pascal  [Select][+][-]
  1. generic function Any2Hex<T>(const a: T): string;
  2. var
  3.   k: TTypeKind;
  4.   Len: SizeInt;
  5. begin
  6.   k := GetTypeKind(a);
  7.   case k of
  8.     tkSString:  Len := System.Length(PShortString(@a)^);
  9.     tkLString:  Len := System.Length(PAnsiString(@a)^);
  10.     tkWString:  Len := System.Length(PWideString(@a)^)*SizeOf(WChar);
  11.     tkUString:  Len := System.Length(PUnicodeString(@a)^)*SizeOf(UnicodeChar);
  12.     tkDynArray: Len := DynArraySize(Pointer(a))*SizeInt(GetTypeData(TypeInfo(a))^.elSize);
  13.   else
  14.     Len := SizeOf(a)
  15.   end;
  16.   System.SetLength(Result, Len*2);
  17.   if k in [tkSString, tkLString, tkWString, tkUString, tkDynArray] then
  18.     BinToHex(Pointer(a), PChar(Result), Len)
  19.   else
  20.     BinToHex(@a, PChar(Result), Len);
  21. end;
  22.  

Okoba

  • Hero Member
  • *****
  • Posts: 528
Re: Getting size of a value in an Generic method
« Reply #9 on: November 20, 2020, 12:50:28 pm »
Yes avk! That so exactly what I like to do. I liked to know if there is any helper to give the total size but it seems there is not.
Thank you!

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Getting size of a value in an Generic method
« Reply #10 on: November 20, 2020, 01:08:48 pm »
You are welcome.

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Getting size of a value in an Generic method
« Reply #11 on: November 20, 2020, 02:19:53 pm »
By the way, the original version is incorrect.
Here's an improved(?) version:
Code: Pascal  [Select][+][-]
  1. generic function Any2Hex<T>(const a: T): string;
  2. var
  3.   p: Pointer;
  4.   Len: SizeInt;
  5. begin
  6.   p := @a;
  7.   case GetTypeKind(a) of
  8.     tkSString:  Len := System.Length(PShortString(p)^);
  9.     tkLString:  Len := System.Length(PAnsiString(p)^);
  10.     tkWString:  Len := System.Length(PWideString(p)^)*SizeOf(WChar);
  11.     tkUString:  Len := System.Length(PUnicodeString(p)^)*SizeOf(UnicodeChar);
  12.     tkDynArray: Len := DynArraySize(Pointer(p^))*SizeInt(GetTypeData(TypeInfo(a))^.elSize);
  13.   else
  14.     Len := SizeOf(a);
  15.   end;
  16.   System.SetLength(Result, Len*2);
  17.   case GetTypeKind(a) of
  18.     tkSString: BinToHex(@PShortString(p)^[1], PChar(Result), Len);
  19.     tkLString, tkWString, tkUString, tkDynArray:
  20.       BinToHex(Pointer(p^), PChar(Result), Len);
  21.   else
  22.     BinToHex(p, PChar(Result), Len);
  23.   end;
  24. end;
  25.  
« Last Edit: November 20, 2020, 06:35:56 pm by avk »

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: Getting size of a value in an Generic method
« Reply #12 on: November 21, 2020, 03:07:23 am »
that is insane if you ask me...

What's wrong with using OVERLOADS ?

Those generics will recreate a complete block of that code per type;

The only true wisdom is knowing you know nothing

avk

  • Hero Member
  • *****
  • Posts: 752
Re: Getting size of a value in an Generic method
« Reply #13 on: November 21, 2020, 09:34:53 am »
Well, code doesn't look very nice, but on the other hand:
A customer comes to the store and says: I need a saxophone.
To which he is answered: the saxophone is not needed, better take a dozen whistles.

Okoba

  • Hero Member
  • *****
  • Posts: 528
Re: Getting size of a value in an Generic method
« Reply #14 on: November 21, 2020, 09:38:10 am »
:D
Yes, this code seems complicated and needs more work for complicated types. But it prevents writing many many overloads. For example, look at TStream and its many overload helpers; it is not good looking.

 

TinyPortal © 2005-2018