Files
raddebugger/src/linker/base_ext/base_arrays.c
T
2025-06-25 10:53:22 -07:00

237 lines
5.1 KiB
C

// Copyright (c) 2025 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal U64
void_list_count_nodes(VoidNode *head)
{
U64 node_count = 0;
for (VoidNode *curr = head; curr != 0; curr = curr->next) {
++node_count;
}
return node_count;
}
internal void
void_node_concat(VoidNode **head, VoidNode *node)
{
Assert(*head != node);
node->next = *head;
*head = node;
}
internal void
void_node_concat_atomic(VoidNode **head, VoidNode *node)
{
Assert(*head != node);
node->next = ins_atomic_ptr_eval_assign(head, node);
}
internal U64Node *
u64_list_push(Arena *arena, U64List *list, U64 data)
{
U64Node *n = push_array(arena, U64Node, 1);
n->next = 0;
n->data = data;
SLLQueuePush(list->first, list->last, n);
++list->count;
return n;
}
internal void
u64_list_concat_in_place(U64List *list, U64List *to_concat)
{
SLLConcatInPlace(list, to_concat);
}
internal U64Array
u64_array_from_list(Arena *arena, U64List *list)
{
U64Array result;
result.count = 0;
result.v = push_array(arena, U64, list->count);
for (U64Node *n = list->first; n != NULL; n = n->next) {
result.v[result.count++] = n->data;
}
return result;
}
internal void
u32_array_sort(U64 count, U32 *v)
{
radsort(v, count, u32_is_before);
}
internal void
u64_array_sort(U64 count, U64 *v)
{
radsort(v, count, u64_is_before);
}
internal void
u32_pair_radix_sort(U64 count, PairU32 *arr)
{
Temp scratch = scratch_begin(0,0);
PairU32 *temp = push_array(scratch.arena, PairU32, count);
const U64 bit_count0 = 11;
const U64 bit_count1 = 11;
const U64 bit_count2 = 10;
U32 *count0 = push_array(scratch.arena, U32, (1 << bit_count0));
U32 *count1 = push_array(scratch.arena, U32, (1 << bit_count1));
U32 *count2 = push_array(scratch.arena, U32, (1 << bit_count2));
for (U64 i = 0; i < count; ++i) {
U32 digit0 = (arr[i].v0 >> 0 ) % (1 << bit_count0);
U32 digit1 = (arr[i].v0 >> bit_count0) % (1 << bit_count1);
U32 digit2 = (arr[i].v0 >> bit_count1) % (1 << bit_count2);
++count0[digit0];
++count1[digit1];
++count2[digit2];
}
counts_to_offsets_array_u32((1 << bit_count0), count0);
counts_to_offsets_array_u32((1 << bit_count1), count1);
counts_to_offsets_array_u32((1 << bit_count2), count2);
for (U64 i = 0; i < count; ++i) {
U32 digit0 = (arr[i].v0 >> 0) % (1 << bit_count0);
temp[count0[digit0]++] = arr[i];
}
for (U64 i = 0; i < count; ++i) {
U32 digit1 = (temp[i].v0 >> bit_count0) % (1 << bit_count1);
arr[count1[digit1]++] = temp[i];
}
for (U64 i = 0; i < count; ++i) {
U32 digit2 = (arr[i].v0 >> bit_count1) % (1 << bit_count2);
temp[count2[digit2]++] = arr[i];
}
MemoryCopyTyped(arr, temp, count);
scratch_end(scratch);
}
internal B32
u32_array_compare(U32Array a, U32Array b)
{
B32 are_equal = 0;
if (a.count == b.count) {
int cmp = MemoryCompare(a.v, b.v, sizeof(a.v[0]) * a.count);
are_equal = (cmp == 0);
}
return are_equal;
}
internal U64Array
u64_array_remove_duplicates(Arena *arena, U64Array in)
{
U64Array result;
result.count = 0;
result.v = push_array(arena, U64, in.count);
for (U64 i = 1; i < in.count; ++i) {
B32 is_unique = in.v[i - 1] != in.v[i];
if (is_unique) {
result.v[result.count++] = in.v[i - 1];
}
}
if (in.count > 0 && result.count > 0) {
B32 is_unique = result.v[result.count - 1] != in.v[in.count - 1];
if (is_unique) {
result.v[result.count++] = in.v[in.count - 1];
}
}
U64 slack_size = (in.count - result.count) * sizeof(result.v[0]);
arena_pop(arena, slack_size);
return result;
}
internal U64
sum_array_u64(U64 count, U64 *v)
{
U64 result = 0;
for (U64 i = 0; i < count; i += 1) {
result += v[i];
}
return result;
}
internal U64
sum_matrix_u64(U64 rows, U64 cols, U64 **v)
{
U64 result = 0;
for (U64 i = 0; i < rows; ++i) {
result += sum_array_u64(cols, v[i]);
}
return result;
}
internal U64
max_array_u64(U64 count, U64 *v)
{
U64 result = 0;
for (U64 i = 0; i < count; i += 1) {
result = Max(v[i], result);
}
return result;
}
internal U64
min_array_u64(U64 count, U64 *v)
{
U64 result = max_U64;
for (U64 i = 0; i < count; i += 1) {
result = Min(v[i], result);
}
return result;
}
internal void
counts_to_offsets_array_u32(U64 count, U32 *arr)
{
U32 next_offset = 0;
for (U64 i = 0; i < count; i += 1) {
U32 current_offset = next_offset;
next_offset += arr[i];
arr[i] = current_offset;
}
}
internal void
counts_to_offsets_array_u64(U64 count, U64 *arr)
{
U64 next_offset = 0;
for (U64 i = 0; i < count; i += 1) {
U64 current_offset = next_offset;
next_offset += arr[i];
arr[i] = current_offset;
}
}
internal U32 *
offsets_from_counts_array_u32(Arena *arena, U32 *v, U64 count)
{
U32 *result = push_array_copy_u32(arena, v, count);
counts_to_offsets_array_u32(count, result);
return result;
}
internal U64 *
offsets_from_counts_array_u64(Arena *arena, U64 *v, U64 count)
{
U64 *result = push_array_copy_u64(arena, v, count);
counts_to_offsets_array_u64(count, result);
return result;
}