Recent

Author Topic: doubt using generics  (Read 2976 times)

damieiro

  • Full Member
  • ***
  • Posts: 200
doubt using generics
« on: November 17, 2018, 10:44:11 pm »
Well, I'm trying some ways of wrapping pointers in generic classes, but i cannot achieve to do all the work.
The idea is a generic class to hold a _T data and having two fields, the data field (which has the data) and the pdata which is a pointer to that data.

My main issue is that i cannot use _T in pdata. I must use "pointer" or compiler tells me a forward declaration error. And i would like to use a typed pointer, not a generic one.

Code: Pascal  [Select][+][-]
  1.  
  2. type
  3.   generic Container<_T>= class
  4.     public
  5.       data:_T;
  6.       pdata:pointer; {^_T doesn't work;, HELP NEEDED}
  7.       size:ptruint;
  8.  
  9.       constructor create;virtual;
  10.       destructor destroy; override;
  11.   end;
  12.  
  13.  
  14. implementation
  15.  
  16. constructor Container.create;
  17.  
  18. begin
  19.   size:=sizeof(data);
  20.   pdata:=@data;
  21.  
  22. end;
  23.  
  24. destructor Container.destroy;
  25. begin
  26. {well, this is not needed really}
  27.   size:=0;
  28.   pdata:=nil;
  29. end;
  30.  
  31. end.      
  32.  
  33.  

Example of use (stupid and basic):

Code: Pascal  [Select][+][-]
  1.  
  2. Type
  3.   TTable=Array[1..100] of longint;
  4.   OTable=Specialize Container <tTable>;
  5.  
  6. Var
  7.   Mytable:=Otable;
  8.  
  9. begin
  10.    MyTable:=Otable.Create;
  11.   {do things with Mytable}
  12.    MyTable.Free;
  13. end;
  14.  
  15.  
  16.  


« Last Edit: November 17, 2018, 11:05:33 pm by damieiro »

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: doubt using generics
« Reply #1 on: November 17, 2018, 11:14:09 pm »
Try define type:
Code: Pascal  [Select][+][-]
  1. type
  2.   generic Container<_T>= class
  3.     public type
  4.       P_T = ^_T;
  5.     public
  6.       data:_T;
  7.       pdata:P_T; {^_T doesn't work;, HELP NEEDED}
  8.       size:ptruint;
  9.  
  10.       constructor create;virtual;
  11.       destructor destroy; override;
  12.   end;
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

damieiro

  • Full Member
  • ***
  • Posts: 200
Re: doubt using generics
« Reply #2 on: November 18, 2018, 10:52:55 am »
@Blaazen:
Thanks, it works now. It's like a forward declaration, but i think it should not be needed.

« Last Edit: November 18, 2018, 11:10:01 am by damieiro »

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: doubt using generics
« Reply #3 on: November 18, 2018, 02:57:32 pm »
AFAIR it wasn't needed in past. But it changed, maybe some 10 years back.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Thaddy

  • Hero Member
  • *****
  • Posts: 14210
  • Probably until I exterminate Putin.
Re: doubt using generics
« Reply #4 on: November 18, 2018, 03:42:17 pm »
Indeed. Florian relaxed the rules a bit - and a bit later constrained them a bit - to have more logic in the behavior.
That is indeed quite recent. Not ten years but more like ten weeks.
Code: Pascal  [Select][+][-]
  1. {$ifdef fpc}{$mode delphi}{$H+}{$endif}
  2. type
  3.    Container<_T>= class
  4.     public
  5.       data:_T;
  6.       pdata:^_T;
  7.       size:ptruint;
  8.       constructor create;virtual;
  9.       destructor destroy; override;
  10.   end;
  11.  
  12.   constructor Container<_T>.Create;
  13.   begin
  14.      inherited;
  15.   end;
  16.   destructor Container<_T>.destroy;
  17.   begin
  18.     inherited;
  19.   end;
  20. var
  21.   m:container<integer>;
  22. begin
  23. end.
Which is almost equivalent to the original code and compiles in trunk.

« Last Edit: November 18, 2018, 05:05:42 pm by Thaddy »
Specialize a type, not a var.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: doubt using generics
« Reply #5 on: November 18, 2018, 04:35:43 pm »
Afaik delphi also requires it.

Thaddy

  • Hero Member
  • *****
  • Posts: 14210
  • Probably until I exterminate Putin.
Re: doubt using generics
« Reply #6 on: November 18, 2018, 05:08:29 pm »
What is wrong in the original code (no compiler would help) is not calling inherited.
« Last Edit: November 18, 2018, 05:19:59 pm by Thaddy »
Specialize a type, not a var.

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: doubt using generics
« Reply #7 on: November 18, 2018, 05:34:09 pm »
I probably messed somehing. With some FPC version it was possible to declare var ^Txxx and with a next FPC version one had to declare type PTxxx = ^Txxx and var PTxxx. It happened years ago and (I'm 100% sure) it was not related to generics.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: doubt using generics
« Reply #8 on: November 18, 2018, 06:12:35 pm »
Well, it was one of the differences of Turbo Pascal to versions before.

In Turbo Pascal types were the same if they had the same typedefinition.

In original Pascal it was more equivalence (two different but same type definitions were compatible)

So logically this should be different in mode macpas and iso


damieiro

  • Full Member
  • ***
  • Posts: 200
Re: doubt using generics
« Reply #9 on: November 19, 2018, 12:33:05 pm »
Some commentary to previous posts:

I think there are two different matters

1.- The type forward Declaration like this to avoid circular reference:
Code: Pascal  [Select][+][-]
  1. Type  
  2.   PListItem = ^TListItem;  
  3.   TListItem = Record  
  4.     Data : Integer;  
  5.     Next : PTListItem;  
  6.   end;
  7.  

2.- The type substitutions as presented, where the <_T> token is substituted by other value by specialize. Not circular reference. In the example
Code: Pascal  [Select][+][-]
  1. Container<_T>= class
  2.     public
  3.       data:_T;
  4.       pdata:^_T;
  5.       size:ptruint;
  6.       constructor create;virtual;
  7.       destructor destroy; override;
  8.   end;
  9.  
pdata doesn't allow even pdata:^data. Compiler considers that a generic type is not specified (false, it's specified) , not a circular reference that in case 1. For that reason i didn't see the solution pointed by Blaazen. I think the declaration without a forward type in generics should be ok. (if _T is substituted by specialization there isn't circular reference nor ambiguity).

And thinking more: I even i don't know why
 public type  P_T = ^_T;  works. I do not know why compiler allow this (the public type directive?)



On the other hand. I didn't put inherited on constructor and destructor because that class goes directly from TObject. AFAIK tobject create and destroy methods are empty/null, and the memory reserve/destruction are performed by the constructor and destructor keyword. Should be used inherited in a direct Tobject descendant class? Has any meaning?  (perhaps helpers changing the TObject constructor behaviour? is this possible?)



 
« Last Edit: November 19, 2018, 12:46:01 pm by damieiro »

 

TinyPortal © 2005-2018