[fpc-pascal] How to inline CompareFunc to Sort method in generic abstract class

Adrian Veith adrian at veith-system.de
Tue Dec 13 17:46:34 CET 2022


Hi,

with standard generics in pascal there is currently no solution, but you 
can do it with a "poor man's template". They work with .inc files which 
contain the generic part of your code and they are then included in your 
specialization unit. Something like this for a generic sort - I use 
Delphi syntax !:

file mySuperSort.inc:

procedure Run;

var n, i: Integer; swapped: Boolean begin // this is the generic array 
like object you want to sort n  :=  Length(this);
   repeat
     swapped  :=  false
     for  i:=0 to n-1 do begin // greater is you generic compare
       if  greater(this[i], this[i+1]) then begin
         swap(i,  i+1);
         swapped  :=  true;
       end;
     end;
     n  :=  n- 1;
until not swapped;
end;

Now include it at the place where you need it. In most of the cases the 
easiest way is to create a small adapter record/object

type
   TMySortAdapter = record
     this: TMyDataArray;
     descending: Boolean;
     procedure swap(var a, b: TMyDataType); inline;
     function greater(a, b: TMyDataType); inline;
     procedure sort(data: TMyDataArray; ADescending:Boolean);
   end;

procedure TMySortAdapter.swap(var a, b: TMyDataType);
var t: TMyDataType;
begin
   t:= a;
   a:= b;
   b:= t;
end;

function TMySortAdapter.greater(a, b: TMyDataType);
begin
   if not descending then
     Result:= a > b // whatever you need for you compare
   else
     Result:= b > a
end;

procedure TMySortAdapter.sort(data: TMyDataArray; ADescending:Boolean);
{$I mySuperSort.inc}
begin
   this:= data;
   descending:= ADescending;
   run;
end;

That's the idea behind "poor man templates". Code completely untested

Not exactly the answer you were looking for, but it works.

Adrian.

Am 14.11.22 um 19:26 schrieb Vojtěch Čihák via fpc-pascal:
> Hi,
>   
> I wrote a generic abstract class - a list based on dynamic array (i.e. array of T;) and this class can be specialized elsewhere with any type (records or classes).
> Part of the class is sorting. There are more ways how to deliver *compare function* to sorting method. I can pass it as a parameter or I can define it as: function Compare(A, B: T): Integer; virtual; abstract;. But this way the function cannot be inlined.
>   
> Question: Is there a way how to *inline* compare function to sorting method in this general purpose generic abstract class?
>   
> Thanks.
>   
> PS: The gain is 6-7%.
> _______________________________________________
> fpc-pascal maillist  -fpc-pascal at lists.freepascal.org
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20221213/19333738/attachment.htm>


More information about the fpc-pascal mailing list