Jump to content
dmitrybv

How to check that TValue.Type is array of TValue

Recommended Posts

Hello 

How to check that TValue.Type is array of TValue

 

 

  function ValueIsValueArray(const V: TValue): Boolean;
  begin
      Result := V.TypeInfo = System.TypeInfo(array of TValue); //??
  end;

Share this post


Link to post

I think like this:

 

  function ValueIsValueArray(const V: TValue): Boolean;
  begin
    Result := (V.TypeInfo <> nil) and (V.TypeInfo^.Kind in [tkArray, tkDynArray]);
    if Result then
      Result := (V.TypeData^.ArrayData.ElType = TypeInfo(TValue));
  end;
 

Share this post


Link to post
Posted (edited)
19 hours ago, dmitrybv said:

    Result := (V.TypeInfo <> nil) and (V.TypeInfo^.Kind in [tkArray, tkDynArray]);

That can be simplified to this:

Result := V.IsArray;
19 hours ago, dmitrybv said:

Result := (V.TypeData^.ArrayData.ElType = TypeInfo(TValue));

The ArrayData field is only meaningful for tkArray, it doesn't exist for tkDynArray.

 

For tkDynArray, the ElType field is a member of TTypeData itself.  However, it is nil if the array holds an unmanaged type.  The actual element type is buried further in the TypeData. The TTypeData record has a DynArrElType() method to fetch it.

 

In both cases, note that the element type is stored as a PPTypeInfo, so you need to dereference it when comparing it to another type.

 

Try something more like this instead:

function ValueIsValueArray(const V: TValue): Boolean;

  // this is pieced together from internal code in System.Rtti.pas...
  function GetArrayElType: PTypeInfo;
  var
    ref: PPTypeInfo;
  begin
    Result := nil;
    case V.Kind of
      tkArray:
        ref := V.TypeData^.ArrayData.ElType;
      tkDynArray:
        ref := V.TypeData^.DynArrElType;
    else
      Exit;
    end;
    if ref <> nil then
      Result := ref^;
  end;

begin
  Result := V.IsArray and (GetArrayElType() = TypeInfo(TValue));
end;

 

Edited by Remy Lebeau
  • Like 2

Share this post


Link to post

Since I only use dynamic arrays I used the following solution:

 

function ValueIsArrayOfValues(const V: TValue): Boolean;
begin
  Result := V.TypeInfo = TypeInfo(TArray<TValue>);
end;

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×