fpc/tests/test/units/sortbase/tsortbase.pp
nickysn 5c4af27a7a + added test for the sortbase unit
git-svn-id: trunk@41195 -
2019-02-03 19:16:48 +00:00

168 lines
3.4 KiB
ObjectPascal

program tsortbase;
{$MODE objfpc}
uses
sortbase;
const
Max = 100;
RelTestMin = 1;
RelTestMax = 7;
type
PElement = ^Integer;
TElement = Integer;
TArray = array [0..Max] of TElement;
TPtrArray = array [0..Max] of PElement;
procedure Fail;
begin
Writeln('Err!');
Halt(1);
end;
procedure CheckEqual(const Arr1, Arr2: TArray; N: Integer);
var
I: Integer;
begin
for I := 0 to N - 1 do
if Arr1[I] <> Arr2[I] then
Fail;
end;
procedure CheckPtrArrayDerefEqual(const PtrArr: TPtrArray; const Arr: TArray; N: Integer);
var
I: Integer;
begin
for I := 0 to N - 1 do
if PtrArr[I]^ <> Arr[I] then
Fail;
end;
procedure InitPtrArr(const Arr: TArray; var PtrArr: TPtrArray; N: Integer);
var
I: Integer;
begin
for I := 0 to N - 1 do
PtrArr[I] := @Arr[I];
end;
procedure Sort(var Arr: TArray; N: Integer);
var
I, J: Integer;
tmp: TElement;
begin
for J := 1 to N - 1 do
begin
I := J;
tmp := Arr[I];
while (I > 0) and (Arr[I - 1] > tmp) do
begin
Arr[I] := Arr[I - 1];
Dec(I);
end;
Arr[I] := tmp;
end;
end;
function ListSortComparer_NoContext(Item1, Item2: Pointer): Integer;
begin
if PElement(Item1)^ > PElement(Item2)^ then
Result := 1
else if PElement(Item1)^ < PElement(Item2)^ then
Result := -1
else
Result := 0;
end;
function ListSortComparer_Context(Item1, Item2, Context: Pointer): Integer;
begin
if PElement(Item1)^ > PElement(Item2)^ then
Result := 1
else if PElement(Item1)^ < PElement(Item2)^ then
Result := -1
else
Result := 0;
end;
procedure ListSortCustomItemExchanger_Context(Item1, Item2, Context: Pointer);
var
tmp: TElement;
begin
tmp := PElement(Item1)^;
PElement(Item1)^ := PElement(Item2)^;
PElement(Item2)^ := tmp;
end;
procedure TestSort(const OrigArr: TArray; N: Integer);
var
Arr, SortArr: TArray;
PtrArr: TPtrArray;
begin
SortArr := OrigArr;
Sort(SortArr, N);
Arr := OrigArr;
DefaultSortingAlgorithm^.ItemListSorter_ContextComparer(@Arr[0], N, SizeOf(TElement), @ListSortComparer_Context, nil);
CheckEqual(Arr, SortArr, N);
Arr := OrigArr;
DefaultSortingAlgorithm^.ItemListSorter_CustomItemExchanger_ContextComparer(@Arr[0], N, SizeOf(TElement), @ListSortComparer_Context, @ListSortCustomItemExchanger_Context, nil);
CheckEqual(Arr, SortArr, N);
Arr := OrigArr;
InitPtrArr(Arr, PtrArr, N);
DefaultSortingAlgorithm^.PtrListSorter_ContextComparer(@PtrArr, N, @ListSortComparer_Context, nil);
CheckEqual(Arr, OrigArr, N);
CheckPtrArrayDerefEqual(PtrArr, SortArr, N);
Arr := OrigArr;
InitPtrArr(Arr, PtrArr, N);
DefaultSortingAlgorithm^.PtrListSorter_NoContextComparer(@PtrArr, N, @ListSortComparer_NoContext);
CheckEqual(Arr, OrigArr, N);
CheckPtrArrayDerefEqual(PtrArr, SortArr, N);
end;
{ brute force tests the sorting algorithms by generating all variations with
repetition of N elements chosen from the numbers [0..N-1]. This grows
extremely fast (O(N**N)), so should be used for small values of N only. }
procedure TestAllVariations(N: Integer);
var
Arr: TArray;
SortArr: TArray;
procedure Gen(P: Integer);
var
I: Integer;
begin
if P = N then
begin
TestSort(Arr, N);
exit;
end;
for I := 0 to N - 1 do
begin
Arr[P] := I;
Gen(P + 1);
end;
end;
begin
Gen(0);
end;
procedure TestAllVariations;
var
I: Integer;
begin
for I := RelTestMin to RelTestMax do
TestAllVariations(I);
end;
begin
TestAllVariations;
Writeln('Ok!');
end.