mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
std.sort: add pdqsort and heapsort
This commit is contained in:
parent
bfe02ff61a
commit
3db3cf7790
37 changed files with 1797 additions and 1386 deletions
|
|
@ -93,7 +93,7 @@ pub const HuffmanEncoder = struct {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.lfs = list;
|
self.lfs = list;
|
||||||
sort.sort(LiteralNode, self.lfs, {}, byFreq);
|
mem.sort(LiteralNode, self.lfs, {}, byFreq);
|
||||||
|
|
||||||
// Get the number of literals for each bit count
|
// Get the number of literals for each bit count
|
||||||
var bit_count = self.bitCounts(list, max_bits);
|
var bit_count = self.bitCounts(list, max_bits);
|
||||||
|
|
@ -270,7 +270,7 @@ pub const HuffmanEncoder = struct {
|
||||||
var chunk = list[list.len - @intCast(u32, bits) ..];
|
var chunk = list[list.len - @intCast(u32, bits) ..];
|
||||||
|
|
||||||
self.lns = chunk;
|
self.lns = chunk;
|
||||||
sort.sort(LiteralNode, self.lns, {}, byLiteral);
|
mem.sort(LiteralNode, self.lns, {}, byLiteral);
|
||||||
|
|
||||||
for (chunk) |node| {
|
for (chunk) |node| {
|
||||||
self.codes[node.literal] = HuffCode{
|
self.codes[node.literal] = HuffCode{
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ fn buildFseTable(values: []const u16, entries: []Table.Fse) !void {
|
||||||
position &= entries.len - 1;
|
position &= entries.len - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std.sort.sort(u16, temp_states[0..probability], {}, std.sort.asc(u16));
|
std.mem.sort(u16, temp_states[0..probability], {}, std.sort.asc(u16));
|
||||||
for (0..probability) |i| {
|
for (0..probability) |i| {
|
||||||
entries[temp_states[i]] = if (i < double_state_count) Table.Fse{
|
entries[temp_states[i]] = if (i < double_state_count) Table.Fse{
|
||||||
.symbol = @intCast(u8, symbol),
|
.symbol = @intCast(u8, symbol),
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ fn assignSymbols(weight_sorted_prefixed_symbols: []LiteralsSection.HuffmanTree.P
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
std.sort.sort(
|
std.mem.sort(
|
||||||
LiteralsSection.HuffmanTree.PrefixedSymbol,
|
LiteralsSection.HuffmanTree.PrefixedSymbol,
|
||||||
weight_sorted_prefixed_symbols,
|
weight_sorted_prefixed_symbols,
|
||||||
weights,
|
weights,
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ pub fn ComptimeStringMap(comptime V: type, comptime kvs_list: anytype) type {
|
||||||
sorted_kvs[i] = .{ .key = kv.@"0", .value = {} };
|
sorted_kvs[i] = .{ .key = kv.@"0", .value = {} };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std.sort.sort(KV, &sorted_kvs, {}, lenAsc);
|
mem.sort(KV, &sorted_kvs, {}, lenAsc);
|
||||||
const min_len = sorted_kvs[0].key.len;
|
const min_len = sorted_kvs[0].key.len;
|
||||||
const max_len = sorted_kvs[sorted_kvs.len - 1].key.len;
|
const max_len = sorted_kvs[sorted_kvs.len - 1].key.len;
|
||||||
var len_indexes: [max_len + 1]usize = undefined;
|
var len_indexes: [max_len + 1]usize = undefined;
|
||||||
|
|
|
||||||
|
|
@ -1211,7 +1211,7 @@ fn readMachODebugInfo(allocator: mem.Allocator, macho_file: File) !ModuleDebugIn
|
||||||
// Even though lld emits symbols in ascending order, this debug code
|
// Even though lld emits symbols in ascending order, this debug code
|
||||||
// should work for programs linked in any valid way.
|
// should work for programs linked in any valid way.
|
||||||
// This sort is so that we can binary search later.
|
// This sort is so that we can binary search later.
|
||||||
std.sort.sort(MachoSymbol, symbols, {}, MachoSymbol.addressLessThan);
|
mem.sort(MachoSymbol, symbols, {}, MachoSymbol.addressLessThan);
|
||||||
|
|
||||||
return ModuleDebugInfo{
|
return ModuleDebugInfo{
|
||||||
.base_address = undefined,
|
.base_address = undefined,
|
||||||
|
|
|
||||||
|
|
@ -1314,7 +1314,7 @@ pub fn EnumIndexer(comptime E: type) type {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
std.sort.sort(EnumField, &fields, {}, ascByValue);
|
std.mem.sort(EnumField, &fields, {}, ascByValue);
|
||||||
const min = fields[0].value;
|
const min = fields[0].value;
|
||||||
const max = fields[fields.len - 1].value;
|
const max = fields[fields.len - 1].value;
|
||||||
const fields_len = fields.len;
|
const fields_len = fields.len;
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ pub const Headers = struct {
|
||||||
|
|
||||||
/// Sorts the headers in lexicographical order.
|
/// Sorts the headers in lexicographical order.
|
||||||
pub fn sort(headers: *Headers) void {
|
pub fn sort(headers: *Headers) void {
|
||||||
std.sort.sort(Field, headers.list.items, {}, Field.lessThan);
|
std.mem.sort(Field, headers.list.items, {}, Field.lessThan);
|
||||||
headers.rebuildIndex();
|
headers.rebuildIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -566,6 +566,34 @@ test "zeroInit" {
|
||||||
}, nested_baz);
|
}, nested_baz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sort(
|
||||||
|
comptime T: type,
|
||||||
|
items: []T,
|
||||||
|
context: anytype,
|
||||||
|
comptime lessThanFn: fn (@TypeOf(context), lhs: T, rhs: T) bool,
|
||||||
|
) void {
|
||||||
|
std.sort.block(T, items, context, lessThanFn);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sortUnstable(
|
||||||
|
comptime T: type,
|
||||||
|
items: []T,
|
||||||
|
context: anytype,
|
||||||
|
comptime lessThanFn: fn (@TypeOf(context), lhs: T, rhs: T) bool,
|
||||||
|
) void {
|
||||||
|
std.sort.pdq(T, items, context, lessThanFn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO: currently this just calls `insertionSortContext`. The block sort implementation
|
||||||
|
/// in this file needs to be adapted to use the sort context.
|
||||||
|
pub fn sortContext(a: usize, b: usize, context: anytype) void {
|
||||||
|
std.sort.insertionContext(a, b, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sortUnstableContext(a: usize, b: usize, context: anytype) void {
|
||||||
|
std.sort.pdqContext(a, b, context);
|
||||||
|
}
|
||||||
|
|
||||||
/// Compares two slices of numbers lexicographically. O(n).
|
/// Compares two slices of numbers lexicographically. O(n).
|
||||||
pub fn order(comptime T: type, lhs: []const T, rhs: []const T) math.Order {
|
pub fn order(comptime T: type, lhs: []const T, rhs: []const T) math.Order {
|
||||||
const n = math.min(lhs.len, rhs.len);
|
const n = math.min(lhs.len, rhs.len);
|
||||||
|
|
|
||||||
|
|
@ -985,7 +985,7 @@ pub fn declList(comptime Namespace: type, comptime Decl: type) []const *const De
|
||||||
for (decls, 0..) |decl, i| {
|
for (decls, 0..) |decl, i| {
|
||||||
array[i] = &@field(Namespace, decl.name);
|
array[i] = &@field(Namespace, decl.name);
|
||||||
}
|
}
|
||||||
std.sort.sort(*const Decl, &array, {}, S.declNameLessThan);
|
mem.sort(*const Decl, &array, {}, S.declNameLessThan);
|
||||||
return &array;
|
return &array;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ pub fn MultiArrayList(comptime T: type) type {
|
||||||
return lhs.alignment > rhs.alignment;
|
return lhs.alignment > rhs.alignment;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
std.sort.sort(Data, &data, {}, Sort.lessThan);
|
mem.sort(Data, &data, {}, Sort.lessThan);
|
||||||
var sizes_bytes: [fields.len]usize = undefined;
|
var sizes_bytes: [fields.len]usize = undefined;
|
||||||
var field_indexes: [fields.len]usize = undefined;
|
var field_indexes: [fields.len]usize = undefined;
|
||||||
for (data, 0..) |elem, i| {
|
for (data, 0..) |elem, i| {
|
||||||
|
|
@ -488,10 +488,7 @@ pub fn MultiArrayList(comptime T: type) type {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std.sort.sortContext(self.len, SortContext{
|
mem.sortContext(0, self.len, SortContext{ .sub_ctx = ctx, .slice = self.slice() });
|
||||||
.sub_ctx = ctx,
|
|
||||||
.slice = self.slice(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn capacityInBytes(capacity: usize) usize {
|
fn capacityInBytes(capacity: usize) usize {
|
||||||
|
|
|
||||||
|
|
@ -1082,7 +1082,7 @@ fn linuxLookupName(
|
||||||
key |= (MAXADDRS - @intCast(i32, i)) << DAS_ORDER_SHIFT;
|
key |= (MAXADDRS - @intCast(i32, i)) << DAS_ORDER_SHIFT;
|
||||||
addr.sortkey = key;
|
addr.sortkey = key;
|
||||||
}
|
}
|
||||||
std.sort.sort(LookupAddr, addrs.items, {}, addrCmpLessThan);
|
mem.sort(LookupAddr, addrs.items, {}, addrCmpLessThan);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Policy = struct {
|
const Policy = struct {
|
||||||
|
|
|
||||||
1661
lib/std/sort.zig
1661
lib/std/sort.zig
File diff suppressed because it is too large
Load diff
1066
lib/std/sort/block.zig
Normal file
1066
lib/std/sort/block.zig
Normal file
File diff suppressed because it is too large
Load diff
331
lib/std/sort/pdq.zig
Normal file
331
lib/std/sort/pdq.zig
Normal file
|
|
@ -0,0 +1,331 @@
|
||||||
|
const std = @import("../std.zig");
|
||||||
|
const sort = std.sort;
|
||||||
|
const mem = std.mem;
|
||||||
|
const math = std.math;
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
/// Unstable in-place sort. n best case, n*log(n) worst case and average case.
|
||||||
|
/// log(n) memory (no allocator required).
|
||||||
|
///
|
||||||
|
/// Sorts in ascending order with respect to the given `lessThan` function.
|
||||||
|
pub fn pdq(
|
||||||
|
comptime T: type,
|
||||||
|
items: []T,
|
||||||
|
context: anytype,
|
||||||
|
comptime lessThanFn: fn (context: @TypeOf(context), lhs: T, rhs: T) bool,
|
||||||
|
) void {
|
||||||
|
const Context = struct {
|
||||||
|
items: []T,
|
||||||
|
sub_ctx: @TypeOf(context),
|
||||||
|
|
||||||
|
pub fn lessThan(ctx: @This(), a: usize, b: usize) bool {
|
||||||
|
return lessThanFn(ctx.sub_ctx, ctx.items[a], ctx.items[b]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn swap(ctx: @This(), a: usize, b: usize) void {
|
||||||
|
return mem.swap(T, &ctx.items[a], &ctx.items[b]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
pdqContext(0, items.len, Context{ .items = items, .sub_ctx = context });
|
||||||
|
}
|
||||||
|
|
||||||
|
const Hint = enum {
|
||||||
|
increasing,
|
||||||
|
decreasing,
|
||||||
|
unknown,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Unstable in-place sort. O(n) best case, O(n*log(n)) worst case and average case.
|
||||||
|
/// O(log(n)) memory (no allocator required).
|
||||||
|
///
|
||||||
|
/// Sorts in ascending order with respect to the given `lessThan` function.
|
||||||
|
pub fn pdqContext(a: usize, b: usize, context: anytype) void {
|
||||||
|
// slices of up to this length get sorted using insertion sort.
|
||||||
|
const max_insertion = 24;
|
||||||
|
// number of allowed imbalanced partitions before switching to heap sort.
|
||||||
|
const max_limit = std.math.floorPowerOfTwo(usize, b) + 1;
|
||||||
|
|
||||||
|
// set upper bound on stack memory usage.
|
||||||
|
const Range = struct { a: usize, b: usize, limit: usize };
|
||||||
|
const stack_size = math.log2(math.maxInt(usize) + 1);
|
||||||
|
var stack: [stack_size]Range = undefined;
|
||||||
|
var range = Range{ .a = a, .b = b, .limit = max_limit };
|
||||||
|
var top: usize = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
var was_balanced = true;
|
||||||
|
var was_partitioned = true;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const len = range.b - range.a;
|
||||||
|
|
||||||
|
// very short slices get sorted using insertion sort.
|
||||||
|
if (len <= max_insertion) {
|
||||||
|
break sort.insertionContext(range.a, range.b, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if too many bad pivot choices were made, simply fall back to heapsort in order to
|
||||||
|
// guarantee O(n*log(n)) worst-case.
|
||||||
|
if (range.limit == 0) {
|
||||||
|
break sort.heapContext(range.a, range.b, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the last partitioning was imbalanced, try breaking patterns in the slice by shuffling
|
||||||
|
// some elements around. Hopefully we'll choose a better pivot this time.
|
||||||
|
if (!was_balanced) {
|
||||||
|
breakPatterns(range.a, range.b, context);
|
||||||
|
range.limit -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// choose a pivot and try guessing whether the slice is already sorted.
|
||||||
|
var pivot: usize = 0;
|
||||||
|
var hint = chosePivot(range.a, range.b, &pivot, context);
|
||||||
|
|
||||||
|
if (hint == .decreasing) {
|
||||||
|
// The maximum number of swaps was performed, so items are likely
|
||||||
|
// in reverse order. Reverse it to make sorting faster.
|
||||||
|
reverseRange(range.a, range.b, context);
|
||||||
|
pivot = (range.b - 1) - (pivot - range.a);
|
||||||
|
hint = .increasing;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the last partitioning was decently balanced and didn't shuffle elements, and if pivot
|
||||||
|
// selection predicts the slice is likely already sorted...
|
||||||
|
if (was_balanced and was_partitioned and hint == .increasing) {
|
||||||
|
// try identifying several out-of-order elements and shifting them to correct
|
||||||
|
// positions. If the slice ends up being completely sorted, we're done.
|
||||||
|
if (partialInsertionSort(range.a, range.b, context)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the chosen pivot is equal to the predecessor, then it's the smallest element in the
|
||||||
|
// slice. Partition the slice into elements equal to and elements greater than the pivot.
|
||||||
|
// This case is usually hit when the slice contains many duplicate elements.
|
||||||
|
if (range.a > 0 and !context.lessThan(range.a - 1, pivot)) {
|
||||||
|
range.a = partitionEqual(range.a, range.b, pivot, context);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// partition the slice.
|
||||||
|
var mid = pivot;
|
||||||
|
was_partitioned = partition(range.a, range.b, &mid, context);
|
||||||
|
|
||||||
|
const left_len = mid - range.a;
|
||||||
|
const right_len = range.b - mid;
|
||||||
|
const balanced_threshold = len / 8;
|
||||||
|
if (left_len < right_len) {
|
||||||
|
was_balanced = left_len >= balanced_threshold;
|
||||||
|
stack[top] = .{ .a = range.a, .b = mid, .limit = range.limit };
|
||||||
|
top += 1;
|
||||||
|
range.a = mid + 1;
|
||||||
|
} else {
|
||||||
|
was_balanced = right_len >= balanced_threshold;
|
||||||
|
stack[top] = .{ .a = mid + 1, .b = range.b, .limit = range.limit };
|
||||||
|
top += 1;
|
||||||
|
range.b = mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
top = math.sub(usize, top, 1) catch break;
|
||||||
|
range = stack[top];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// partitions `items[a..b]` into elements smaller than `items[pivot]`,
|
||||||
|
/// followed by elements greater than or equal to `items[pivot]`.
|
||||||
|
///
|
||||||
|
/// sets the new pivot.
|
||||||
|
/// returns `true` if already partitioned.
|
||||||
|
fn partition(a: usize, b: usize, pivot: *usize, context: anytype) bool {
|
||||||
|
// move pivot to the first place
|
||||||
|
context.swap(a, pivot.*);
|
||||||
|
|
||||||
|
var i = a + 1;
|
||||||
|
var j = b - 1;
|
||||||
|
|
||||||
|
while (i <= j and context.lessThan(i, a)) i += 1;
|
||||||
|
while (i <= j and !context.lessThan(j, a)) j -= 1;
|
||||||
|
|
||||||
|
// check if items are already partitioned (no item to swap)
|
||||||
|
if (i > j) {
|
||||||
|
// put pivot back to the middle
|
||||||
|
context.swap(j, a);
|
||||||
|
pivot.* = j;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.swap(i, j);
|
||||||
|
i += 1;
|
||||||
|
j -= 1;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
while (i <= j and context.lessThan(i, a)) i += 1;
|
||||||
|
while (i <= j and !context.lessThan(j, a)) j -= 1;
|
||||||
|
if (i > j) break;
|
||||||
|
|
||||||
|
context.swap(i, j);
|
||||||
|
i += 1;
|
||||||
|
j -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Enable the BlockQuicksort optimization
|
||||||
|
|
||||||
|
context.swap(j, a);
|
||||||
|
pivot.* = j;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// partitions items into elements equal to `items[pivot]`
|
||||||
|
/// followed by elements greater than `items[pivot]`.
|
||||||
|
///
|
||||||
|
/// it assumed that `items[a..b]` does not contain elements smaller than the `items[pivot]`.
|
||||||
|
fn partitionEqual(a: usize, b: usize, pivot: usize, context: anytype) usize {
|
||||||
|
// move pivot to the first place
|
||||||
|
context.swap(a, pivot);
|
||||||
|
|
||||||
|
var i = a + 1;
|
||||||
|
var j = b - 1;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
while (i <= j and !context.lessThan(a, i)) i += 1;
|
||||||
|
while (i <= j and context.lessThan(a, j)) j -= 1;
|
||||||
|
if (i > j) break;
|
||||||
|
|
||||||
|
context.swap(i, j);
|
||||||
|
i += 1;
|
||||||
|
j -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// partially sorts a slice by shifting several out-of-order elements around.
|
||||||
|
///
|
||||||
|
/// returns `true` if the slice is sorted at the end. This function is `O(n)` worst-case.
|
||||||
|
fn partialInsertionSort(a: usize, b: usize, context: anytype) bool {
|
||||||
|
@setCold(true);
|
||||||
|
|
||||||
|
// maximum number of adjacent out-of-order pairs that will get shifted
|
||||||
|
const max_steps = 5;
|
||||||
|
// if the slice is shorter than this, don't shift any elements
|
||||||
|
const shortest_shifting = 50;
|
||||||
|
|
||||||
|
var i = a + 1;
|
||||||
|
for (0..max_steps) |_| {
|
||||||
|
// find the next pair of adjacent out-of-order elements.
|
||||||
|
while (i < b and !context.lessThan(i, i - 1)) i += 1;
|
||||||
|
|
||||||
|
// are we done?
|
||||||
|
if (i == b) return true;
|
||||||
|
|
||||||
|
// don't shift elements on short arrays, that has a performance cost.
|
||||||
|
if (b - a < shortest_shifting) return false;
|
||||||
|
|
||||||
|
// swap the found pair of elements. This puts them in correct order.
|
||||||
|
context.swap(i, i - 1);
|
||||||
|
|
||||||
|
// shift the smaller element to the left.
|
||||||
|
if (i - a >= 2) {
|
||||||
|
var j = i - 1;
|
||||||
|
while (j >= 1) : (j -= 1) {
|
||||||
|
if (!context.lessThan(j, j - 1)) break;
|
||||||
|
context.swap(j, j - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// shift the greater element to the right.
|
||||||
|
if (b - i >= 2) {
|
||||||
|
var j = i + 1;
|
||||||
|
while (j < b) : (j += 1) {
|
||||||
|
if (!context.lessThan(j, j - 1)) break;
|
||||||
|
context.swap(j, j - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn breakPatterns(a: usize, b: usize, context: anytype) void {
|
||||||
|
@setCold(true);
|
||||||
|
|
||||||
|
const len = b - a;
|
||||||
|
if (len < 8) return;
|
||||||
|
|
||||||
|
var rand = @intCast(u64, len);
|
||||||
|
const modulus = math.ceilPowerOfTwoAssert(u64, len);
|
||||||
|
|
||||||
|
var i = a + (len / 4) * 2 - 1;
|
||||||
|
while (i <= a + (len / 4) * 2 + 1) : (i += 1) {
|
||||||
|
// xorshift64
|
||||||
|
rand ^= rand << 13;
|
||||||
|
rand ^= rand >> 7;
|
||||||
|
rand ^= rand << 17;
|
||||||
|
|
||||||
|
var other = @intCast(usize, rand & (modulus - 1));
|
||||||
|
if (other >= len) other -= len;
|
||||||
|
context.swap(i, a + other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// choses a pivot in `items[a..b]`.
|
||||||
|
/// swaps likely_sorted when `items[a..b]` seems to be already sorted.
|
||||||
|
fn chosePivot(a: usize, b: usize, pivot: *usize, context: anytype) Hint {
|
||||||
|
// minimum length for using the Tukey's ninther method
|
||||||
|
const shortest_ninther = 50;
|
||||||
|
// max_swaps is the maximum number of swaps allowed in this function
|
||||||
|
const max_swaps = 4 * 3;
|
||||||
|
|
||||||
|
var len = b - a;
|
||||||
|
var i = a + len / 4 * 1;
|
||||||
|
var j = a + len / 4 * 2;
|
||||||
|
var k = a + len / 4 * 3;
|
||||||
|
var swaps: usize = 0;
|
||||||
|
|
||||||
|
if (len >= 8) {
|
||||||
|
if (len >= shortest_ninther) {
|
||||||
|
// find medians in the neighborhoods of `i`, `j` and `k`
|
||||||
|
i = sort3(i - 1, i, i + 1, &swaps, context);
|
||||||
|
j = sort3(j - 1, j, j + 1, &swaps, context);
|
||||||
|
k = sort3(k - 1, k, k + 1, &swaps, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the median among `i`, `j` and `k`
|
||||||
|
j = sort3(i, j, k, &swaps, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
pivot.* = j;
|
||||||
|
return switch (swaps) {
|
||||||
|
0 => .increasing,
|
||||||
|
max_swaps => .decreasing,
|
||||||
|
else => .unknown,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sort3(a: usize, b: usize, c: usize, swaps: *usize, context: anytype) usize {
|
||||||
|
if (context.lessThan(b, a)) {
|
||||||
|
swaps.* += 1;
|
||||||
|
context.swap(b, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.lessThan(c, b)) {
|
||||||
|
swaps.* += 1;
|
||||||
|
context.swap(c, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.lessThan(b, a)) {
|
||||||
|
swaps.* += 1;
|
||||||
|
context.swap(b, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reverseRange(a: usize, b: usize, context: anytype) void {
|
||||||
|
var i = a;
|
||||||
|
var j = b - 1;
|
||||||
|
while (i < j) {
|
||||||
|
context.swap(i, j);
|
||||||
|
i += 1;
|
||||||
|
j -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -672,7 +672,7 @@ fn addPackageTableToCacheHash(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Sort the slice by package name
|
// Sort the slice by package name
|
||||||
std.sort.sort(Package.Table.KV, packages, {}, struct {
|
mem.sort(Package.Table.KV, packages, {}, struct {
|
||||||
fn lessThan(_: void, lhs: Package.Table.KV, rhs: Package.Table.KV) bool {
|
fn lessThan(_: void, lhs: Package.Table.KV, rhs: Package.Table.KV) bool {
|
||||||
return std.mem.lessThan(u8, lhs.key, rhs.key);
|
return std.mem.lessThan(u8, lhs.key, rhs.key);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -672,7 +672,7 @@ fn computePackageHash(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std.sort.sort(*HashedFile, all_files.items, {}, HashedFile.lessThan);
|
mem.sort(*HashedFile, all_files.items, {}, HashedFile.lessThan);
|
||||||
|
|
||||||
var hasher = Manifest.Hash.init(.{});
|
var hasher = Manifest.Hash.init(.{});
|
||||||
var any_failures = false;
|
var any_failures = false;
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
|
||||||
if (self.ranges.items.len == 0)
|
if (self.ranges.items.len == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std.sort.sort(Range, self.ranges.items, LessThanContext{
|
std.mem.sort(Range, self.ranges.items, LessThanContext{
|
||||||
.ty = ty,
|
.ty = ty,
|
||||||
.module = self.module,
|
.module = self.module,
|
||||||
}, lessThan);
|
}, lessThan);
|
||||||
|
|
|
||||||
|
|
@ -30979,7 +30979,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
|
||||||
ctx.struct_obj.fields.values()[b].ty.abiAlignment(target);
|
ctx.struct_obj.fields.values()[b].ty.abiAlignment(target);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
std.sort.sort(u32, optimized_order, AlignSortContext{
|
mem.sort(u32, optimized_order, AlignSortContext{
|
||||||
.struct_obj = struct_obj,
|
.struct_obj = struct_obj,
|
||||||
.sema = sema,
|
.sema = sema,
|
||||||
}, AlignSortContext.lessThan);
|
}, AlignSortContext.lessThan);
|
||||||
|
|
|
||||||
|
|
@ -2176,7 +2176,7 @@ fn computeFrameLayout(self: *Self) !FrameLayout {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const sort_context = SortContext{ .frame_align = frame_align };
|
const sort_context = SortContext{ .frame_align = frame_align };
|
||||||
std.sort.sort(FrameIndex, stack_frame_order, sort_context, SortContext.lessThan);
|
mem.sort(FrameIndex, stack_frame_order, sort_context, SortContext.lessThan);
|
||||||
}
|
}
|
||||||
|
|
||||||
const call_frame_align = frame_align[@enumToInt(FrameIndex.call_frame)];
|
const call_frame_align = frame_align[@enumToInt(FrameIndex.call_frame)];
|
||||||
|
|
|
||||||
|
|
@ -770,7 +770,7 @@ const mnemonic_to_encodings_map = init: {
|
||||||
@setEvalBranchQuota(30_000);
|
@setEvalBranchQuota(30_000);
|
||||||
const encodings = @import("encodings.zig");
|
const encodings = @import("encodings.zig");
|
||||||
var entries = encodings.table;
|
var entries = encodings.table;
|
||||||
std.sort.sort(encodings.Entry, &entries, {}, struct {
|
std.mem.sort(encodings.Entry, &entries, {}, struct {
|
||||||
fn lessThan(_: void, lhs: encodings.Entry, rhs: encodings.Entry) bool {
|
fn lessThan(_: void, lhs: encodings.Entry, rhs: encodings.Entry) bool {
|
||||||
return @enumToInt(lhs[0]) < @enumToInt(rhs[0]);
|
return @enumToInt(lhs[0]) < @enumToInt(rhs[0]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1292,7 +1292,7 @@ pub const CType = extern union {
|
||||||
fn sortFields(self: *@This(), fields_len: usize) []Payload.Fields.Field {
|
fn sortFields(self: *@This(), fields_len: usize) []Payload.Fields.Field {
|
||||||
const Field = Payload.Fields.Field;
|
const Field = Payload.Fields.Field;
|
||||||
const slice = self.storage.anon.fields[0..fields_len];
|
const slice = self.storage.anon.fields[0..fields_len];
|
||||||
std.sort.sort(Field, slice, {}, struct {
|
mem.sort(Field, slice, {}, struct {
|
||||||
fn before(_: void, lhs: Field, rhs: Field) bool {
|
fn before(_: void, lhs: Field, rhs: Field) bool {
|
||||||
return lhs.alignas.@"align" > rhs.alignas.@"align";
|
return lhs.alignas.@"align" > rhs.alignas.@"align";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1837,7 +1837,7 @@ fn writeBaseRelocations(self: *Coff) !void {
|
||||||
pages.appendAssumeCapacity(page.*);
|
pages.appendAssumeCapacity(page.*);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std.sort.sort(u32, pages.items, {}, std.sort.asc(u32));
|
mem.sort(u32, pages.items, {}, std.sort.asc(u32));
|
||||||
|
|
||||||
var buffer = std.ArrayList(u8).init(gpa);
|
var buffer = std.ArrayList(u8).init(gpa);
|
||||||
defer buffer.deinit();
|
defer buffer.deinit();
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch)
|
||||||
// afterwards by address in each group. Normally, dysymtab should
|
// afterwards by address in each group. Normally, dysymtab should
|
||||||
// be enough to guarantee the sort, but turns out not every compiler
|
// be enough to guarantee the sort, but turns out not every compiler
|
||||||
// is kind enough to specify the symbols in the correct order.
|
// is kind enough to specify the symbols in the correct order.
|
||||||
sort.sort(SymbolAtIndex, sorted_all_syms.items, self, SymbolAtIndex.lessThan);
|
mem.sort(SymbolAtIndex, sorted_all_syms.items, self, SymbolAtIndex.lessThan);
|
||||||
|
|
||||||
var prev_sect_id: u8 = 0;
|
var prev_sect_id: u8 = 0;
|
||||||
var section_index_lookup: ?Entry = null;
|
var section_index_lookup: ?Entry = null;
|
||||||
|
|
@ -462,7 +462,7 @@ pub fn splitRegularSections(self: *Object, zld: *Zld, object_id: u32) !void {
|
||||||
sorted_sections[id] = .{ .header = sect, .id = @intCast(u8, id) };
|
sorted_sections[id] = .{ .header = sect, .id = @intCast(u8, id) };
|
||||||
}
|
}
|
||||||
|
|
||||||
std.sort.sort(SortedSection, sorted_sections, {}, sectionLessThanByAddress);
|
mem.sort(SortedSection, sorted_sections, {}, sectionLessThanByAddress);
|
||||||
|
|
||||||
var sect_sym_index: u32 = 0;
|
var sect_sym_index: u32 = 0;
|
||||||
for (sorted_sections) |section| {
|
for (sorted_sections) |section| {
|
||||||
|
|
@ -663,7 +663,7 @@ fn parseRelocs(self: *Object, gpa: Allocator, sect_id: u8) !void {
|
||||||
if (self.getSourceRelocs(section)) |relocs| {
|
if (self.getSourceRelocs(section)) |relocs| {
|
||||||
try self.relocations.ensureUnusedCapacity(gpa, relocs.len);
|
try self.relocations.ensureUnusedCapacity(gpa, relocs.len);
|
||||||
self.relocations.appendUnalignedSliceAssumeCapacity(relocs);
|
self.relocations.appendUnalignedSliceAssumeCapacity(relocs);
|
||||||
std.sort.sort(macho.relocation_info, self.relocations.items[start..], {}, relocGreaterThan);
|
mem.sort(macho.relocation_info, self.relocations.items[start..], {}, relocGreaterThan);
|
||||||
}
|
}
|
||||||
self.section_relocs_lookup.items[sect_id] = start;
|
self.section_relocs_lookup.items[sect_id] = start;
|
||||||
}
|
}
|
||||||
|
|
@ -901,7 +901,7 @@ pub fn parseDataInCode(self: *Object, gpa: Allocator) !void {
|
||||||
const dice = @ptrCast([*]align(1) const macho.data_in_code_entry, self.contents.ptr + cmd.dataoff)[0..ndice];
|
const dice = @ptrCast([*]align(1) const macho.data_in_code_entry, self.contents.ptr + cmd.dataoff)[0..ndice];
|
||||||
try self.data_in_code.ensureTotalCapacityPrecise(gpa, dice.len);
|
try self.data_in_code.ensureTotalCapacityPrecise(gpa, dice.len);
|
||||||
self.data_in_code.appendUnalignedSliceAssumeCapacity(dice);
|
self.data_in_code.appendUnalignedSliceAssumeCapacity(dice);
|
||||||
std.sort.sort(macho.data_in_code_entry, self.data_in_code.items, {}, diceLessThan);
|
mem.sort(macho.data_in_code_entry, self.data_in_code.items, {}, diceLessThan);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn diceLessThan(ctx: void, lhs: macho.data_in_code_entry, rhs: macho.data_in_code_entry) bool {
|
fn diceLessThan(ctx: void, lhs: macho.data_in_code_entry, rhs: macho.data_in_code_entry) bool {
|
||||||
|
|
|
||||||
|
|
@ -411,7 +411,7 @@ pub fn collect(info: *UnwindInfo, zld: *Zld) !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
var slice = common_encodings_counts.values();
|
var slice = common_encodings_counts.values();
|
||||||
std.sort.sort(CommonEncWithCount, slice, {}, CommonEncWithCount.greaterThan);
|
mem.sort(CommonEncWithCount, slice, {}, CommonEncWithCount.greaterThan);
|
||||||
|
|
||||||
var i: u7 = 0;
|
var i: u7 = 0;
|
||||||
while (i < slice.len) : (i += 1) {
|
while (i < slice.len) : (i += 1) {
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ pub fn finalize(rebase: *Rebase, gpa: Allocator) !void {
|
||||||
|
|
||||||
const writer = rebase.buffer.writer(gpa);
|
const writer = rebase.buffer.writer(gpa);
|
||||||
|
|
||||||
std.sort.sort(Entry, rebase.entries.items, {}, Entry.lessThan);
|
std.mem.sort(Entry, rebase.entries.items, {}, Entry.lessThan);
|
||||||
|
|
||||||
try setTypePointer(writer);
|
try setTypePointer(writer);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ pub fn Bind(comptime Ctx: type, comptime Target: type) type {
|
||||||
|
|
||||||
const writer = self.buffer.writer(gpa);
|
const writer = self.buffer.writer(gpa);
|
||||||
|
|
||||||
std.sort.sort(Entry, self.entries.items, ctx, Entry.lessThan);
|
std.mem.sort(Entry, self.entries.items, ctx, Entry.lessThan);
|
||||||
|
|
||||||
var start: usize = 0;
|
var start: usize = 0;
|
||||||
var seg_id: ?u8 = null;
|
var seg_id: ?u8 = null;
|
||||||
|
|
|
||||||
|
|
@ -1441,7 +1441,7 @@ pub const Zld = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std.sort.sort(Section, sections.items, {}, SortSection.lessThan);
|
mem.sort(Section, sections.items, {}, SortSection.lessThan);
|
||||||
|
|
||||||
self.sections.shrinkRetainingCapacity(0);
|
self.sections.shrinkRetainingCapacity(0);
|
||||||
for (sections.items) |out| {
|
for (sections.items) |out| {
|
||||||
|
|
@ -2237,7 +2237,7 @@ pub const Zld = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std.sort.sort(u64, addresses.items, {}, asc_u64);
|
mem.sort(u64, addresses.items, {}, asc_u64);
|
||||||
|
|
||||||
var offsets = std.ArrayList(u32).init(gpa);
|
var offsets = std.ArrayList(u32).init(gpa);
|
||||||
defer offsets.deinit();
|
defer offsets.deinit();
|
||||||
|
|
|
||||||
|
|
@ -2143,7 +2143,7 @@ fn sortDataSegments(wasm: *Wasm) !void {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std.sort.sort([]const u8, keys, {}, SortContext.sort);
|
mem.sort([]const u8, keys, {}, SortContext.sort);
|
||||||
for (keys) |key| {
|
for (keys) |key| {
|
||||||
const segment_index = wasm.data_segments.get(key).?;
|
const segment_index = wasm.data_segments.get(key).?;
|
||||||
new_mapping.putAssumeCapacity(key, segment_index);
|
new_mapping.putAssumeCapacity(key, segment_index);
|
||||||
|
|
@ -2187,7 +2187,7 @@ fn setupInitFunctions(wasm: *Wasm) !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort the initfunctions based on their priority
|
// sort the initfunctions based on their priority
|
||||||
std.sort.sort(InitFuncLoc, wasm.init_funcs.items, {}, InitFuncLoc.lessThan);
|
mem.sort(InitFuncLoc, wasm.init_funcs.items, {}, InitFuncLoc.lessThan);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates an atom containing the global error set' size.
|
/// Generates an atom containing the global error set' size.
|
||||||
|
|
@ -3687,7 +3687,7 @@ fn writeToFile(
|
||||||
}
|
}
|
||||||
}.sort;
|
}.sort;
|
||||||
|
|
||||||
std.sort.sort(*Atom, sorted_atoms.items, wasm, atom_sort_fn);
|
mem.sort(*Atom, sorted_atoms.items, wasm, atom_sort_fn);
|
||||||
|
|
||||||
for (sorted_atoms.items) |sorted_atom| {
|
for (sorted_atoms.items) |sorted_atom| {
|
||||||
try leb.writeULEB128(binary_writer, sorted_atom.size);
|
try leb.writeULEB128(binary_writer, sorted_atom.size);
|
||||||
|
|
@ -4050,8 +4050,8 @@ fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), arena: std.mem
|
||||||
data_segment_index += 1;
|
data_segment_index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std.sort.sort(Name, funcs.values(), {}, Name.lessThan);
|
mem.sort(Name, funcs.values(), {}, Name.lessThan);
|
||||||
std.sort.sort(Name, globals.items, {}, Name.lessThan);
|
mem.sort(Name, globals.items, {}, Name.lessThan);
|
||||||
|
|
||||||
const header_offset = try reserveCustomSectionHeader(binary_bytes);
|
const header_offset = try reserveCustomSectionHeader(binary_bytes);
|
||||||
const writer = binary_bytes.writer();
|
const writer = binary_bytes.writer();
|
||||||
|
|
|
||||||
|
|
@ -402,7 +402,7 @@ const BinaryElfOutput = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std.sort.sort(*BinaryElfSegment, self.segments.items, {}, segmentSortCompare);
|
mem.sort(*BinaryElfSegment, self.segments.items, {}, segmentSortCompare);
|
||||||
|
|
||||||
for (self.segments.items, 0..) |firstSegment, i| {
|
for (self.segments.items, 0..) |firstSegment, i| {
|
||||||
if (firstSegment.firstSection) |firstSection| {
|
if (firstSegment.firstSection) |firstSection| {
|
||||||
|
|
@ -427,7 +427,7 @@ const BinaryElfOutput = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std.sort.sort(*BinaryElfSection, self.sections.items, {}, sectionSortCompare);
|
mem.sort(*BinaryElfSection, self.sections.items, {}, sectionSortCompare);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -607,7 +607,7 @@ fn sortTestFilenames(filenames: [][]const u8) void {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
std.sort.sort([]const u8, filenames, Context{}, Context.lessThan);
|
std.mem.sort([]const u8, filenames, Context{}, Context.lessThan);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterates a set of filenames extracting batches that are either incremental
|
/// Iterates a set of filenames extracting batches that are either incremental
|
||||||
|
|
|
||||||
|
|
@ -437,7 +437,7 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: builtin.Endian)
|
||||||
const dynstr = elf_bytes[dynstr_offset..];
|
const dynstr = elf_bytes[dynstr_offset..];
|
||||||
|
|
||||||
// Sort the list by address, ascending.
|
// Sort the list by address, ascending.
|
||||||
std.sort.sort(Sym, @alignCast(8, dyn_syms), {}, S.symbolAddrLessThan);
|
mem.sort(Sym, @alignCast(8, dyn_syms), {}, S.symbolAddrLessThan);
|
||||||
|
|
||||||
for (dyn_syms) |sym| {
|
for (dyn_syms) |sym| {
|
||||||
const this_section = s(sym.st_shndx);
|
const this_section = s(sym.st_shndx);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ pub fn main() !void {
|
||||||
while (try it.next()) |entry| {
|
while (try it.next()) |entry| {
|
||||||
try names.append(try allocator.dupe(u8, entry.name));
|
try names.append(try allocator.dupe(u8, entry.name));
|
||||||
}
|
}
|
||||||
std.sort.sort([]const u8, names.items, {}, (struct {
|
std.mem.sort([]const u8, names.items, {}, (struct {
|
||||||
fn lessThan(_: void, a: []const u8, b: []const u8) bool {
|
fn lessThan(_: void, a: []const u8, b: []const u8) bool {
|
||||||
return std.mem.lessThan(u8, a, b);
|
return std.mem.lessThan(u8, a, b);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -460,7 +460,7 @@ pub fn main() !void {
|
||||||
try contents_list.append(contents);
|
try contents_list.append(contents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std.sort.sort(*Contents, contents_list.items, {}, Contents.hitCountLessThan);
|
std.mem.sort(*Contents, contents_list.items, {}, Contents.hitCountLessThan);
|
||||||
const best_contents = contents_list.popOrNull().?;
|
const best_contents = contents_list.popOrNull().?;
|
||||||
if (best_contents.hit_count > 1) {
|
if (best_contents.hit_count > 1) {
|
||||||
// worth it to make it generic
|
// worth it to make it generic
|
||||||
|
|
|
||||||
|
|
@ -260,7 +260,7 @@ pub fn main() !void {
|
||||||
try contents_list.append(contents);
|
try contents_list.append(contents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std.sort.sort(*Contents, contents_list.items, {}, Contents.hitCountLessThan);
|
std.mem.sort(*Contents, contents_list.items, {}, Contents.hitCountLessThan);
|
||||||
const best_contents = contents_list.popOrNull().?;
|
const best_contents = contents_list.popOrNull().?;
|
||||||
if (best_contents.hit_count > 1) {
|
if (best_contents.hit_count > 1) {
|
||||||
// worth it to make it generic
|
// worth it to make it generic
|
||||||
|
|
|
||||||
|
|
@ -646,7 +646,7 @@ pub fn main() anyerror!void {
|
||||||
}
|
}
|
||||||
// Some options have multiple matches. As an example, "-Wl,foo" matches both
|
// Some options have multiple matches. As an example, "-Wl,foo" matches both
|
||||||
// "W" and "Wl,". So we sort this list in order of descending priority.
|
// "W" and "Wl,". So we sort this list in order of descending priority.
|
||||||
std.sort.sort(*json.ObjectMap, all_objects.items, {}, objectLessThan);
|
std.mem.sort(*json.ObjectMap, all_objects.items, {}, objectLessThan);
|
||||||
|
|
||||||
var buffered_stdout = std.io.bufferedWriter(std.io.getStdOut().writer());
|
var buffered_stdout = std.io.bufferedWriter(std.io.getStdOut().writer());
|
||||||
const stdout = buffered_stdout.writer();
|
const stdout = buffered_stdout.writer();
|
||||||
|
|
|
||||||
|
|
@ -1187,8 +1187,8 @@ fn processOneTarget(job: Job) anyerror!void {
|
||||||
for (llvm_target.extra_cpus) |extra_cpu| {
|
for (llvm_target.extra_cpus) |extra_cpu| {
|
||||||
try all_cpus.append(extra_cpu);
|
try all_cpus.append(extra_cpu);
|
||||||
}
|
}
|
||||||
std.sort.sort(Feature, all_features.items, {}, featureLessThan);
|
mem.sort(Feature, all_features.items, {}, featureLessThan);
|
||||||
std.sort.sort(Cpu, all_cpus.items, {}, cpuLessThan);
|
mem.sort(Cpu, all_cpus.items, {}, cpuLessThan);
|
||||||
|
|
||||||
const target_sub_path = try fs.path.join(arena, &.{ "lib", "std", "target" });
|
const target_sub_path = try fs.path.join(arena, &.{ "lib", "std", "target" });
|
||||||
var target_dir = try job.zig_src_dir.makeOpenPath(target_sub_path, .{});
|
var target_dir = try job.zig_src_dir.makeOpenPath(target_sub_path, .{});
|
||||||
|
|
@ -1283,7 +1283,7 @@ fn processOneTarget(job: Job) anyerror!void {
|
||||||
try dependencies.append(key.*);
|
try dependencies.append(key.*);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std.sort.sort([]const u8, dependencies.items, {}, asciiLessThan);
|
mem.sort([]const u8, dependencies.items, {}, asciiLessThan);
|
||||||
|
|
||||||
if (dependencies.items.len == 0) {
|
if (dependencies.items.len == 0) {
|
||||||
try w.writeAll(
|
try w.writeAll(
|
||||||
|
|
@ -1328,7 +1328,7 @@ fn processOneTarget(job: Job) anyerror!void {
|
||||||
try cpu_features.append(key.*);
|
try cpu_features.append(key.*);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std.sort.sort([]const u8, cpu_features.items, {}, asciiLessThan);
|
mem.sort([]const u8, cpu_features.items, {}, asciiLessThan);
|
||||||
if (cpu.llvm_name) |llvm_name| {
|
if (cpu.llvm_name) |llvm_name| {
|
||||||
try w.print(
|
try w.print(
|
||||||
\\ pub const {} = CpuModel{{
|
\\ pub const {} = CpuModel{{
|
||||||
|
|
|
||||||
|
|
@ -303,7 +303,7 @@ fn gatherVersions(allocator: Allocator, registry: g.CoreRegistry) ![]const Versi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std.sort.sort(Version, versions.items, {}, Version.lessThan);
|
std.mem.sort(Version, versions.items, {}, Version.lessThan);
|
||||||
|
|
||||||
return versions.items;
|
return versions.items;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue