Recent

Author Topic: How to add operators to an existing record that can't be edited?  (Read 3186 times)

jamie

  • Hero Member
  • *****
  • Posts: 6686
In this case:
   Windows.LogFont.

 using FpgMap<LogFont, TFONT> for example.

 It requires that logFont has <> operators.

 I can create a local TLogFont with a logfont in it, however, that creates a mess because now I need an identifier for that logfont because the language does not support anonymous records inside another, nor does RECORDS support inheritance, which would also solve this issue.

I tried implementing operators in the unit for this record, but the compiler won't have it, it wants to see a CLASS for this to work.

I looked around and did not find a TLogFont record ready made with operators.

The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 15979
  • Censorship about opinions does not belong here.
Re: How to add operators to an existing record that can't be edited?
« Reply #1 on: August 24, 2024, 05:13:35 pm »
The easiest solution is to write a type helper for logfont.
Slightly more involved is a unit with the TLogfont copied and the operators implemented on your copy.
« Last Edit: August 24, 2024, 05:18:38 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5726
  • Compiler Developer
Re: How to add operators to an existing record that can't be edited?
« Reply #2 on: August 25, 2024, 12:14:20 pm »
The easiest solution is to write a type helper for logfont.

That won't help either, cause at specialization time the compiler only sees the involved types themselves (in this case LogFont and TFont) as well as the units at the time the generic itself had been declared.

Thaddy

  • Hero Member
  • *****
  • Posts: 15979
  • Censorship about opinions does not belong here.
Re: How to add operators to an existing record that can't be edited?
« Reply #3 on: August 25, 2024, 01:12:46 pm »
I tested my second suggestion and that works. In fact it works on any windows structure, provided unit order is obeyed.
If I smell bad code it usually is bad code and that includes my own code.

jamie

  • Hero Member
  • *****
  • Posts: 6686
Re: How to add operators to an existing record that can't be edited?
« Reply #4 on: August 25, 2024, 02:56:32 pm »
I solved the problem for now.

I create a TCLogFont and a member lf:LOGFONT, the rest has the operators in it.


P.S.

 Helpers do not support operators from what I can see and also, operators in the unit interface work but are not seen when specializing the generic.

 So they must live in a record.

The only true wisdom is knowing you know nothing

PascalDragon

  • Hero Member
  • *****
  • Posts: 5726
  • Compiler Developer
Re: How to add operators to an existing record that can't be edited?
« Reply #5 on: September 04, 2024, 09:15:24 pm »
I tested my second suggestion and that works. In fact it works on any windows structure, provided unit order is obeyed.

Code or it did not happen. ;)

jamie

  • Hero Member
  • *****
  • Posts: 6686
Re: How to add operators to an existing record that can't be edited?
« Reply #6 on: September 04, 2024, 11:07:34 pm »
I Dropped a Font structure inside a record and placed the operators there.

SO now I have a TCLogFont and that works.

I guess if Helpers could employ operators that also would have worked.

The only true wisdom is knowing you know nothing

Warfley

  • Hero Member
  • *****
  • Posts: 1684
Re: How to add operators to an existing record that can't be edited?
« Reply #7 on: September 05, 2024, 09:23:29 am »
Why not just add an operator like this?
Code: Pascal  [Select][+][-]
  1. operator =(constref lhs, rhs: LOGFONT): Boolean;
  2. var
  3.   i: Integer;
  4. begin
  5.   Result := True;
  6.   for i:=0 to sizeof(LOGFONT)-1 do
  7.     if PByte(@lhs)[i] <> PByte(@rhs)[i] then
  8.       Exit(False);
  9. end;
  10.  
  11. operator <>(constref lhs, rhs: LOGFONT): Boolean;
  12. begin
  13.   Result := not (lhs = rhs);
  14. end;

PS:
Quote
because the language does not support anonymous records inside another
Well... I did build that, just laying bare rn
« Last Edit: September 05, 2024, 09:26:12 am by Warfley »

Thaddy

  • Hero Member
  • *****
  • Posts: 15979
  • Censorship about opinions does not belong here.
Re: How to add operators to an existing record that can't be edited?
« Reply #8 on: September 05, 2024, 09:58:32 am »
No, it is not laying bare.
What is the case is that you provided examples that do work, where some of the core developers disproved correctness in its current state.
Your effort is very much appreciated, though, and would be a welcome addition.
(Carl Popper's falsification theory in action: has nothing to do with false, but about a counter example that disproves the verifications, however much there are)
 From the discussion on the development branch I can only conclude your effort is greatly appreciated.
« Last Edit: September 05, 2024, 10:03:50 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

Warfley

  • Hero Member
  • *****
  • Posts: 1684
Re: How to add operators to an existing record that can't be edited?
« Reply #9 on: September 05, 2024, 11:55:07 am »
No, it is not laying bare.
I addressed all the issues raised by the maintainers 3 month ago and am now just waiting for responses. I'm very happy with fixing any further issues, but rn I'm just waiting for feedback.

Note: I fully understand that the developers are currently fully occupied with the release of the next FPC version, so I'm not blaming anyone that it is laying bare, because it's just not of priority. But it doesn't change that right now it's just laying there waiting for further input

jamie

  • Hero Member
  • *****
  • Posts: 6686
Re: How to add operators to an existing record that can't be edited?
« Reply #10 on: September 05, 2024, 01:34:28 pm »
Why not just add an operator like this?
Code: Pascal  [Select][+][-]
  1. operator =(constref lhs, rhs: LOGFONT): Boolean;
  2. var
  3.   i: Integer;
  4. begin
  5.   Result := True;
  6.   for i:=0 to sizeof(LOGFONT)-1 do
  7.     if PByte(@lhs)[i] <> PByte(@rhs)[i] then
  8.       Exit(False);
  9. end;
  10.  
  11. operator <>(constref lhs, rhs: LOGFONT): Boolean;
  12. begin
  13.   Result := not (lhs = rhs);
  14. end;

PS:
Quote
because the language does not support anonymous records inside another
Well... I did build that, just laying bare rn

The problem I believe is the Generics, it needs < > comparators and seems only records work .
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018