Enigma #25, force 5 (successive clues could be given to lower the level of difficulty)
Macro to determine if any Type (including pre-defined types and user defined types) has a destructor (explicit or implicit).
Fill in the macro definition (
'TypeHasDtor()') of the code below, which from a passed symbol name for a Type (
'Typesymbol') assigns the value of a passed Boolean variable (
'TypeHasDtorResult') as
'True' or
'False' depending of the existence of a destructor for the corresponding Type:
Code: Select all
#macro TypeHasDtor(TypeSymbol, TypeHasDtorResult)
'' Determine if the Type has a destructor (implicit or explicit).
'' TypeSymbol must be a symbol name referring to a Type (built-in or UDT).
'' (either the Type name itself if it's a symbol name, or an alias)
'' TypeHasDtorResult must be a Boolean variable.
'' (or an integer numeric variable)
'' ------------------------------------------------------------------------
' Insert here the definition code of the macro:
' .....
' .....
' .....
' TypeHasDtorResult = ...
'' ------------------------------------------------------------------------
#endmacro
Dim As Boolean hasDtorResult
TypeHasDtor(Integer, hasDtorResult)
Print "The 'Integer' Type has a destructor (implicit or explicit): ", hasDtorResult
TypeHasDtor(String, hasDtorResult)
Print "The 'String' Type has a destructor (implicit or explicit): ", hasDtorResult
Type string10Type As String * 10 '' define an alias to get a symbol name
TypeHasDtor(string10Type, hasDtorResult)
Print "The 'String * 10' Type has a destructor (implicit or explicit): ", hasDtorResult
Type stringptrType As String Ptr '' define an alias to get a symbol name
TypeHasDtor(stringptrType, hasDtorResult)
Print "The 'String Ptr' Type has a destructor (implicit or explicit): ", hasDtorResult
TypeHasDtor(Object, hasDtorResult)
Print "The 'Object' Type has a destructor (implicit or explicit): ", hasDtorResult
Type UDT1 Extends Object
End Type
TypeHasDtor(UDT1, hasDtorResult)
Print "The 'UDT1' User-Type has destructor (implicit or explicit): ", hasDtorResult
Type UDT2 Extends Object
Declare Destructor ()
End Type
Destructor UDT2 ()
End Destructor
TypeHasDtor(UDT2, hasDtorResult)
Print "The 'UDT2' User-Type has destructor (implicit or explicit): ", hasDtorResult
Sleep
My full solution for defining this macro is a code of 16 simple lines (no concatenated instructions on the same line with
':').
Expected output for the above test case (but must work for any Type):
Code: Select all
The 'Integer' Type has a destructor (implicit or explicit): false
The 'String' Type has a destructor (implicit or explicit): true
The 'String * 10' Type has a destructor (implicit or explicit): false
The 'String Ptr' Type has a destructor (implicit or explicit): false
The 'Object' Type has a destructor (implicit or explicit): false
The 'UDT1' User-Type has destructor (implicit or explicit): false
The 'UDT2' User-Type has destructor (implicit or explicit): true
[edit]
- First clue lowering Enigma #25 to force 4: When a Type has a destructor (explicit or implicit), NEW [] adds an Integer in front of the user instances block to store the number of allocated elements, so that DELETE [] can call the destructor on each element.
- Second clue lowering Enigma #25 to force 3: The macro principle is to apply the New [] operator on an UDT containing a single data member of the Type to test, and to safely check if an Integer (to store the number of instances to destroy) is added ahead the user instances block in the allocated memory. Consequently, the address of the user instances block is different from that of the global allocated memory.
- Third clue lowering Enigma #25 to force 2: To resolve this, the simpler is to define in the UDT an overload operator DELETE [] (a similar method could have been used by defining this time an overload operator NEW []).
- Forth (and last) clue lowering Enigma #25 to force 1: The address of the global memory that the overload operator NEW [] must deallocate is passed to it (under the hood) as a parameter. So, one just has to also store it to later can compare it to the known address of the user instances block (the overload operator being static has no access to the THIS reference).
- Note:
- When one adds an overload operator NEW or NEW [], a parameter gives the number of byte to allocate, and the operator must return the allocated memory address.
- When one adds an overload operator DELETE or DELETE [], a parameter gives the memory address to deallocate.