class operator enumerator

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

class operator enumerator

Ryan Joseph
Is "class operator enumerator” supposed to work or is this a bug that it compiles but doesn’t do anything? Seems like it should work.

===========================

{$mode objfpc}
{$modeswitch advancedrecords}

program test;

type
  TArrayEnumerator = class
    public type
      TArrayValue = integer;
    public
      function GetCurrent: TArrayValue;
      constructor Create(a: pointer);
      property Current: TArrayValue read GetCurrent;
      function MoveNext: Boolean;
  end;
  TRec = record
    class operator enumerator(a: TRec): TArrayEnumerator;
  end;

class operator TRec.Enumerator(a: TRec): TArrayEnumerator;
begin
  result := TArrayEnumerator.Create(@a);
end;

function TArrayEnumerator.GetCurrent: TArrayValue;
begin
end;

constructor TArrayEnumerator.Create(a: pointer);
begin
end;

function TArrayEnumerator.MoveNext: Boolean;
begin  
end;

var
  arr: TRec;
  value: integer;
begin
  for value in arr do // <<<< ERROR: Cannot find an enumerator for the type "TRec"
    begin
    end;
end.


Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: class operator enumerator

Ben Grasset
Seems like it's mixed up in some way with the FPC-style enumerator operator, so the "class" version is recognized but not actually implemented currently or something.

The normal way for classes/records/objects is to implement a GetEnumerator function, anyways. Here's an expanded-on version of your example, using your generic constants feature:

program Test;

{$mode ObjFPC}
{$PointerMath On}
{$modeswitch AdvancedRecords}

type
  generic TConstArray<T; const N: PtrUInt> = array[0..N] of T;

  generic TArrayEnumerator<T; const N: PtrUInt> = record
  public type 
    PT = ^T;
  public const 
    HIGH_INDEX = N;
  private
    CurrentIndex: PtrUInt;
    DataPointer: PT;
  public
    function GetCurrent: T; inline;
    class function Create(const A: PT): TArrayEnumerator; static; inline;
    function MoveNext: Boolean; inline;
    property Current: T read GetCurrent;
  end;

  generic TRec<T; const N: PtrUInt> = record
  public type 
    TRecEnumerator = specialize TArrayEnumerator<T, N>;
  private
    FData: specialize TConstArray<T, N>;
  public
    class operator Initialize(var Rec: TRec);
    function GetEnumerator: TRecEnumerator; inline;
  end;

  function TArrayEnumerator.GetCurrent: T;
  begin
    Result := DataPointer[CurrentIndex];
  end;

  class function TArrayEnumerator.Create(const A: PT): TArrayEnumerator;
  begin
    with Result do begin
      DataPointer := A;
      CurrentIndex := -1;
    end;
  end;

  function TArrayEnumerator.MoveNext: Boolean;
  begin
    Inc(CurrentIndex);
    Result := CurrentIndex <= HIGH_INDEX;
  end;

  class operator TRec.Initialize(var Rec: TRec);
  var I: PtrUInt;
  begin
    for I := 0 to N do Rec.FData[I] := I;
  end;

  function TRec.GetEnumerator: TRecEnumerator;
  begin
    Result := TRecEnumerator.Create(@FData);
  end;

var
  Arr: specialize TRec<SizeInt, 5>;
  Value: SizeInt;

begin
  for Value in Arr do WriteLn(Value);
end.

On Tue, Apr 23, 2019 at 2:08 PM Ryan Joseph <[hidden email]> wrote:
Is "class operator enumerator” supposed to work or is this a bug that it compiles but doesn’t do anything? Seems like it should work.

===========================

{$mode objfpc}
{$modeswitch advancedrecords}

program test;

type
  TArrayEnumerator = class
    public type
      TArrayValue = integer;
    public
      function GetCurrent: TArrayValue;
      constructor Create(a: pointer);
      property Current: TArrayValue read GetCurrent;
      function MoveNext: Boolean;
  end;
  TRec = record
    class operator enumerator(a: TRec): TArrayEnumerator;
  end;

class operator TRec.Enumerator(a: TRec): TArrayEnumerator;
begin
  result := TArrayEnumerator.Create(@a);
end;

function TArrayEnumerator.GetCurrent: TArrayValue;
begin
end;

constructor TArrayEnumerator.Create(a: pointer);
begin
end;

function TArrayEnumerator.MoveNext: Boolean;
begin 
end;

var
  arr: TRec;
  value: integer;
begin
  for value in arr do   // <<<< ERROR: Cannot find an enumerator for the type "TRec"
    begin
    end;
end.


Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: class operator enumerator

Ryan Joseph


> On Apr 24, 2019, at 12:30 AM, Ben Grasset <[hidden email]> wrote:
>
> Seems like it's mixed up in some way with the FPC-style enumerator operator, so the "class" version is recognized but not actually implemented currently or something.
>
> The normal way for classes/records/objects is to implement a GetEnumerator function, anyways. Here's an expanded-on version of your example, using your generic constants feature:

I think they just forget to disable the operator for records but I believe the operator function works as intended however.

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: class operator enumerator

Free Pascal - General mailing list
Am 24.04.2019 um 15:31 schrieb Ryan Joseph:
>
>> On Apr 24, 2019, at 12:30 AM, Ben Grasset <[hidden email]> wrote:
>>
>> Seems like it's mixed up in some way with the FPC-style enumerator operator, so the "class" version is recognized but not actually implemented currently or something.
>>
>> The normal way for classes/records/objects is to implement a GetEnumerator function, anyways. Here's an expanded-on version of your example, using your generic constants feature:
> I think they just forget to disable the operator for records but I believe the operator function works as intended however.
It should probably best be forbidden for class operators considering
there is the GetEnumerator way to add one (and it even works with helpers).

Regadrs,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal