Forum > General

How to port TArray.Sort?

<< < (2/2)

Thaddy:
To demonstrate the original issue, that is now solved on the compiler level:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$ifdef fpc}{$mode delphi}{$endif}uses generics.defaults;type  // the delphi style syntax is now accepted!!!  TArray = class  public    class procedure Sort<T>(var Arr:TArray<T>;const Comparer:IComparer<T>);overload;  end;    class procedure TArray.Sort<T>(var Arr:TArray<T>;const Comparer:IComparer<T>);  begin  end; beginend.That means that the TArrayHelper class can be reworked into the TArray class, but as I wrote: that has not been done yet. Bugs  #24254 are/seems  fixed.

domasz:
Great, thank you!

Thaddy:
@domasz

One could use a proxy unit for now.
An example unit would like like this:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit generics.proxies;{$ifndef fpc}{$error this compatibility unit is not needed for Delphi, only for FPC 3.2.3 or higher}{$endif}{$mode delphi}interfaceuses   generics.defaults, generics.collections;type   TArray = class  public    class procedure Sort<T>(var Arr:TArray<T>;const Comparer:IComparer<T>);overload;    class procedure Sort<T>(var AValues: array of T); overload;    class procedure Sort<T>(var AValues: array of T;      const AComparer: IComparer<T>);   overload;    class procedure Sort<T>(var AValues: array of T;      const AComparer: IComparer<T>; AIndex, ACount: NativeInt); overload;    class function BinarySearch<T>(const AValues: array of T; const AItem: T;      out AFoundIndex: NativeInt; const AComparer: IComparer<T>): Boolean; overload;    class function BinarySearch<T>(const AValues: array of T; const AItem: T;      out AFoundIndex: NativeInt): Boolean; overload;    class function BinarySearch<T>(const AValues: array of T; const AItem: T;      out ASearchResult: TBinarySearchResult; const AComparer: IComparer<T>): Boolean; overload;    class function BinarySearch<T>(const AValues: array of T; const AItem: T;      out ASearchResult: TBinarySearchResult): Boolean; overload;    class procedure Copy<T>(const aSource: array of T; var aDestination: array of T; aCount: NativeInt); overload;    class procedure Copy<T>(const aSource: array of T; var aDestination: array of T; aSourceIndex, aDestIndex, aCount: SizeInt); overload;     // Add more to proxy more..  end;    implementation       class procedure TArray.Sort<T>(var Arr:TArray<T>;const Comparer:IComparer<T>);overload;    begin      TArrayHelper<T>.Sort(Arr,Comparer);    end;        class procedure TArray.Sort<T>(var AValues: array of T); overload;    begin      TArrayHelper<T>.Sort(AValues);    end;        class procedure TArray.Sort<T>(var AValues: array of T;      const AComparer: IComparer<T>);   overload;    begin      TArrayHelper<T>.Sort(AValues,AComparer);    end;        class procedure TArray.Sort<T>(var AValues: array of T;      const AComparer: IComparer<T>; AIndex, ACount: NativeInt); overload;    begin      TArrayHelper<T>.Sort(AValues,AComparer,AIndex,ACount);    end;        class function TArray.BinarySearch<T>(const AValues: array of T; const AItem: T;      out AFoundIndex: NativeInt; const AComparer: IComparer<T>): Boolean; overload;    begin      Result := TArrayHelper<T>.BinarySearch(AValues,AItem, AFoundIndex,AComparer);    end;        class function TArray.BinarySearch<T>(const AValues: array of T; const AItem: T;      out AFoundIndex: NativeInt): Boolean; overload;    begin      Result := TArrayHelper<T>.BinarySearch(AValues, AItem,AFoundIndex);    end;     class function TArray.BinarySearch<T>(const AValues: array of T; const AItem: T;      out ASearchResult: TBinarySearchResult; const AComparer: IComparer<T>): Boolean; overload;    begin      Result := TArrayHelper<T>.BinarySearch(AValues,AItem,ASearchResult, AComparer);    end;         class function TArray.BinarySearch<T>(const AValues: array of T; const AItem: T;      out ASearchResult: TBinarySearchResult): Boolean; overload;    begin      Result := TArrayHelper<T>.BinarySearch(AValues,AItem,ASearchResult);    end;     class procedure TArray.Copy<T>(const aSource: array of T; var aDestination: array of T; aCount: NativeInt); overload;    begin      TArrayHelper<T>.Copy(aSource, aDestination, aCount);    end;        class procedure TArray.Copy<T>(const aSource: array of T; var aDestination: array of T; aSourceIndex, aDestIndex,            aCount: SizeInt); overload;    begin       TArrayHelper<T>.Copy(aSource, aDestination, aSourceIndex, aDestIndex, aCount);    end;  end.Simply add this unit for FreePascal only and sort, copy and binarysearch will be Delphi compatible from fpc version 3.2.3 onwards.

The example becomes then:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$ifdef fpc}{$mode delphi}{$endif}uses   classes,generics.defaults, generics.collections   {$ifdef fpc}, generics.proxies{$endif};type   TARecord = record    min,    max:integer;  end;   TMinComparer = class(TInterfacedObject,IComparer<TARecord>)    function Compare(const Left, Right: TARecord): Integer; overload;  end;   function TMinComparer.Compare(const left,right:TARecord):integer;  begin    result := 0;    if right.min > left.min then result := -1    else if right.min < left.min then result := 1;  end; var  RecordArray:TArray<TARecord> = nil;  MinComparer:IComparer<TARecord>;  R:TARecord;  Idx:nativeint;begin  MinComparer   := TMinComparer.Create;  SetLength(RecordArray,4000);   for idx := 0 to High(RecordArray) do  begin    RecordArray[idx].min := random(40);    RecordArray[idx].max := random(40);  end;  TArray.Sort<TArecord>(RecordArray,MinComparer);  for R in RecordArray do write(R.Min:3);  writeln;  readln;end.And compiles in both Delphi12.1+ and Freepascal 3.2.3 + by using just the proxies unit.

Thaddy:
Note, I just noticed I only implemented the parts from Delphi's TArray for which TArrayHelper<T> already provides an implementation. It is in that sense not complete yet, but what is provided in the generics.proxies unit is Delphi compatible.

Navigation

[0] Message Index

[*] Previous page

Go to full version