diff --git a/core/path/filepath/match.odin b/core/path/filepath/match.odin index 3e94d3fd9..75508c449 100644 --- a/core/path/filepath/match.odin +++ b/core/path/filepath/match.odin @@ -284,7 +284,7 @@ _glob :: proc(dir, pattern: string, matches: ^[dynamic]string) -> (m: [dynamic]s fis, _ := os.read_dir(d, -1); - slice.sort_proc(fis, proc(a, b: os.File_Info) -> bool { + slice.sort_by(fis, proc(a, b: os.File_Info) -> bool { return a.name < b.name; }); defer { diff --git a/core/path/filepath/walk.odin b/core/path/filepath/walk.odin index 04424b92e..ba198ff0e 100644 --- a/core/path/filepath/walk.odin +++ b/core/path/filepath/walk.odin @@ -81,7 +81,7 @@ read_dir :: proc(dir_name: string, allocator := context.temp_allocator) -> ([]os if err != 0 { return nil, err; } - slice.sort_proc(fis, proc(a, b: os.File_Info) -> bool { + slice.sort_by(fis, proc(a, b: os.File_Info) -> bool { return a.name < b.name; }); return fis, 0; diff --git a/core/slice/sort.odin b/core/slice/sort.odin index 04199eef6..1e346b1f6 100644 --- a/core/slice/sort.odin +++ b/core/slice/sort.odin @@ -16,9 +16,9 @@ sort :: proc(data: $T/[]$E) where ORD(E) { } } -// sort_proc sorts a slice with a given procedure to test whether two values are ordered "i < j" +// sort_by sorts a slice with a given procedure to test whether two values are ordered "i < j" // This sort is not guaranteed to be stable -sort_proc :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool) { +sort_by :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool) { when size_of(E) != 0 { if n := len(data); n > 1 { _quick_sort_proc(data, 0, n, _max_depth(n), less); @@ -26,15 +26,6 @@ sort_proc :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool) { } } -reverse_sort :: proc(data: $T/[]$E) where ORD(E) { - sort_proc(data, proc(i, j: E) -> bool { - return j < i; - }); -} - - - - is_sorted :: proc(array: $T/[]$E) -> bool where ORD(E) { for i := len(array)-1; i > 0; i -= 1 { if array[i] < array[i-1] { @@ -44,7 +35,7 @@ is_sorted :: proc(array: $T/[]$E) -> bool where ORD(E) { return true; } -is_sorted_proc :: proc(array: $T/[]$E, less: proc(i, j: E) -> bool) -> bool { +is_sorted_by :: proc(array: $T/[]$E, less: proc(i, j: E) -> bool) -> bool { for i := len(array)-1; i > 0; i -= 1 { if less(array[i], array[i-1]) { return false; @@ -54,6 +45,40 @@ is_sorted_proc :: proc(array: $T/[]$E, less: proc(i, j: E) -> bool) -> bool { } +reverse_sort :: proc(data: $T/[]$E) where ORD(E) { + sort_by(data, proc(i, j: E) -> bool { + return j < i; + }); +} + + +// TODO(bill): Should `sort_by_key` exist or is `sort_by` more than enough? +sort_by_key :: proc(data: $T/[]$E, key: proc(E) -> $K) where ORD(K) { + context.user_ptr = rawptr(key); + sort_by(data, proc(i, j: E) -> bool { + k := (proc(E) -> K)(context.user_ptr); + return k(i) < k(j); + }); +} + +reverse_sort_by_key :: proc(data: $T/[]$E, key: proc(E) -> $K) where ORD(K) { + context.user_ptr = rawptr(key); + sort_by(data, proc(i, j: E) -> bool { + k := (proc(E) -> K)(context.user_ptr); + return k(j) < k(i); + }); +} + +is_sorted_by_key :: proc(array: $T/[]$E, key: proc(E) -> $K) -> bool where ORD(K) { + for i := len(array)-1; i > 0; i -= 1 { + if key(array[i]) < key(array[i-1]) { + return false; + } + } + return true; +} + + @(private) _max_depth :: proc(n: int) -> int { // 2*ceil(log2(n+1)) diff --git a/core/sort/sort.odin b/core/sort/sort.odin index 7927bfa11..23a6ef8b3 100644 --- a/core/sort/sort.odin +++ b/core/sort/sort.odin @@ -290,7 +290,7 @@ _insertion_sort :: proc(it: Interface, a, b: int) { -// @(deprecated="use sort.sort or slice.sort_proc") +// @(deprecated="use sort.sort or slice.sort_by") bubble_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) { assert(f != nil); count := len(array); @@ -347,7 +347,7 @@ bubble_sort :: proc(array: $A/[]$T) where intrinsics.type_is_ordered(T) { } } -// @(deprecated="use sort.sort or slice.sort_proc") +// @(deprecated="use sort.sort or slice.sort_by") quick_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) { assert(f != nil); a := array; @@ -412,7 +412,7 @@ _log2 :: proc(x: int) -> int { return res; } -// @(deprecated="use sort.sort or slice.sort_proc") +// @(deprecated="use sort.sort or slice.sort_by") merge_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) { merge :: proc(a: A, start, mid, end: int, f: proc(T, T) -> int) { s, m := start, mid; @@ -497,7 +497,7 @@ merge_sort :: proc(array: $A/[]$T) where intrinsics.type_is_ordered(T) { } -// @(deprecated="use sort.sort or slice.sort_proc") +// @(deprecated="use sort.sort or slice.sort_by") heap_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) { sift_proc :: proc(a: A, pi: int, n: int, f: proc(T, T) -> int) #no_bounds_check { p := pi;