aboutsummaryrefslogtreecommitdiff
path: root/src/stdlib/lists.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/stdlib/lists.c')
-rw-r--r--src/stdlib/lists.c174
1 files changed, 89 insertions, 85 deletions
diff --git a/src/stdlib/lists.c b/src/stdlib/lists.c
index bae79dfd..516f37e2 100644
--- a/src/stdlib/lists.c
+++ b/src/stdlib/lists.c
@@ -18,6 +18,9 @@
// Use inline version of siphash code:
#include "siphash-internals.h"
+public
+char _EMPTY_LIST_SENTINEL = '\0';
+
PUREFUNC static INLINE int64_t get_padded_item_size(const TypeInfo_t *info) {
int64_t size = info->ListInfo.item->size;
if (info->ListInfo.item->align > 1 && size % info->ListInfo.item->align) errx(1, "Item size is not padded!");
@@ -35,7 +38,7 @@ void List$compact(List_t *list, int64_t padded_item_size) {
if ((int64_t)list->stride == padded_item_size) {
memcpy(copy, list->data, (size_t)list->length * (size_t)padded_item_size);
} else {
- for (int64_t i = 0; i < list->length; i++)
+ for (int64_t i = 0; i < (int64_t)list->length; i++)
memcpy(copy + i * padded_item_size, list->data + list->stride * i, (size_t)padded_item_size);
}
}
@@ -50,7 +53,7 @@ void List$compact(List_t *list, int64_t padded_item_size) {
public
void List$insert(List_t *list, const void *item, Int_t int_index, int64_t padded_item_size) {
int64_t index = Int64$from_int(int_index, false);
- if (index <= 0) index = list->length + index + 1;
+ if (index <= 0) index = (int64_t)list->length + index + 1;
if (index < 1) index = 1;
else if (index > (int64_t)list->length + 1)
@@ -74,9 +77,9 @@ void List$insert(List_t *list, const void *item, Int_t int_index, int64_t padded
list->data_refcount = 0;
list->stride = padded_item_size;
} else {
- if (index != list->length + 1) {
- assert(list->length >= index);
- size_t size = (size_t)((list->length - index + 1) * padded_item_size);
+ if (index != (int64_t)list->length + 1) {
+ assert((int64_t)list->length >= index);
+ size_t size = (size_t)(((int64_t)list->length - index + 1) * padded_item_size);
assert(size < SIZE_MAX);
memmove(list->data + index * padded_item_size, list->data + (index - 1) * padded_item_size, size);
}
@@ -98,7 +101,7 @@ void List$insert_all(List_t *list, List_t to_insert, Int_t int_index, int64_t pa
return;
}
- if (index < 1) index = list->length + index + 1;
+ if (index < 1) index = (int64_t)list->length + index + 1;
if (index < 1) index = 1;
else if (index > (int64_t)list->length + 1)
@@ -110,15 +113,15 @@ void List$insert_all(List_t *list, List_t to_insert, Int_t int_index, int64_t pa
// If we can fit this within the list's preallocated free space, do that:
list->free -= to_insert.length;
list->length += to_insert.length;
- if (index != list->length + 1)
+ if (index != (int64_t)list->length + 1)
memmove((void *)list->data + index * padded_item_size, list->data + (index - 1) * padded_item_size,
- (size_t)((list->length - index + to_insert.length - 1) * padded_item_size));
- for (int64_t i = 0; i < to_insert.length; i++)
+ (size_t)(((int64_t)list->length - index + (int64_t)to_insert.length - 1) * padded_item_size));
+ for (int64_t i = 0; i < (int64_t)to_insert.length; i++)
memcpy((void *)list->data + (index - 1 + i) * padded_item_size, to_insert.data + i * to_insert.stride,
(size_t)padded_item_size);
} else {
// Otherwise, allocate a new chunk of memory for the list and populate it:
- int64_t new_len = list->length + to_insert.length;
+ int64_t new_len = (int64_t)list->length + (int64_t)to_insert.length;
list->free = MIN(LIST_MAX_FREE_ENTRIES, MAX(8, new_len / 4));
void *data = list->atomic ? GC_MALLOC_ATOMIC((size_t)((new_len + list->free) * padded_item_size))
: GC_MALLOC((size_t)((new_len + list->free) * padded_item_size));
@@ -139,8 +142,8 @@ void List$insert_all(List_t *list, List_t to_insert, Int_t int_index, int64_t pa
// Copy `to_insert`
if (to_insert.stride == padded_item_size) {
- memcpy(p, to_insert.data, (size_t)(to_insert.length * padded_item_size));
- p += to_insert.length * padded_item_size;
+ memcpy(p, to_insert.data, (size_t)((int64_t)to_insert.length * padded_item_size));
+ p += (int64_t)to_insert.length * padded_item_size;
} else {
for (int64_t i = 0; i < index - 1; i++) {
memcpy(p, to_insert.data + to_insert.stride * i, (size_t)padded_item_size);
@@ -149,19 +152,19 @@ void List$insert_all(List_t *list, List_t to_insert, Int_t int_index, int64_t pa
}
// Copy last chunk of `list` if needed:
- if (index < list->length + 1) {
+ if (index < (int64_t)list->length + 1) {
if (list->stride == padded_item_size) {
memcpy(p, list->data + padded_item_size * (index - 1),
- (size_t)((list->length - index + 1) * padded_item_size));
- p += (list->length - index + 1) * padded_item_size;
+ (size_t)(((int64_t)list->length - index + 1) * padded_item_size));
+ p += ((int64_t)list->length - index + 1) * padded_item_size;
} else {
- for (int64_t i = index - 1; i < list->length - 1; i++) {
+ for (int64_t i = index - 1; i < (int64_t)list->length - 1; i++) {
memcpy(p, list->data + list->stride * i, (size_t)padded_item_size);
p += padded_item_size;
}
}
}
- list->length = new_len;
+ list->length = (uint64_t)new_len;
list->stride = padded_item_size;
list->data = data;
list->data_refcount = 0;
@@ -171,20 +174,20 @@ void List$insert_all(List_t *list, List_t to_insert, Int_t int_index, int64_t pa
public
void List$remove_at(List_t *list, Int_t int_index, Int_t int_count, int64_t padded_item_size) {
int64_t index = Int64$from_int(int_index, false);
- if (index < 1) index = list->length + index + 1;
+ if (index < 1) index = (int64_t)list->length + index + 1;
int64_t count = Int64$from_int(int_count, false);
if (index < 1 || index > (int64_t)list->length || count < 1) return;
- if (count > list->length - index + 1) count = (list->length - index) + 1;
+ if (count > (int64_t)list->length - index + 1) count = ((int64_t)list->length - index) + 1;
if (index == 1) {
list->data += list->stride * count;
- } else if (index + count > list->length) {
+ } else if (index + count > (int64_t)list->length) {
list->free += count;
} else if (list->data_refcount != 0 || (int64_t)list->stride != padded_item_size) {
- void *copy = list->atomic ? GC_MALLOC_ATOMIC((size_t)((list->length - 1) * padded_item_size))
- : GC_MALLOC((size_t)((list->length - 1) * padded_item_size));
+ void *copy = list->atomic ? GC_MALLOC_ATOMIC((size_t)(((int64_t)list->length - 1) * padded_item_size))
+ : GC_MALLOC((size_t)(((int64_t)list->length - 1) * padded_item_size));
for (int64_t src = 1, dest = 1; src <= (int64_t)list->length; src++) {
if (src < index || src >= index + count) {
memcpy(copy + (dest - 1) * padded_item_size, list->data + list->stride * (src - 1),
@@ -198,10 +201,10 @@ void List$remove_at(List_t *list, Int_t int_index, Int_t int_count, int64_t padd
} else {
memmove((void *)list->data + (index - 1) * padded_item_size,
list->data + (index - 1 + count) * padded_item_size,
- (size_t)((list->length - index + count - 1) * padded_item_size));
+ (size_t)(((int64_t)list->length - index + count - 1) * padded_item_size));
list->free += count;
}
- list->length -= count;
+ list->length -= (uint64_t)count;
if (list->length == 0) list->data = NULL;
}
@@ -211,7 +214,7 @@ void List$remove_item(List_t *list, void *item, Int_t max_removals, const TypeIn
const Int_t ZERO = (Int_t){.small = (0 << 2) | 1};
const Int_t ONE = (Int_t){.small = (1 << 2) | 1};
const TypeInfo_t *item_type = type->ListInfo.item;
- for (int64_t i = 0; i < list->length;) {
+ for (int64_t i = 0; i < (int64_t)list->length;) {
if (max_removals.small == ZERO.small) // zero
break;
@@ -227,7 +230,7 @@ void List$remove_item(List_t *list, void *item, Int_t max_removals, const TypeIn
public
OptionalInt_t List$find(List_t list, void *item, const TypeInfo_t *type) {
const TypeInfo_t *item_type = type->ListInfo.item;
- for (int64_t i = 0; i < list.length; i++) {
+ for (int64_t i = 0; i < (int64_t)list.length; i++) {
if (generic_equal(item, list.data + i * list.stride, item_type)) return I(i + 1);
}
return NONE_INT;
@@ -236,7 +239,7 @@ OptionalInt_t List$find(List_t list, void *item, const TypeInfo_t *type) {
public
OptionalInt_t List$first(List_t list, Closure_t predicate) {
bool (*is_good)(void *, void *) = (void *)predicate.fn;
- for (int64_t i = 0; i < list.length; i++) {
+ for (int64_t i = 0; i < (int64_t)list.length; i++) {
if (is_good(list.data + i * list.stride, predicate.userdata)) return I(i + 1);
}
return NONE_INT;
@@ -300,9 +303,9 @@ void List$shuffle(List_t *list, OptionalClosure_t random_int64, int64_t padded_i
typedef int64_t (*rng_fn_t)(int64_t, int64_t, void *);
rng_fn_t rng_fn = random_int64.fn ? (rng_fn_t)random_int64.fn : _default_random_int64;
char tmp[padded_item_size];
- for (int64_t i = list->length - 1; i > 1; i--) {
+ for (int64_t i = (int64_t)list->length - 1; i > 1; i--) {
int64_t j = rng_fn(0, i, random_int64.userdata);
- if unlikely (j < 0 || j > list->length - 1)
+ if unlikely (j < 0 || j > (int64_t)list->length - 1)
fail("The provided random number function returned an invalid value: ", j, " (not between 0 and ", i, ")");
memcpy(tmp, list->data + i * padded_item_size, (size_t)padded_item_size);
memcpy((void *)list->data + i * padded_item_size, list->data + j * padded_item_size, (size_t)padded_item_size);
@@ -323,8 +326,8 @@ void *List$random(List_t list, OptionalClosure_t random_int64) {
typedef int64_t (*rng_fn_t)(int64_t, int64_t, void *);
rng_fn_t rng_fn = random_int64.fn ? (rng_fn_t)random_int64.fn : _default_random_int64;
- int64_t index = rng_fn(0, list.length - 1, random_int64.userdata);
- if unlikely (index < 0 || index > list.length - 1)
+ int64_t index = rng_fn(0, (int64_t)list.length - 1, random_int64.userdata);
+ if unlikely (index < 0 || index > (int64_t)list.length - 1)
fail("The provided random number function returned an invalid value: ", index, " (not between 0 and ",
(int64_t)list.length, ")");
return list.data + list.stride * index;
@@ -332,9 +335,9 @@ void *List$random(List_t list, OptionalClosure_t random_int64) {
public
Table_t List$counts(List_t list, const TypeInfo_t *type) {
- Table_t counts = {};
+ Table_t counts = EMPTY_TABLE;
const TypeInfo_t count_type = *Table$info(type->ListInfo.item, &Int$info);
- for (int64_t i = 0; i < list.length; i++) {
+ for (int64_t i = 0; i < (int64_t)list.length; i++) {
void *key = list.data + i * list.stride;
int64_t *count = Table$get(counts, key, &count_type);
int64_t val = count ? *count + 1 : 1;
@@ -362,7 +365,7 @@ List_t List$sample(List_t list, Int_t int_n, List_t weights, OptionalClosure_t r
int64_t n = Int64$from_int(int_n, false);
if (n < 0) fail("Cannot select a negative number of values");
- if (n == 0) return (List_t){};
+ if (n == 0) return EMPTY_LIST;
if (list.length == 0) fail("There are no elements in this list!");
@@ -370,7 +373,7 @@ List_t List$sample(List_t list, Int_t int_n, List_t weights, OptionalClosure_t r
fail("List has ", (int64_t)list.length, " elements, but there are ", (int64_t)weights.length, " weights given");
double total = 0.0;
- for (int64_t i = 0; i < weights.length && i < list.length; i++) {
+ for (int64_t i = 0; i < (int64_t)weights.length && i < (int64_t)list.length; i++) {
double weight = *(double *)(weights.data + weights.stride * i);
if (isinf(weight)) fail("Infinite weight!");
else if (isnan(weight)) fail("NaN weight!");
@@ -389,19 +392,19 @@ List_t List$sample(List_t list, Int_t int_n, List_t weights, OptionalClosure_t r
double odds;
} aliases[list.length];
- for (int64_t i = 0; i < list.length; i++) {
- double weight = i >= weights.length ? 0.0 : *(double *)(weights.data + weights.stride * i);
+ for (int64_t i = 0; i < (int64_t)list.length; i++) {
+ double weight = i >= (int64_t)weights.length ? 0.0 : *(double *)(weights.data + weights.stride * i);
aliases[i].odds = weight * inverse_average;
aliases[i].alias = -1;
}
int64_t small = 0;
- for (int64_t big = 0; big < list.length; big++) {
+ for (int64_t big = 0; big < (int64_t)list.length; big++) {
while (aliases[big].odds >= 1.0) {
- while (small < list.length && (aliases[small].odds >= 1.0 || aliases[small].alias != -1))
+ while (small < (int64_t)list.length && (aliases[small].odds >= 1.0 || aliases[small].alias != -1))
++small;
- if (small >= list.length) {
+ if (small >= (int64_t)list.length) {
aliases[big].odds = 1.0;
aliases[big].alias = big;
break;
@@ -413,7 +416,7 @@ List_t List$sample(List_t list, Int_t int_n, List_t weights, OptionalClosure_t r
if (big < small) small = big;
}
- for (int64_t i = small; i < list.length; i++)
+ for (int64_t i = small; i < (int64_t)list.length; i++)
if (aliases[i].alias == -1) aliases[i].alias = i;
typedef double (*rng_fn_t)(void *);
@@ -421,7 +424,7 @@ List_t List$sample(List_t list, Int_t int_n, List_t weights, OptionalClosure_t r
List_t selected = {.data = list.atomic ? GC_MALLOC_ATOMIC((size_t)(n * padded_item_size))
: GC_MALLOC((size_t)(n * padded_item_size)),
- .length = n,
+ .length = (uint64_t)n,
.stride = padded_item_size,
.atomic = list.atomic};
for (int64_t i = 0; i < n; i++) {
@@ -430,7 +433,7 @@ List_t List$sample(List_t list, Int_t int_n, List_t weights, OptionalClosure_t r
fail("The random number function returned a value not between 0.0 (inclusive) and 1.0 (exclusive): ", r);
r *= (double)list.length;
int64_t index = (int64_t)r;
- assert(index >= 0 && index < list.length);
+ assert(index >= 0 && index < (int64_t)list.length);
if ((r - (double)index) > aliases[index].odds) index = aliases[index].alias;
memcpy(selected.data + i * selected.stride, list.data + index * list.stride, (size_t)padded_item_size);
}
@@ -449,29 +452,29 @@ List_t List$by(List_t list, Int_t int_stride, int64_t padded_item_size) {
// In the unlikely event that the stride value would be too large to fit in
// a 15-bit integer, fall back to creating a copy of the list:
if (unlikely(list.stride * stride < LIST_MIN_STRIDE || list.stride * stride > LIST_MAX_STRIDE)) {
- void *copy = NULL;
- int64_t len = (stride < 0 ? list.length / -stride : list.length / stride) + ((list.length % stride) != 0);
- if (len > 0) {
- copy = list.atomic ? GC_MALLOC_ATOMIC((size_t)(len * padded_item_size))
- : GC_MALLOC((size_t)(len * padded_item_size));
- void *start = (stride < 0 ? list.data + (list.stride * (list.length - 1)) : list.data);
- for (int64_t i = 0; i < len; i++)
- memcpy(copy + i * padded_item_size, start + list.stride * stride * i, (size_t)padded_item_size);
- }
+ int64_t len = (stride < 0 ? (int64_t)list.length / -stride : (int64_t)list.length / stride)
+ + (((int64_t)list.length % stride) != 0);
+ if (len <= 0) return list.atomic ? EMPTY_ATOMIC_LIST : EMPTY_LIST;
+ void *copy = list.atomic ? GC_MALLOC_ATOMIC((size_t)(len * padded_item_size))
+ : GC_MALLOC((size_t)(len * padded_item_size));
+ void *start = (stride < 0 ? list.data + (list.stride * ((int64_t)list.length - 1)) : list.data);
+ for (int64_t i = 0; i < len; i++)
+ memcpy(copy + i * padded_item_size, start + list.stride * stride * i, (size_t)padded_item_size);
return (List_t){
.data = copy,
- .length = len,
+ .length = (uint64_t)len,
.stride = padded_item_size,
.atomic = list.atomic,
};
}
- if (stride == 0) return (List_t){.atomic = list.atomic};
+ if (stride == 0) return list.atomic ? EMPTY_ATOMIC_LIST : EMPTY_LIST;
return (List_t){
.atomic = list.atomic,
- .data = (stride < 0 ? list.data + (list.stride * (list.length - 1)) : list.data),
- .length = (stride < 0 ? list.length / -stride : list.length / stride) + ((list.length % stride) != 0),
+ .data = (stride < 0 ? list.data + (list.stride * ((int64_t)list.length - 1)) : list.data),
+ .length = (uint64_t)((stride < 0 ? (int64_t)list.length / -stride : (int64_t)list.length / stride)
+ + (((int64_t)list.length % stride) != 0)),
.stride = list.stride * stride,
.data_refcount = list.data_refcount,
};
@@ -482,19 +485,19 @@ List_t List$slice(List_t list, Int_t int_first, Int_t int_last)
{
int64_t first = Int64$from_int(int_first, false);
- if (first < 0) first = list.length + first + 1;
+ if (first < 0) first = (int64_t)list.length + first + 1;
int64_t last = Int64$from_int(int_last, false);
- if (last < 0) last = list.length + last + 1;
+ if (last < 0) last = (int64_t)list.length + last + 1;
- if (last > list.length) last = list.length;
+ if (last > (int64_t)list.length) last = (int64_t)list.length;
- if (first < 1 || first > list.length || last == 0) return (List_t){.atomic = list.atomic};
+ if (first < 1 || first > (int64_t)list.length || last == 0) return EMPTY_ATOMIC_LIST;
return (List_t){
.atomic = list.atomic,
.data = list.data + list.stride * (first - 1),
- .length = last - first + 1,
+ .length = (uint64_t)(last - first + 1),
.stride = list.stride,
.data_refcount = list.data_refcount,
};
@@ -511,26 +514,26 @@ List_t List$reversed(List_t list, int64_t padded_item_size) {
List_t reversed = list;
reversed.stride = -list.stride;
- reversed.data = list.data + (list.length - 1) * list.stride;
+ reversed.data = list.data + ((int64_t)list.length - 1) * list.stride;
return reversed;
}
public
List_t List$concat(List_t x, List_t y, int64_t padded_item_size) {
- void *data = x.atomic ? GC_MALLOC_ATOMIC((size_t)(padded_item_size * (x.length + y.length)))
- : GC_MALLOC((size_t)(padded_item_size * (x.length + y.length)));
+ void *data = x.atomic ? GC_MALLOC_ATOMIC((size_t)(padded_item_size * (int64_t)(x.length + y.length)))
+ : GC_MALLOC((size_t)(padded_item_size * (int64_t)(x.length + y.length)));
if (x.stride == padded_item_size) {
- memcpy(data, x.data, (size_t)(padded_item_size * x.length));
+ memcpy(data, x.data, (size_t)(padded_item_size * (int64_t)x.length));
} else {
- for (int64_t i = 0; i < x.length; i++)
+ for (int64_t i = 0; i < (int64_t)x.length; i++)
memcpy(data + i * padded_item_size, x.data + i * padded_item_size, (size_t)padded_item_size);
}
- void *dest = data + padded_item_size * x.length;
+ void *dest = data + padded_item_size * (int64_t)x.length;
if (y.stride == padded_item_size) {
- memcpy(dest, y.data, (size_t)(padded_item_size * y.length));
+ memcpy(dest, y.data, (size_t)(padded_item_size * (int64_t)y.length));
} else {
- for (int64_t i = 0; i < y.length; i++)
+ for (int64_t i = 0; i < (int64_t)y.length; i++)
memcpy(dest + i * padded_item_size, y.data + i * y.stride, (size_t)padded_item_size);
}
@@ -545,14 +548,14 @@ List_t List$concat(List_t x, List_t y, int64_t padded_item_size) {
public
bool List$has(List_t list, void *item, const TypeInfo_t *type) {
const TypeInfo_t *item_type = type->ListInfo.item;
- for (int64_t i = 0; i < list.length; i++) {
+ for (int64_t i = 0; i < (int64_t)list.length; i++) {
if (generic_equal(list.data + i * list.stride, item, item_type)) return true;
}
return false;
}
public
-void List$clear(List_t *list) { *list = (List_t){.data = 0, .length = 0}; }
+void List$clear(List_t *list) { *list = list->atomic ? EMPTY_ATOMIC_LIST : EMPTY_LIST; }
public
int32_t List$compare(const void *vx, const void *vy, const TypeInfo_t *type) {
@@ -568,7 +571,8 @@ int32_t List$compare(const void *vx, const void *vy, const TypeInfo_t *type) {
if ((int64_t)x->stride == item_padded_size && (int64_t)y->stride == item_padded_size
&& item->size == item_padded_size) {
- int32_t cmp = (int32_t)memcmp(x->data, y->data, (size_t)(MIN(x->length, y->length) * item_padded_size));
+ int32_t cmp = (int32_t)memcmp(x->data, y->data,
+ (size_t)(MIN((int64_t)x->length, (int64_t)y->length) * item_padded_size));
if (cmp != 0) return cmp;
} else {
for (int32_t i = 0, len = MIN(x->length, y->length); i < len; i++) {
@@ -597,7 +601,7 @@ Text_t List$as_text(const void *obj, bool colorize, const TypeInfo_t *type) {
const TypeInfo_t *item_type = type->ListInfo.item;
Text_t text = Text("[");
- for (int64_t i = 0; i < list->length; i++) {
+ for (int64_t i = 0; i < (int64_t)list->length; i++) {
if (i > 0) text = Text$concat(text, Text(", "));
Text_t item_text = generic_as_text(list->data + i * list->stride, colorize, item_type);
text = Text$concat(text, item_text);
@@ -613,10 +617,10 @@ uint64_t List$hash(const void *obj, const TypeInfo_t *type) {
siphash sh;
siphashinit(&sh, sizeof(uint64_t[list->length]));
if (item->tag == PointerInfo || (!item->metamethods.hash && item->size == sizeof(void *))) { // Raw data hash
- for (int64_t i = 0; i < list->length; i++)
+ for (int64_t i = 0; i < (int64_t)list->length; i++)
siphashadd64bits(&sh, (uint64_t)(list->data + i * list->stride));
} else {
- for (int64_t i = 0; i < list->length; i++) {
+ for (int64_t i = 0; i < (int64_t)list->length; i++) {
uint64_t item_hash = generic_hash(list->data + i * list->stride, item);
siphashadd64bits(&sh, item_hash);
}
@@ -625,7 +629,7 @@ uint64_t List$hash(const void *obj, const TypeInfo_t *type) {
}
static void siftdown(List_t *heap, int64_t startpos, int64_t pos, Closure_t comparison, int64_t padded_item_size) {
- assert(pos > 0 && pos < heap->length);
+ assert(pos > 0 && pos < (int64_t)heap->length);
char newitem[padded_item_size];
memcpy(newitem, heap->data + heap->stride * pos, (size_t)(padded_item_size));
while (pos > startpos) {
@@ -641,7 +645,7 @@ static void siftdown(List_t *heap, int64_t startpos, int64_t pos, Closure_t comp
}
static void siftup(List_t *heap, int64_t pos, Closure_t comparison, int64_t padded_item_size) {
- int64_t endpos = heap->length;
+ int64_t endpos = (int64_t)heap->length;
int64_t startpos = pos;
assert(pos < endpos);
@@ -673,7 +677,7 @@ void List$heap_push(List_t *heap, const void *item, Closure_t comparison, int64_
if (heap->length > 1) {
if (heap->data_refcount != 0) List$compact(heap, padded_item_size);
- siftdown(heap, 0, heap->length - 1, comparison, padded_item_size);
+ siftdown(heap, 0, (int64_t)heap->length - 1, comparison, padded_item_size);
}
}
@@ -682,13 +686,13 @@ void List$heap_pop(List_t *heap, Closure_t comparison, int64_t padded_item_size)
if (heap->length == 0) fail("Attempt to pop from an empty list");
if (heap->length == 1) {
- *heap = (List_t){};
+ *heap = EMPTY_LIST;
} else if (heap->length == 2) {
heap->data += heap->stride;
--heap->length;
} else {
if (heap->data_refcount != 0) List$compact(heap, padded_item_size);
- memcpy(heap->data, heap->data + heap->stride * (heap->length - 1), (size_t)(padded_item_size));
+ memcpy(heap->data, heap->data + heap->stride * ((int64_t)heap->length - 1), (size_t)(padded_item_size));
--heap->length;
siftup(heap, 0, comparison, padded_item_size);
}
@@ -701,7 +705,7 @@ void List$heapify(List_t *heap, Closure_t comparison, int64_t padded_item_size)
// It's necessary to bump the refcount because the user's comparison
// function could do stuff that modifies the heap's data.
LIST_INCREF(*heap);
- int64_t i, n = heap->length;
+ int64_t i, n = (int64_t)heap->length;
for (i = (n >> 1) - 1; i >= 0; i--)
siftup(heap, i, comparison, padded_item_size);
LIST_DECREF(*heap);
@@ -710,7 +714,7 @@ void List$heapify(List_t *heap, Closure_t comparison, int64_t padded_item_size)
public
Int_t List$binary_search(List_t list, void *target, Closure_t comparison) {
typedef int32_t (*cmp_fn_t)(void *, void *, void *);
- int64_t lo = 0, hi = list.length - 1;
+ int64_t lo = 0, hi = (int64_t)list.length - 1;
while (lo <= hi) {
int64_t mid = (lo + hi) / 2;
int32_t cmp = ((cmp_fn_t)comparison.fn)(list.data + list.stride * mid, target, comparison.userdata);
@@ -724,13 +728,13 @@ Int_t List$binary_search(List_t list, void *target, Closure_t comparison) {
public
PUREFUNC bool List$is_none(const void *obj, const TypeInfo_t *info) {
(void)info;
- return ((List_t *)obj)->length < 0;
+ return ((List_t *)obj)->data == NULL;
}
public
void List$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) {
List_t list = *(List_t *)obj;
- int64_t len = list.length;
+ int64_t len = (int64_t)list.length;
Int64$serialize(&len, out, pointers, &Int64$info);
serialize_fn_t item_serialize = type->ListInfo.item->metamethods.serialize;
if (item_serialize) {
@@ -752,7 +756,7 @@ void List$deserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *t
if (type->ListInfo.item->align > 0 && padded_size % type->ListInfo.item->align > 0)
padded_size += type->ListInfo.item->align - (padded_size % type->ListInfo.item->align);
List_t list = {
- .length = len,
+ .length = (uint64_t)len,
.data = GC_MALLOC((size_t)(len * padded_size)),
.stride = padded_size,
};