Quicksort and insertsort incorrectly allowing arrays and vectors by value. #1845.

This commit is contained in:
Christoffer Lerno
2025-01-15 13:31:29 +01:00
parent 29a6a0db32
commit 2f7d18bfb8
7 changed files with 43 additions and 12 deletions

View File

@@ -6,10 +6,15 @@ Sort list using the quick sort algorithm.
@require @is_sortable(list) "The list must be indexable and support .len or .len()"
@require @is_valid_cmp_fn(cmp, list, context) "Expected a comparison function which compares values"
*>
macro insertionsort(list, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @builtin
macro insertionsort(list, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @builtin @safemacro
{
usz len = sort::len_from_list(list);
is::isort(<$typeof(list), $typeof(cmp), $typeof(context)>)(list, 0, (isz)len, cmp, context);
$if @typekind(list) == POINTER &&& (@typekind(*list) == ARRAY || @typekind(*list) == VECTOR):
$typeof((*list)[0])[] list2 = list;
is::isort(<$typeof(list2), $typeof(cmp), $typeof(context)>)(list2, 0, list.len, cmp, context);
$else
usz len = sort::len_from_list(list);
is::isort(<$typeof(list), $typeof(cmp), $typeof(context)>)(list, 0, (isz)len, cmp, context);
$endif
}
module std::sort::is(<Type, CmpFn, Context>);

View File

@@ -9,8 +9,13 @@ Sort list using the quick sort algorithm.
*>
macro quicksort(list, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @builtin
{
usz len = sort::len_from_list(list);
qs::qsort(<$typeof(list), $typeof(cmp), $typeof(context)>)(list, 0, (isz)len - 1, cmp, context);
$if @typekind(list) == POINTER &&& (@typekind(*list) == ARRAY || @typekind(*list) == VECTOR):
$typeof((*list)[0])[] list2 = list;
qs::qsort(<$typeof(list2), $typeof(cmp), $typeof(context)>)(list2, 0, (isz)list.len - 1, cmp, context);
$else
usz len = sort::len_from_list(list);
qs::qsort(<$typeof(list), $typeof(cmp), $typeof(context)>)(list, 0, (isz)len - 1, cmp, context);
$endif
}
<*

View File

@@ -21,6 +21,8 @@ macro bool @is_sortable(#list)
return false;
$case !$defined(#list.len):
return false;
$case @typekind(#list) == VECTOR || @typekind(#list) == ARRAY:
return false;
$case $defined(&#list[0]) &&& !types::is_same($typeof(&#list[0]), $typeof(#list[0])*):
return false;
$default: