/examples/manual/proguide/compare_all_rtti_info.bas

https://github.com/freebasic/fbc · Basic · 140 lines · 101 code · 11 blank · 28 comment · 0 complexity · ddc523cf03b128b2eeecb451f845d2ac MD5 · raw file

  1. '' examples/manual/proguide/compare_all_rtti_info.bas
  2. ''
  3. '' Example extracted from the FreeBASIC Manual
  4. '' from topic 'OBJECT built-in and RTTI info'
  5. ''
  6. '' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=ProPgObjectRtti
  7. '' --------
  8. Namespace oop
  9. Type parent Extends Object
  10. End Type
  11. Type child Extends parent
  12. End Type
  13. Type grandchild Extends child
  14. End Type
  15. End Namespace
  16. Function mangledTypeNameFromRTTI (ByVal po As Object Ptr, ByVal baseIndex As Integer = 0) As String
  17. ' Function to get any mangled-typename in the inheritance up hierarchy
  18. ' of the type of an instance (address: 'po') compatible with the built-in 'Object'
  19. '
  20. ' ('baseIndex = 0' to get the mangled-typename of the instance)
  21. ' ('baseIndex = -1' to get the base mangled-typename of the instance, or "" if not existing)
  22. ' ('baseIndex = -2' to get the base.base mangled-typename of the instance, or "" if not existing)
  23. ' (.....)
  24. '
  25. Dim As String s
  26. Dim As ZString Ptr pz
  27. Dim As Any Ptr p = CPtr(Any Ptr Ptr Ptr, po)[0][-1] ' Ptr to RTTI info
  28. For I As Integer = baseIndex To -1
  29. p = CPtr(Any Ptr Ptr, p)[2] ' Ptr to Base RTTI info of previous RTTI info
  30. If p = 0 Then Return s
  31. Next I
  32. pz = CPtr(Any Ptr Ptr, p)[1] ' Ptr to mangled-typename
  33. s = *pz
  34. Return s
  35. End Function
  36. Function typeNameFromRTTI (ByVal po As Object Ptr, ByVal baseIndex As Integer = 0) As String
  37. ' Function to get any typename in the inheritance up hierarchy
  38. ' of the type of an instance (address: 'po') compatible with the built-in 'Object'
  39. '
  40. ' ('baseIndex = 0' to get the typename of the instance)
  41. ' ('baseIndex = -1' to get the base.typename of the instance, or "" if not existing)
  42. ' ('baseIndex = -2' to get the base.base.typename of the instance, or "" if not existing)
  43. ' (.....)
  44. '
  45. Dim As String s
  46. Dim As ZString Ptr pz
  47. Dim As Any Ptr p = CPtr(Any Ptr Ptr Ptr, po)[0][-1] ' Ptr to RTTI info
  48. For I As Integer = baseIndex To -1
  49. p = CPtr(Any Ptr Ptr, p)[2] ' Ptr to Base RTTI info of previous RTTI info
  50. If p = 0 Then Return s
  51. Next I
  52. pz = CPtr(Any Ptr Ptr, p)[1] ' Ptr to mangled-typename
  53. Do
  54. Do While (*pz)[0] > Asc("9") OrElse (*pz)[0] < Asc("0")
  55. If (*pz)[0] = 0 Then Return s
  56. pz += 1
  57. Loop
  58. Dim As Integer N = Val(*pz)
  59. Do
  60. pz += 1
  61. Loop Until (*pz)[0] > Asc("9") OrElse (*pz)[0] < Asc("0")
  62. If s <> "" Then s &= "."
  63. s &= Left(*pz, N)
  64. pz += N
  65. Loop
  66. End Function
  67. Function typeNameHierarchyFromRTTI (ByVal po As Object Ptr) As String
  68. ' Function to get the typename inheritance up hierarchy
  69. ' of the type of an instance (address: po) compatible with the built-in 'Object'
  70. '
  71. Dim As String s = TypeNameFromRTTI(po)
  72. Dim As Integer i = -1
  73. Do
  74. Dim As String s0 = typeNameFromRTTI(po, i)
  75. If s0 = "" Then Exit Do
  76. s &= "->" & s0
  77. i -= 1
  78. Loop
  79. Return s
  80. End Function
  81. Function typeNameEqualFromRTTI (ByVal po As Object Ptr, ByRef typeName As String) As Boolean
  82. ' Function to get true if the instance typename (address: po) is the same than the passed string
  83. '
  84. Dim As String t = UCase(typeName)
  85. Dim As ZString Ptr pz = CPtr(Any Ptr Ptr Ptr Ptr, po)[0][-1][1] ' Ptr to Mangled Typename
  86. Dim As Integer i = 1
  87. Do
  88. Do While (*pz)[0] > Asc("9") OrElse (*pz)[0] < Asc("0")
  89. If (*pz)[0] = 0 Then Return True
  90. pz += 1
  91. Loop
  92. Dim As Integer N = Val(*pz)
  93. Do
  94. pz += 1
  95. Loop Until (*pz)[0] > Asc("9") OrElse (*pz)[0] < Asc("0")
  96. If i > 1 Then
  97. If Mid(t, i, 1) <> "." Then Return False Else i += 1
  98. End If
  99. If Mid(t, i, N) <> Left(*pz, N) Then Return False Else pz += N : i += N
  100. Loop
  101. End Function
  102. Dim As Object Ptr p = New oop.grandchild
  103. Print "Mangled typenames list, from RTTI info:"
  104. Print " " & mangledTypeNameFromRTTI(p, 0)
  105. Print " " & mangledTypeNameFromRTTI(p, -1)
  106. Print " " & mangledTypeNameFromRTTI(p, -2)
  107. Print " " & mangledTypeNameFromRTTI(p, -3)
  108. Print
  109. Print "Typenames (demangled) list, from RTTI info:"
  110. Print " " & typeNameFromRTTI(p, 0)
  111. Print " " & typeNameFromRTTI(p, -1)
  112. Print " " & typeNameFromRTTI(p, -2)
  113. Print " " & typeNameFromRTTI(p, -3)
  114. Print
  115. Print "Typename (demangled) and all those of its base-types hierarchy, from RTTI info:"
  116. Print " " & typeNameHierarchyFromRTTI(p)
  117. Delete p
  118. Print
  119. p = New oop.child
  120. Print "Is the typename of an oop.child instance the same as ""child""?"
  121. Print " " & typeNameEqualFromRTTI(p, "child")
  122. Print "Is the typename of an oop.child instance the same as ""oop.child""?"
  123. Print " " & typeNameEqualFromRTTI(p, "oop.child")
  124. Print "Is the typename of an oop.child instance the same as ""oop.grandchild""?"
  125. Print " " & typeNameEqualFromRTTI(p, "oop.grandchild")
  126. Print "Is the typename of an oop.child instance the same as ""oop.parent""?"
  127. Print " " & typeNameEqualFromRTTI(p, "oop.parent")
  128. Delete p
  129. Sleep