1# Copyright (C) 2025 yuygfgg
3# This file is part of Vapoursynth-llvmexpr.
5# Vapoursynth-llvmexpr is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
10# Vapoursynth-llvmexpr is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
15# You should have received a copy of the GNU General Public License
16# along with Vapoursynth-llvmexpr. If not, see <https://www.gnu.org/licenses/>.
19 @define ___STDLIB_ALGORITHMS_RANGE_PARAM_TYPE Literal
21 @define ___STDLIB_ALGORITHMS_RANGE_PARAM_TYPE Value
24function ___stdlib_algorithms_swap(Array a, Value i, Value j) {
30function ___stdlib_algorithms_heapify(Array a, Value n, Value i, Value offset) {
34 left = 2 * current_i + 1;
35 right = 2 * current_i + 2;
37 if (left < n && a[offset + largest] < a[offset + left]) {
40 if (right < n && a[offset + largest] < a[offset + right]) {
44 if (largest == current_i) {
45 goto heapify_loop_end;
48 ___stdlib_algorithms_swap(a, offset + current_i, offset + largest);
54function ___stdlib_algorithms_insertion_sort(Array a, Value begin, Value end) {
59 while (j >= begin && a[j] > key) {
68function ___stdlib_algorithms_heapsort(Array a, Value begin, Value end) {
73 ___stdlib_algorithms_heapify(a, n, i, begin);
79 ___stdlib_algorithms_swap(a, begin, begin + i);
80 ___stdlib_algorithms_heapify(a, i, 0, begin);
85function ___stdlib_algorithms_median_of_three(Array a, Value low, Value high) {
86 mid = floor(low + (high - low) / 2);
87 if (a[low] > a[mid]) {
88 ___stdlib_algorithms_swap(a, low, mid);
90 if (a[low] > a[high]) {
91 ___stdlib_algorithms_swap(a, low, high);
93 if (a[mid] > a[high]) {
94 ___stdlib_algorithms_swap(a, mid, high);
96 ___stdlib_algorithms_swap(a, mid, high);
99function ___stdlib_algorithms_partition(Array a, Value low, Value high) {
106 ___stdlib_algorithms_swap(a, i, j);
110 ___stdlib_algorithms_swap(a, i + 1, high);
114function ___stdlib_algorithms_copy_range(Array dest, Value dest_start, Array src, Value src_start, Value len) {
117 dest[dest_start + i] = src[src_start + i];
122function ___stdlib_algorithms_find_kth_smallest_fast(Array a, ___STDLIB_ALGORITHMS_RANGE_PARAM_TYPE begin, ___STDLIB_ALGORITHMS_RANGE_PARAM_TYPE end, ___STDLIB_ALGORITHMS_RANGE_PARAM_TYPE len, Value k) {
124 ___stdlib_algorithms_copy_range(temp_arr, 0, a, begin, len);
128 result = -1.0; # Default error value
130 while (low <= high) {
131 pivot_idx = ___stdlib_algorithms_partition(temp_arr, low, high);
132 if (pivot_idx == k) {
133 result = temp_arr[k];
134 goto find_kth_fast_end;
139 high = pivot_idx - 1;
147function ___stdlib_algorithms_find_kth_smallest_slow(Array arr, Value begin, Value end, Value k) {
150 candidate_val = arr[i];
156 if (elem < candidate_val) {
157 less_count = less_count + 1;
158 } else if (elem == candidate_val) {
159 equal_count = equal_count + 1;
163 if (k >= less_count && k < (less_count + equal_count)) {
164 return candidate_val;
171function ___stdlib_algorithms_sort(Array a, Value begin, Value end) {
177 INSERTION_SORT_THRESHOLD = 16;
178 if (n < INSERTION_SORT_THRESHOLD) {
179 ___stdlib_algorithms_insertion_sort(a, begin, end);
186 stack[stack_ptr] = begin;
187 stack[stack_ptr + 1] = end;
188 stack[stack_ptr + 2] = 2 * floor(log2(n));
189 stack_ptr = stack_ptr + 3;
191 while (stack_ptr > 0) {
192 stack_ptr = stack_ptr - 3;
193 current_begin = stack[stack_ptr];
194 current_end = stack[stack_ptr + 1];
195 depth_limit = stack[stack_ptr + 2];
197 current_n = current_end - current_begin;
199 if (current_n < INSERTION_SORT_THRESHOLD) {
200 ___stdlib_algorithms_insertion_sort(a, current_begin, current_end);
201 } else if (depth_limit == 0) {
202 ___stdlib_algorithms_heapsort(a, current_begin, current_end);
204 p_high = current_end - 1;
205 ___stdlib_algorithms_median_of_three(a, current_begin, p_high);
206 pivot_idx = ___stdlib_algorithms_partition(a, current_begin, p_high);
208 stack[stack_ptr] = pivot_idx + 1;
209 stack[stack_ptr + 1] = current_end;
210 stack[stack_ptr + 2] = depth_limit - 1;
211 stack_ptr = stack_ptr + 3;
213 stack[stack_ptr] = current_begin;
214 stack[stack_ptr + 1] = pivot_idx;
215 stack[stack_ptr + 2] = depth_limit - 1;
216 stack_ptr = stack_ptr + 3;
222function ___stdlib_algorithms_reverse(Array a, Value begin, Value end) {
225 while (left < right) {
226 ___stdlib_algorithms_swap(a, left, right);
232@define ___STDLIB_ALGORITHMS_CALC_LEN(b, e) ((e) - (b))
233@define ___STDLIB_ALGORITHMS_USE_SLOW_IMPL(begin, end) (!is_consteval(___STDLIB_ALGORITHMS_CALC_LEN(begin, end)) && defined(__EXPR__))
234@define ___stdlib_algorithms_find_kth_smallest(a, begin, end, k) (___STDLIB_ALGORITHMS_USE_SLOW_IMPL(begin, end) ? ___stdlib_algorithms_find_kth_smallest_slow(a, begin, end, k) : ___stdlib_algorithms_find_kth_smallest_fast(a, begin, end, ___STDLIB_ALGORITHMS_CALC_LEN(begin, end), k))