﻿`` Data := Range(10)->{ A: it, B: Mod(it, 2), C: 17i8 }->Sort(B, [>] A);
`` DataInd := Data->Map(({ A, B }, #));
`` G := 3;

Sort(Data, A)
SortDown(Data, A)
SortUp(Data, [>] A)
SortDown(Data, [<] A)

Sort(Data, [<] B, [<] A)
Sort(Data, [<] B, [>] A)
Sort(Data, [>] B, [<] A)
Sort(Data, [>] B, [>] A)

Sort(DataInd, [<] # + it[0].A + it[0].B)
Sort(DataInd, [<] # + it[0].A + it[0].B, [>] #)
Sort(DataInd, [>] # + it[0].A + it[0].B)
Sort(DataInd, [>] # + it[0].A + it[0].B, [<] #)

SortUp(Data, B, B + 1, A)

SortUp(Data, C, B, A)
SortUp(Data, C, C+1, B, A)
SortUp(Data, C, C+1, C+2, C+3, C+4, C+5, C+6, C+7, C+8, C+9, C+10, C+11, C+12, C+13, C+14, C+15, C+16, C+17, C+18, C+19, C+20, C+21, C+22, C+23, C+24, C+25, C+26, C+27, C+28, C+29, C+30, C+31, C+32, C+33, C+34, C+35, C+36, C+37, C+38, C+39, B, A)

// *** Text sort order.

`` S :=
``   [
``     "B", "A", "a", "A", "b", "\xC1", "\xE1", "\xC0", "\xE0", "0", "9", " ", "", null, "AZ", "BZ", "AZ", "az", "aZ", "Az", "Bz", "Ba", "BA", "az",
``     "st", "\xDF", "ss", "SS", "St", "ST", "\xDF", "st",
``   ];
`` T := Zip(
``   i: Range(1000),
``   t: S,
``   { i, s: CastU8(Text.Len(t)), t });

Sort(     S)
Sort([<]  S)
Sort([>]  S)
Sort([~]  S)
Sort([~<] S)
Sort([~>] S)

Sort(T,      t)
Sort(T, [<]  t)
Sort(T, [>]  t)
Sort(T, [~]  t)
Sort(T, [~<] t)
Sort(T, [~>] t)

// Reverse ties.
Sort(T,      t, [>] i)
Sort(T, [<]  t, [>] i)
Sort(T, [>]  t, [>] i)
Sort(T, [~]  t, [>] i)
Sort(T, [~<] t, [>] i)
Sort(T, [~>] t, [>] i)

// Sort first by length.
Sort(T, [<] s,      t)
Sort(T, [<] s, [<]  t)
Sort(T, [<] s, [>]  t)
Sort(T, [<] s, [~]  t)
Sort(T, [<] s, [~<] t)
Sort(T, [<] s, [~>] t)

// Sort first by length.
Sort(T,     s,      t)
Sort(T, [>] s, [<]  t)
Sort(T, [>] s, [>]  t)
Sort(T, [>] s, [~]  t)
Sort(T, [>] s, [~<] t)
Sort(T, [>] s, [~>] t)

// Do multiple text sorts in the same expression.

// Should see the same comparer loaded twice. This doesn't share the same selector delegate, though it could (with more optimization).
Sort(T, t) ++ Sort(T, [>] t)

// Should also see the same selector delegate loaded twice.
Sort(S) ++ Sort([>] S)

// External values.
Sort(Data, A + G)
Sort(Data, Sum(Range(A)->TakeIf(it mod 3 = 0)))
Sort(Data, Sum(Range(A)->TakeIf(it mod G = 0)))
Range(2)->Map(Sort(Data, A, [<] A, it$1))

// IL subtraction to compare req numeric types <= 4 bytes.
`` D := Range(10);
`` DB := D->Map(it mod 2 = 0);
`` DI1 := D->CastI1();
`` DU1 := D->CastU1();
`` DI2 := D->CastI2();
`` DU2 := D->CastU2();
`` DI4 := D->CastI4();
`` DU4 := D->CastU4();

Sort(DI1, Wrap(it))
Sort(DU1, Wrap(it))
Sort(DI2, Wrap(it))
Sort(DU2, Wrap(it))
Sort(DI4, Wrap(it))
Sort(DU4, Wrap(it))
Sort(DB, Wrap(it))