typeof

New to FreeBASIC? Post your questions here.
fxm
Moderator
Posts: 12106
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: typeof

Post by fxm »

If in addition the list of possible dynamic types is unknown at compile time, the problem is more difficult because the type name must be directly extract from the mangled typename contained in the RTTI info block of the user object itself (the IS keyword can no longer be used):

Code: Select all

Type simpleUDT
  Dim As Longint l
End Type

Type UDT Extends Object
End Type

Type derivedUDT Extends UDT
End Type

Function staticTypeName overload (Byref i As Integer) As String
  Return "Integer"
End Function

Function staticTypeName overload (Byref d As Double) As String
  Return "Double"
End Function

Function staticTypeName overload (Byref s As String) As String
  Return "String"
End Function

Function staticTypeName overload (Byref su0 As simpleUDT) As String
  Return "simpleUDT"
End Function

Function staticTypeName overload (Byref o As Object) As String
  Return "Object"
End Function

Function staticTypeName overload (Byref u As UDT) As String
  Return "UDT"
End Function

Function staticTypeName overload (Byref du As derivedUDT) As String
  Return "derivedUDT"
End Function

Function dynamicTypeName overload (Byref o As Object) As String
  If o Is derivedUDT Then Return "derivedUDT"
  If o Is UDT Then Return "UDT"
  Return "Object"
End Function

Function mangledTypeName (Byref o As Object, Byval baseIndex As Integer = 0) As String
  ' Function to get the mangled type name or the mangled type name of any of its base-types
  '  (baseIndex = 0 to get the type name of the instance)
  '  (baseIndex = -1 to get the base-type name of the instance, or "" if not existing)
  '  (baseIndex = -2 to get the base-base-type name of the instance, or "" if not existing)
  '  (.....)
  Dim As String S
  Dim As ZString Ptr pz = Cptr(Any Ptr Ptr Ptr, @o)[0][-1]   '' Ptr to RTTIinfo
  For I As Integer = baseIndex To -1
    pz = Cptr(Any Ptr Ptr, pz)[2]                            '' Ptr to Base RTTIinfo
    If pz = 0 Then Return s
  Next I
  pz = Cptr(Any Ptr Ptr, pz)[1]                              '' Ptr to mangled Typename
  Do
    Do While (*pz)[0] > Asc("9") Orelse (*pz)[0] < Asc("0")
      If (*pz)[0] = 0 Then Return S
      pz += 1
    Loop
    Dim As Integer N = Val(*pz)
    Do
      pz += 1
    Loop Until (*pz)[0] > Asc("9") Orelse (*pz)[0] < Asc("0")
    If s <> "" Then S &= "."
    S &= Left(*pz, N)
    pz += N
  Loop
End Function

Function mangledTypeNameHierarchy (Byref o As Object) As String
' Function to get the mangled type names inheritance hierarchy
  Dim As String s = mangledTypeName(o)
  Dim As Integer i = -1
  Do
    Dim As String s0 = mangledTypeName(O, i)
    If s0 = "" Then Exit Do
    s &= "->" & s0
    i -= 1
  Loop
  Return s
End Function

'-------------------------------------------------------------------------------------------------------------------------

Dim As Integer i0                '' Integer type variable (only static type)
Dim As Double d0                 '' Double type variable (only static type)
Dim As String s0                 '' String type variable (only static type)
Dim As simpleUDT su0             '' simpleUDT type variable (only static type)
Dim As Object o0                 '' Object type variable (only static type)
Dim As UDT u0                    '' UDT type variable (only static type)
Dim As derivedUDT du0            '' derivedUDT type variable (only static type)
Dim Byref As Object roo0 = o0    '' Object type reference, referring to an Object instance (static type + dynamic type)
Dim Byref As Object rou0 = u0    '' Object type reference, referring to a UDT instance (static type + dynamic type)
Dim Byref As Object rodu0 = du0  '' Object type reference, referring to a derivedUDT instance (static type + dynamic type)
Dim Byref As UDT ruu0 = u0       '' UDT type reference, referring to a UDT instance (static type + dynamic type)
Dim Byref As UDT rudu0 = du0     '' UDT type reference, referring to a derivedUDT instance (static type + dynamic type)

