diff --git a/src/shared/binheap.pas b/src/shared/binheap.pas
index 50531ed6f453d79044597739bf48d813dfe96c6f..e3ff3e742870f89fda244fd1b86152e35a1cfe67 100644 (file)
--- a/src/shared/binheap.pas
+++ b/src/shared/binheap.pas
-(* Copyright (C) DooM 2D:Forever Developers
+(* Copyright (C) Doom 2D: Forever Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, version 3 of the License ONLY.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
interface
interface
+(*
+ * CmpObjT: class that contains class methods:
+ * class function less (const[ref] a, b: KeyT): Boolean;
+ *)
type
// WARNING! don't put structures into heap, use ponters or ids!
type
// WARNING! don't put structures into heap, use ponters or ids!
- generic TBinaryHeapBase<ITP> = class(TObject)
- private
- type
- TBinaryHeapLessFn = function (a, b: ITP): Boolean;
-
+ generic TBinaryHeapBase<ITP, CmpObjT> = class(TObject)
private
elem: array of ITP;
elemUsed: Integer;
private
elem: array of ITP;
elemUsed: Integer;
- lessfn: TBinaryHeapLessFn;
private
procedure heapify (root: Integer);
public
private
procedure heapify (root: Integer);
public
- constructor Create (alessfn: TBinaryHeapLessFn);
+ constructor Create ();
destructor Destroy (); override;
procedure clear ();
destructor Destroy (); override;
procedure clear ();
type
type
- TBinaryHeapObj = specialize TBinaryHeapBase<TObject>;
- TBinaryHeapInt = specialize TBinaryHeapBase<Integer>;
+ TBinHeapKeyIntLess = class
+ public
+ class function less (const a, b: Integer): Boolean; inline;
+ end;
+
+ TBinHeapKeyIntGreat = class
+ public
+ class function less (const a, b: Integer): Boolean; inline;
+ end;
-function binHeapNewIntLess (): TBinaryHeapInt;
-function binHeapNewIntGreat (): TBinaryHeapInt;
+type
+ TBinaryHeapIntLess = specialize TBinaryHeapBase<Integer, TBinHeapKeyIntLess>;
+ TBinaryHeapIntGreat = specialize TBinaryHeapBase<Integer, TBinHeapKeyIntGreat>;
implementation
implementation
// ////////////////////////////////////////////////////////////////////////// //
// ////////////////////////////////////////////////////////////////////////// //
-function intLess (a, b: Integer): Boolean; begin result := (a < b); end;
-function intGreat (a, b: Integer): Boolean; begin result := (a > b); end;
-
-
-function binHeapNewIntLess (): TBinaryHeapInt; begin result := TBinaryHeapInt.Create(@intLess); end;
-function binHeapNewIntGreat (): TBinaryHeapInt; begin result := TBinaryHeapInt.Create(@intGreat); end;
+class function TBinHeapKeyIntLess.less (const a, b: Integer): Boolean; inline; begin result := (a < b); end;
+class function TBinHeapKeyIntGreat.less (const a, b: Integer): Boolean; inline; begin result := (a > b); end;
// ////////////////////////////////////////////////////////////////////////// //
// ////////////////////////////////////////////////////////////////////////// //
-constructor TBinaryHeapBase.Create (alessfn: TBinaryHeapLessFn);
+constructor TBinaryHeapBase.Create ();
begin
begin
- if not assigned(alessfn) then raise Exception.Create('wutafuck?!');
- lessfn := alessfn;
SetLength(elem, 128); // 'cause why not?
elemUsed := 0;
end;
SetLength(elem, 128); // 'cause why not?
elemUsed := 0;
end;
smallest := 2*root+1; // left child
if (smallest >= elemUsed) then break; // anyway
right := smallest+1; // right child
smallest := 2*root+1; // left child
if (smallest >= elemUsed) then break; // anyway
right := smallest+1; // right child
- if not lessfn(elem[smallest], elem[root]) then smallest := root;
- if (right < elemUsed) and (lessfn(elem[right], elem[smallest])) then smallest := right;
+ if not CmpObjT.less(elem[smallest], elem[root]) then smallest := root;
+ if (right < elemUsed) and (CmpObjT.less(elem[right], elem[smallest])) then smallest := right;
if (smallest = root) then break;
// swap
tmp := elem[root];
if (smallest = root) then break;
// swap
tmp := elem[root];
while (i <> 0) do
begin
par := (i-1) div 2; // parent
while (i <> 0) do
begin
par := (i-1) div 2; // parent
- if not lessfn(val, elem[par]) then break;
+ if not CmpObjT.less(val, elem[par]) then break;
elem[i] := elem[par];
i := par;
end;
elem[i] := elem[par];
i := par;
end;