Recent

Poll

I would like to see this feature added to the compiler

Yes
8 (34.8%)
No
10 (43.5%)
I don't care
5 (21.7%)

Total Members Voted: 23

Author Topic: Feature request: hard type creation/declaration  (Read 11710 times)

440bx

  • Hero Member
  • *****
  • Posts: 6462
Re: Feature request: hard type creation/declaration
« Reply #60 on: July 08, 2025, 05:27:22 pm »
Btw, if you only need one base type, then you don't even need the generic.
Can you elaborate on that ?... the majority of handles are ptruint (in Windows)...

Your solution depends on defining records, which works but it really isn't desirable... but that solves the "type" problem...
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12339
  • Debugger - SynEdit - and more
    • wiki
Re: Feature request: hard type creation/declaration
« Reply #61 on: July 08, 2025, 05:36:12 pm »
Btw, if you only need one base type, then you don't even need the generic.
Can you elaborate on that ?... the majority of handles are ptruint (in Windows)...

Your solution depends on defining records, which works but it really isn't desirable... but that solves the "type" problem...

No it doesn't solve the type problem.

If you only need Ptruint, then you can define your "record wrapper" as a normal record instead of as a generic.

But you still have do then do
Code: Pascal  [Select][+][-]
  1. TMFooHandle = type TMWrapper;

And that still has the issue of not copying all operators.

Mind that with the generic, even though you have a specialize on each declaration, that does not create new types.
Code: Pascal  [Select][+][-]
  1. var
  2.   a: specialize TFoo<byte>;
  3.   b: specialize TFoo<byte>;
gives the same type to a and b.

The 2nd specialize re-uses the same type that already exists. That is why you can specialize inline, even do stuff like (if TFoo was a class): begin a := specialize TFoo<byte>.create;



However since it is just the explicit operator that does not get copied....

You can declare the := operator. That seems to get copied.
Code: Pascal  [Select][+][-]
  1. class operator :=(const i: integer): TTypeWrapper;

That also allows typecasts.

Just unfortunately it also allows
  TFooHandle := 0; // without typecast.

but different handles are still incompatible.

440bx

  • Hero Member
  • *****
  • Posts: 6462
Re: Feature request: hard type creation/declaration
« Reply #62 on: July 08, 2025, 05:53:44 pm »
Martin, thank you for elaborating.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Warfley

  • Hero Member
  • *****
  • Posts: 2053
Re: Feature request: hard type creation/declaration
« Reply #63 on: July 10, 2025, 01:45:22 am »
Quick update on the matter, I found the issue and I've fixed it (tbh quite a horrible fix but seems to work). The following test case now compiles:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. {$modeswitch advancedrecords}
  3. type
  4.   generic TTypeWrapper<T> = record
  5.     data: T;
  6.  
  7.     class operator =(const lhs, rhs: specialize TTypeWrapper<T>): Boolean;inline;
  8.     class operator <>(const lhs, rhs: specialize TTypeWrapper<T>): Boolean;inline;
  9.     class operator Explicit(const rec: specialize TTypeWrapper<T>): T;inline;
  10.     class operator Explicit(const value: T): specialize TTypeWrapper<T>;inline;
  11.   end;
  12.  
  13.  
  14. class operator TTypeWrapper.=(const lhs, rhs: specialize TTypeWrapper<T>): Boolean;
  15. begin
  16.   result:=lhs.data=rhs.data;
  17. end;
  18.  
  19. class operator TTypeWrapper.<>(const lhs, rhs: specialize TTypeWrapper<T>): Boolean;
  20. begin
  21.   result:=lhs.data<>rhs.data;
  22. end;
  23.  
  24. class operator TTypeWrapper.Explicit(const rec: specialize TTypeWrapper<T>): T;
  25. begin
  26.   result:=rec.data;
  27. end;
  28.  
  29. class operator TTypeWrapper.Explicit(const value: T): specialize TTypeWrapper<T
  30.   >;
  31. begin
  32.   result.data:=value;
  33. end;
  34.  
  35. type
  36.   TIntegerWrapper = specialize TTypeWrapper<Integer>;
  37.   THWND = type TIntegerWrapper;
  38.   THandle = type TIntegerWrapper;
  39.  
  40.  
  41. var
  42.   hw: THWND;
  43.   hnd: THandle;
  44. begin
  45.   hw := THWND(0);
  46.   hnd := THandle(-1);
  47.   if Integer(hw) <> 0 then Halt(1);
  48.   if Integer(hnd) <> -1 then Halt(2);
  49.   if not (hw=hw) then Halt(3);
  50.   if hw<>hw then Halt(4);
  51. end.
  52.  

Pipeline still failing and need to test a bit more, but hopefully I get this done by the weekend

 

TinyPortal © 2005-2018