One curio is whether qsort allows a 3-parameter function to be specified (even though only 2 parameters would be used).
Another curio is whether RegisterCallback can specify 2 parameters, when the function actually has 3 parameters.
Code: Select all
q:: ;sort a string by using qsort (case sensitive)
vText := "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
vText := StrAlphabetize(vText, "C")
;Clipboard := vText
MsgBox, % vText ;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
return
w:: ;sort a string by using qsort (case insensitive)
vText := "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
vText := StrAlphabetize(vText)
;Clipboard := vText
MsgBox, % vText ;AaBbCcDdeEfFGgHhiIJjkKLlMmNnOoPpQqRrsStTuUVvwWxXYyZz
return
e:: ;shuffle a string by using qsort
vText := "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
vText := StrShuffle(vText)
;Clipboard := vText
MsgBox, % vText
return
r:: ;reverse a string by using _wcsrev/_strrev
vText := "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
vText := StrReverse(vText)
;Clipboard := vText
MsgBox, % vText
return
t:: ;sort an array by using qsort (proof of concept)
oArray := StrSplit("qwertyuiopasdfghjklzxcvbnm")
oArray2 := ArrSort(oArray)
vOutput := ""
for vKey, vValue in oArray2
vOutput .= vKey " " vValue "`r`n"
;Clipboard := vOutput
MsgBox, % vOutput
return
;==================================================
;StrAlphabetise
StrAlphabetize(vText, vOpt:="")
{
local
static vChrSize := A_IsUnicode ? 2 : 1
static vFuncCS := A_IsUnicode ? "BinCmpShort" : "BinCmpChar"
static vFuncCI := A_IsUnicode ? "BinCmpShortLower" : "BinCmpCharLower"
static pFuncCS := RegisterCallback(vFuncCS, "C", 2)
static pFuncCI := RegisterCallback(vFuncCI, "C", 2)
pFunc := InStr(vOpt, "C") ? pFuncCS : pFuncCI
DllCall("msvcrt\qsort", "Ptr",&vText, "UPtr",StrLen(vText), "UPtr",vChrSize, "Ptr",pFunc, "Cdecl")
return vText
}
StrShuffle(vText, vOpt:="")
{
local
static vChrSize := A_IsUnicode ? 2 : 1
static pFunc := RegisterCallback("BinCmpRandom", "C", 2)
DllCall("msvcrt\qsort", "Ptr",&vText, "UPtr",StrLen(vText), "UPtr",vChrSize, "Ptr",pFunc, "Cdecl")
return vText
}
StrReverse(vText)
{
local
static vFunc := "msvcrt\" (A_IsUnicode ? "_wcsrev" : "_strrev")
DllCall(vFunc, "Str",vText, "Cdecl")
return vText
}
BinCmpChar(vPtr1, vPtr2, vOffset:=0)
{
local
vNum1 := NumGet(vPtr1+0, 0, "UChar")
vNum2 := NumGet(vPtr2+0, 0, "UChar")
return (vNum1 > vNum2) ? 1 : (vNum1 < vNum2) ? -1 : -vOffset
}
BinCmpShort(vPtr1, vPtr2, vOffset:=0)
{
local
vNum1 := NumGet(vPtr1+0, 0, "UShort")
vNum2 := NumGet(vPtr2+0, 0, "UShort")
return (vNum1 > vNum2) ? 1 : (vNum1 < vNum2) ? -1 : -vOffset
}
BinCmpCharLower(vPtr1, vPtr2, vOffset:=0)
{
local
vNum1 := NumGet(vPtr1+0, 0, "UChar")
vNum2 := NumGet(vPtr2+0, 0, "UChar")
vNum1 := Ord(Format("{:L}", Chr(vNum1)))
vNum2 := Ord(Format("{:L}", Chr(vNum2)))
return (vNum1 > vNum2) ? 1 : (vNum1 < vNum2) ? -1 : -vOffset
}
BinCmpShortLower(vPtr1, vPtr2, vOffset:=0)
{
local
vNum1 := NumGet(vPtr1+0, 0, "UShort")
vNum2 := NumGet(vPtr2+0, 0, "UShort")
vNum1 := Ord(Format("{:L}", Chr(vNum1)))
vNum2 := Ord(Format("{:L}", Chr(vNum2)))
return (vNum1 > vNum2) ? 1 : (vNum1 < vNum2) ? -1 : -vOffset
}
BinCmpRandom(vPtr1, vPtr2, vOffset:=0)
{
local
vNum := Random(0, 1)
return vNum ? 1 : -1
}
;==================================================
;proof of concept
ArrSort(oArray)
{
local
static pFunc := RegisterCallback("ArrSort_Cmp", "C", 2)
vCount := oArray.Length()
VarSetCapacity(vData, vCount*8)
Loop % vCount
NumPut(A_Index, &vData, A_Index*8-8, "Int64")
ArrSort_Cmp(1, oArray)
DllCall("msvcrt\qsort", "Ptr",&vData, "UPtr",vCount, "UPtr",8, "Ptr",pFunc, "Cdecl")
ArrSort_Cmp(2, 0)
oArray2 := []
oArray2.SetCapacity(oArray.Length())
Loop % vCount
vNum := NumGet(&vData, A_Index*8-8, "Int64")
, oArray2.Push(oArray[vNum])
return oArray2
}
;proof of concept
ArrSort_Cmp(vPtr1, vPtr2, vOffset:=0)
{
static oArray
if (vPtr1 = 1)
{
oArray := vPtr2
return
}
else if (vPtr1 = 2)
{
oArray := ""
return
}
vValue1 := oArray[NumGet(vPtr1+0, 0, "Int64")]
vValue2 := oArray[NumGet(vPtr2+0, 0, "Int64")]
return (vValue1 > vValue2) ? 1 : (vValue1 < vValue2) ? -1 : -vOffset
}
;==================================================