Re: [fpc-devel] Is this supposed to work (generic)?

2023-03-28 Thread Kostas Michalopoulos via fpc-devel

On 3/26/23 14:30, Martin Frb via fpc-devel wrote:
>generic GenLinkedList = class
>  Data: D;
>  Next: T;
>end;
>TSome = class;
>TSome = class(specialize GenLinkedList);

AFAIK "specialize" essentially "pastes" the parameters (after some 
checking) so it'd be as if you had declared...


TSome = class;
GenLinkedList = class
  Data: Integer;
  Next: TSome;
end;
TSome = class(GenLinkedList);

...which is perfectly valid Free Pascal code.

Also AFAIK the reason the others do not work is because when specialize 
is called, TFoo and TBar are not known to the compiler yet, but the 
forward declaration with TSome tells to the compiler that it is a class.


I guess it *is* a bit inconsistent that you can use the name of the type 
you are declaring during the declaration itself for classes - like "TFoo 
= class Foo: TFoo; end" - or target a type with a pointer before the 
targeted type is even known and yet specialization needs to know ahead 
of time everything, but that's how things are :-P


Kostas

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Is this supposed to work (generic)?

2023-03-27 Thread Martin Frb via fpc-devel

On 27/03/2023 22:59, Sven Barth via fpc-devel wrote:

Am 26.03.2023 um 13:30 schrieb Martin Frb via fpc-devel:

  TSome = class;
  TSome = class(specialize GenLinkedList);



The correct way to declare a generic linked list using classes is the 
following:


=== code begin ===

type
  generic TGenLinkedList = class
    Data: D;
    Next: specialize TGenLinkedList;
  end;

  TSome = specialize TGenLinkedList;

=== code end ===


Ok, but the forward declaration (which is the only working one of my 
examples) is also important.
Not sure, why it needs the forward. After all, the forward also comes 
after the generic.



  generic TGenLinkedList = class
    Data: D;
    Next: C;
  end;

  TSome = class;
  TSome = class(specialize TGenLinkedList)
    other: boolean;
    procedure Foo;
  end;

procedure TSome.Foo;
begin
  Next.other := true; // Next must be type TSome, not just the 
specialized generic.

end;

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Is this supposed to work (generic)?

2023-03-27 Thread Sven Barth via fpc-devel

Am 26.03.2023 um 13:30 schrieb Martin Frb via fpc-devel:

3.2.3 and 3.3.1 on Win 64bit

Trying a generic linked list.
So the specialized class must have an entry for the "next" element. 
And that entry is of the same type as the class itself.


Now at first, this seems to be not possible using generics, because 
specialize does not allow to pass in the "partially done" class.

(the 2 commented lines produce "Error: Illegal expression")
Only it does work, if the class is forward declared.

So is it supposed to work?
And if it is in the last case, then what about the other two cases?


program Project1;
type
  generic GenLinkedList = class
    Data: D;
    Next: T;
  end;

  //TBar = specialize GenLinkedList;
  //TFoo = class(specialize GenLinkedList);

  TSome = class;
  TSome = class(specialize GenLinkedList);
begin
end.


Btw, it is the same, if the linked list uses actual pointer.

  generic GenLinkedList = class
    type  PT = ^T;
  public
    Data: D;
    NextPtr: PT;
  end;


The correct way to declare a generic linked list using classes is the 
following:


=== code begin ===

type
  generic TGenLinkedList = class
    Data: D;
    Next: specialize TGenLinkedList;
  end;

  TSome = specialize TGenLinkedList;

=== code end ===

Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel