/usr/src/castle-game-engine-4.1.1/base/castleutils_implement_sort.inc is in castle-game-engine-src 4.1.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | { Implementation of Sort and SortByObject }
procedure SimpleSort(
L: Pointer; LIndex: Integer;
R: Pointer; RIndex: Integer);
{ Simple sort by choosing }
var
NowIndex: Integer;
MinPtr, NowPtr, Temp: Pointer;
{ PtrInt aliases for pointer types, to allow for
addition on them with ArrStride (signed) without any warnings. }
NowPtrInt: PtrInt absolute NowPtr;
LInt: PtrInt absolute L;
begin
Temp := GetMem(ArrRecordSize);
try
while LIndex < RIndex do
begin
MinPtr := L;
NowPtr := L;
for NowIndex := LIndex + 1 to RIndex do
begin
NowPtrInt := NowPtrInt + ArrStride;
if IsSmallerFunc(NowPtr, MinPtr
{$ifndef SORT_BY_OBJECT},IsSmallerFuncData{$endif}) then
MinPtr := NowPtr;
end;
{ swap L and MinPtr }
Move(L^, Temp^, ArrRecordSize);
Move(MinPtr^, L^, ArrRecordSize);
Move(Temp^, MinPtr^, ArrRecordSize);
LInt := LInt + ArrStride;
Inc(LIndex);
end;
finally FreeMem(Temp) end;
end;
procedure InternalSort(
L: Pointer; LIndex: Integer;
R: Pointer; RIndex: Integer);
var
I, J: Pointer;
{ PtrInt aliases for pointer types, to allow for
addition on them with ArrStride (signed) without any warnings. }
IInt: PtrInt absolute I;
JInt: PtrInt absolute J;
IIndex, JIndex: Integer;
Temp, Middle: Pointer;
begin
if LIndex >= RIndex then Exit;
if RIndex - LIndex <= CountToUseSimpleSort - 1 then
begin
SimpleSort(L, LIndex, R, RIndex);
Exit;
end;
I := L; IIndex := LIndex;
J := R; JIndex := RIndex;
Middle := nil;
Temp := nil;
try
{ Set Middle pointer.
Many strategies possible here. }
Middle := GetMem(ArrRecordSize);
Move(PointerAdd(Arr, ((LIndex + RIndex) div 2) * ArrStride)^,
Middle^, ArrRecordSize);
Temp := GetMem(ArrRecordSize);
repeat
while IsSmallerFunc(I, Middle {$ifndef SORT_BY_OBJECT},IsSmallerFuncData{$endif}) do
begin
{ next i }
IInt := IInt + ArrStride;
Inc(IIndex);
end;
while IsSmallerFunc(Middle, J {$ifndef SORT_BY_OBJECT},IsSmallerFuncData{$endif}) do
begin
{ previous j }
JInt := JInt - ArrStride;
Dec(JIndex);
end;
if IIndex <= JIndex then
begin
{ swap ith and jth items }
Move(I^, Temp^, ArrRecordSize); { temp:=Arr[i] }
Move(J^, I^, ArrRecordSize); { Arr[i]:=Arr[j] }
Move(Temp^, J^, ArrRecordSize); { Arr[j]:=temp }
{ next i }
IInt := IInt + ArrStride;
Inc(IIndex);
{ previous j }
JInt := JInt - ArrStride;
Dec(JIndex);
end;
until IIndex > JIndex;
finally
FreeMem(Temp);
FreeMem(Middle);
end;
InternalSort(L, LIndex, J, JIndex);
InternalSort(I, IIndex, R, RIndex);
end;
begin
InternalSort(
PointerAdd(Arr, FirstIndex * ArrStride), FirstIndex,
PointerAdd(Arr, LastIndex * ArrStride), LastIndex);
end;
|