[fpc-pascal] Indexing into records using [] property

Ben Grasset operator97 at gmail.com
Thu Oct 18 17:44:07 CEST 2018


If the absence of dereferencing is the most important thing to you, you
could do something like this:

program Example;

{$mode ObjFPC}{$H+}
{$modeswitch AdvancedRecords}

type
  TVec2 = record
    X, Y: Integer;
  end;

  TVec2Array = array of TVec2;

  TVecArray = record
  strict private
    Values: TVec2Array;
  public
    class function Create(const ACapacity: Integer = 16): TVecArray;
inline; static;
    procedure Resize(const NewLength: Integer); inline;
    property I: TVec2Array read Values write Values;
  end;

  class function TVecArray.Create(const ACapacity: Integer = 16): TVecArray;
  begin
    Result := Default(TVecArray);
    SetLength(Result.Values, ACapacity);
  end;

  procedure TVecArray.Resize(const NewLength: Integer);
  begin
    SetLength(Values, NewLength);
  end;

begin
  with TVecArray.Create(0) do
  begin
    Resize(1);
    I[0].X := 100;
    I[0].Y := 100;
  end;
end.

The only downside there is that you obviously don't quite get the real
"default" property syntax.

On Wed, Oct 10, 2018 at 11:06 PM Ryan Joseph <ryan at thealchemistguild.com>
wrote:

> I’d like to know if there is a solution to the problem of indexing into
> records using [] properties.
>
> In the example below I have an array of records (a dynamic array for the
> example) and I’d like to use the [] property to index into the values. The
> problem is because the array holds records I need to return a pointer to
> the record so I can access the fields. In the end the only problem is I
> need to dereference the pointer using ^.
>
> Are there any solutions we could propose to this? Some ideas:
>
> 1) I looks like we could have a “var” modifier for function results but
> that concept has only ever existed in function params (like & in C++).
>
>         function GetValue(i: integer): TVec2; var;
>
> 2) Maybe a modifier added to GetValue which tells the compiler to call the
> function (and result) like a pointer when the indexer is used?
>
> ====================================
>
> type
>         TVec2 = record
>                 x, y: integer;
>         end;
>         TVec2Ptr = ^TVec2;
>         TVec2Array = array of TVec2;
>
> type
>         TVecArray = class
>                 values: TVec2Array;
>                 function GetValue(i: integer): TVec2Ptr;
>                 procedure Resize(newLength: integer);
>                 property Indexer[i: integer]: TVec2Ptr read GetValue;
> default;
>         end;
>
>
> function TVecArray.GetValue(i: integer): TVec2Ptr;
> begin
>         result := @values[i];
> end;
>
> procedure TVecArray.Resize(newLength: integer);
> begin
>         SetLength(values, newLength);
> end;
>
> var
>         arr: TVecArray;
> begin
>         arr := TVecArray.Create;
>         arr.Resize(1);
>         arr[0]^.x := 100;
>         arr[0]^.y := 100;
> end.
>
> Regards,
>         Ryan Joseph
>
> _______________________________________________
> fpc-pascal maillist  -  fpc-pascal at lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20181018/9bf72ad1/attachment.html>


More information about the fpc-pascal mailing list