RTTI Delphi Create as TValue n-dimensional matrix

Good afternoon,

TValue is a feature of Delphi 2010 and RTTI.

Following my previous question, I tried to make a repeating function in order to return TValue as n-dimensional. matrix (2D, 3D, 4D ...)

for example, this procedure will show an n-dimensional matrix (it will display all elements from an n-dimensional matrix as a TValue variable):

Procedure Show(X:TValue); var i:integer; begin if x.IsArray then begin for i:=0 to x.GetArrayLength-1 do show(x.GetArrayElement(i)); writeln; end else write(x.ToString,' '); end; 

I don’t understand how to create a function to create an n-dimensional matrix from TValue. For example, I need a function CreateDynArray (Dimensions: array of integer; Kind: TTypeKind): TValue; and the function will return TValue, which is a dynamic array that contains dimensions, for example:

Return = CreateDynArray ([2,3], tkInteger); will return TValue as tkDynArray and if I show (Return) you will list

 0 0 0 0 0 0 

Not completed. From TValue, I am trying to create a DynArray with n-dimensional dimensions

 Procedure CreateArray(var Value:TValue; NewDimmension:integer; NewValue2Kind:TTypeKind; NewValue2:TValue; IsLast:Boolean); var i:integer; NewValue:TValue; len:Longint; begin If Value.IsArray then// we have components in this dimension begin for i:=0 to Value.GetArrayLength-1 do// list all begin NewValue:=Value.GetArrayElement[i]; CreateArray(newValue,NewDimension,NewValue2Kind,NewValue2,IsLast); Value.SetArrayElement(i,NewValue); end; end; end else begin if isLast then begin len:=NewDimension; DynArraySetLength(PPointer(Value.GetRefereneToRawData)^,Value.TypeInfo,1,@len); //set length to NewDimension for i:=0 to NewDimension-1 do //Fill all with 0 Value.SetArrayElement(i,NewValue2); end else begin len:=NewDimension; DynArraySetLength(PPointer(Value.GetRefereneToRawData)^,Value.TypeInfo,1,@len);//I will create len TValues end; end; var Index:array of integer; Value:TValue; ValuKind:TTypeKind; ...... ...... .... Case token of tokInt: begin ValueKind:=tkInteger; Value:=0; end; ..... end; Index:=GetIndexFromSintacticTree;//for example if i have int[20][30] index=[20,30] for i:=0 to high(index) do begin if i = high(index) then CreateArray(Variable.Value,Index[i],ValueKind,Value,True) else CreateArray(Variable.Value,Index[i],ValueKind,Value,False) //Variable.Value is TValue end; //first TValue have 1 element, after that it will have 20 elements, and after that will have 20*30 elements 

The ideea

Thank you very much and have a nice day!

+4
source share
1 answer

To dynamically create a dynamic array, you need a link to its type information structure ( PTypeInfo ) to go to DynArraySetLength ; calling DynArraySetLength and passing a reference to a nil pointer is how you can create a new dynamic array. If the specific form of the dynamic array does not already exist in your Delphi program, there will not be any specific PTypeInfo pointer that the compiler will generate for you. In this case, you will need to create the corresponding PTypeInfo data PTypeInfo yourself. It is possible, though tiring.

Frankly, I would recommend using a different structure than Delphi's built-in dynamic arrays to represent arrays in your problem with similar scripts. In the long run, this is likely to be much less than trying to dynamically generate low-level RTTI data, which is more likely to change from version to version, now that it has a significantly higher level abstraction in the Rtti block.

+5
source

Source: https://habr.com/ru/post/1333793/


All Articles