Recent

Author Topic: Operator overload in record helper?  (Read 1648 times)

Zoë

  • New Member
  • *
  • Posts: 28
Operator overload in record helper?
« on: May 15, 2024, 09:34:16 pm »
Is it possible to overload an operator for a record type after the record is declared in {$MODE DELPHI}?

This code works in Delphi:

Code: Pascal  [Select][+][-]
  1. program Main;
  2.  
  3. {$APPTYPE CONSOLE}
  4.  
  5. uses
  6.   SysUtils;
  7.  
  8. type
  9.   timespec = record
  10.     tv_sec: Integer;
  11.     tv_nsec: Integer;
  12.   end;
  13.  
  14.   TTimespecHelper = record helper for timespec
  15.     class operator LessThan(A, B: timespec): Boolean;
  16.   end;
  17.  
  18. class operator TTimespecHelper.LessThan(A, B: timespec): Boolean;
  19. begin
  20.   Result := (A.tv_sec < B.tv_sec) or ((A.tv_sec = B.tv_sec) and (A.tv_nsec < B.tv_nsec))
  21. end;
  22.  
  23. const
  24.   A: timespec = (tv_sec: 2; tv_nsec: 123);
  25.   B: timespec = (tv_sec: 3; tv_nsec: 123);
  26. begin
  27.   WriteLn(A < B);
  28. end.

If I try to compile it with FPC 3.3.1 using {$MODE DELPHI}, it fails with the errors:

Quote
main.pp(15,11) Error: Procedure or Function expected
main.pp(15,11) Error: An interface, helper or Objective-C protocol or category cannot contain fields
main.pp(15,20) Fatal: Syntax error, ":" expected but "identifier LESSTHAN" found

I can get the same effect in {$MODE OBJFPC} by switching from a class helper to a global overload declared like so:

Code: Pascal  [Select][+][-]
  1. operator < (A, B: timespec): Boolean;

But that doesn't compile in {$MODE DELPHI} even if I switch from "operator <" to "operator LessThan".

Am I missing something / is there a way to make this work, or is "Support operator overloading in class helpers" just a feature request?  I can make it work by moving the OBJFPC variant into its own unit so I can switch the {$MODE} for just that, or wrapping the record, but I'd like to avoid it if possible.

Thaddy

  • Hero Member
  • *****
  • Posts: 16992
  • Ceterum censeo Trump esse delendam
Re: Operator overload in record helper?
« Reply #1 on: May 15, 2024, 09:36:11 pm »
No
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

ASerge

  • Hero Member
  • *****
  • Posts: 2411
Re: Operator overload in record helper?
« Reply #2 on: May 16, 2024, 04:12:46 am »
Create a separate unit where you use OBJFPC. In OBJFPC you can use operator:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode ObjFPC}
  4.  
  5. interface
  6.  
  7. type
  8.   TimeSpec = record
  9.     tv_sec: Integer;
  10.     tv_nsec: Integer;
  11.   end;
  12.  
  13. operator < (const A, B: TimeSpec): Boolean;
  14.  
  15. implementation
  16.  
  17. operator < (const A, B: TimeSpec): Boolean;
  18. begin
  19.   Result := (A.tv_sec < B.tv_sec) or ((A.tv_sec = B.tv_sec) and (A.tv_nsec < B.tv_nsec))
  20. end;
  21.  
  22. end.
  23.  

Code: Pascal  [Select][+][-]
  1. {$MODE DELPHI}
  2. {$APPTYPE CONSOLE}
  3.  
  4. uses unit1;
  5.  
  6. const
  7.   A: TimeSpec = (tv_sec: 2; tv_nsec: 123);
  8.   B: TimeSpec = (tv_sec: 3; tv_nsec: 123);
  9. begin
  10.   WriteLn(A < B);
  11.   Readln;
  12. end.

Zoë

  • New Member
  • *
  • Posts: 28
Re: Operator overload in record helper?
« Reply #3 on: May 16, 2024, 05:38:48 pm »
Create a separate unit where you use OBJFPC. In OBJFPC you can use operator:

Thanks.  I did mention that option in my original post; I just wanted to make sure I wasn't missing something.

My use is simple enough that I opted for the wrapper instead so I wouldn't need to use the second unit everywhere, but I did open a feature request for it in case anyone else needs it:

https://gitlab.com/freepascal.org/fpc/source/-/issues/40788

 

TinyPortal © 2005-2018