Print "  variable", " static type", " by IS type", "mangled type", " mangled type hierarchy"
Print "-------------|-------------|-------------|-------------|-----------------------"
Print "io", staticTypeName(i0)
Print "d0", staticTypeName(d0)
Print "s0", staticTypeName(s0)
Print "su0", staticTypeName(su0)
Print "o0", staticTypeName(o0), dynamicTypeName(o0), mangledTypeName(o0), mangledTypeNameHierarchy(o0)
Print "u0", staticTypeName(u0), dynamicTypeName(u0), mangledTypeName(u0), mangledTypeNameHierarchy(u0)
Print "roo0", staticTypeName(roo0), dynamicTypeName(roo0), mangledTypeName(roo0), mangledTypeNameHierarchy(roo0)
Print "rou0", staticTypeName(rou0), dynamicTypeName(rou0), mangledTypeName(rou0), mangledTypeNameHierarchy(rou0)
Print "rodu0", staticTypeName(rodu0), dynamicTypeName(rodu0), mangledTypeName(rodu0), mangledTypeNameHierarchy(rodu0)
Print "ruu0", staticTypeName(ruu0), dynamicTypeName(ruu0), mangledTypeName(ruu0), mangledTypeNameHierarchy(ruu0)
Print "rudu0", staticTypeName(rudu0), dynamicTypeName(rudu0), mangledTypeName(rudu0), mangledTypeNameHierarchy(rudu0)

Sleep

Code: Select all

  variable     static type   by IS type   mangled type   mangled type hierarchy
-------------|-------------|-------------|-------------|-----------------------
io            Integer
d0            Double
s0            String
su0           simpleUDT
o0            Object        Object        OBJECT        OBJECT
u0            UDT           UDT           UDT           UDT->OBJECT
roo0          Object        Object        OBJECT        OBJECT
rou0          Object        UDT           UDT           UDT->OBJECT
rodu0         Object        derivedUDT    DERIVEDUDT    DERIVEDUDT->UDT->OBJECT
ruu0          UDT           UDT           UDT           UDT->OBJECT
rudu0         UDT           derivedUDT    DERIVEDUDT    DERIVEDUDT->UDT->OBJECT
Last edited by fxm on May 05, 2018 19:29, edited 2 times in total.
Juergen Kuehlwein
Posts: 284
Joined: Mar 07, 2018 13:59
Location: Germany

Re: typeof

Post by Juergen Kuehlwein »

@fxm,

thanks for the sample code! I didn´t have time for coding today, so i will have a closer look at it maybe tomorrow. I´m most interested in the name of UDTs like "simpleUDT", but i cannot make use of the staticTypeName function method.


JK
fxm
Moderator
Posts: 12106
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: typeof

Post by fxm »

If you want directly to be able to retrieve in a string the type of a variable at program run time, and this without having previously defined a list of potential types (in whatever form) at compile time, you must necessarily use the Run-Time Type Information (RTTI).
That implies:
- Pre-defined variables such as integral/floating values ​​and strings will not be supported.
- Only User Defined Types (UDT) are supported, provided that they derive (directly or indirectly) from the built-in type "OBJECT".
- Finally it is necessary to use my own function "mangledTypeName ()" which gives access to the type name contained in the RTTI information block of the concerned UDT.

Note:
- Putting "Extends OBJECT" in all the definitions of your super-base UDTs (those that extend nothing before) only adds a hidden pointer to the structure of each constructed instance of the UDT (allowing to access to RTTI).
- Besides, you may access to the virtuality and polymorphism feature, but you are not forced to use it, so that it is transparent for you (no difference in use compared to a simple UDT).
Post Reply