commit 3628b8ab8ce153d7189a27f5d66860552e9a38b4
parent 045132350572ad8f273c580685218821c7dd562e
Author: Sebastian <sebastian@sebsite.pw>
Date: Sun, 20 Mar 2022 00:28:32 -0400
slice: add more void functions
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
M | slice/void.ha | | | 64 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
1 file changed, 56 insertions(+), 8 deletions(-)
diff --git a/slice/void.ha b/slice/void.ha
@@ -3,26 +3,74 @@
use rt;
use types;
-// Appends an item, or items, to a slice, returning a new slice.
+// Appends an item, or multiple items, to a slice.
export fn appendto(sl: *[]void, itemsz: size, items: const *void...) void = {
+ const repr = sl: *types::slice;
+ insertinto(sl, itemsz, repr.length, items...);
+};
+
+@test fn appendto() void = {
+ let input: []int = [];
+ let num = 1337;
+ appendto(&input: *[]void, size(int), &num, &num);
+ assert(len(input) == 2 && input[0] == 1337 && input[1] == 1337);
+ num = 7331;
+ appendto(&input: *[]void, size(int), &num);
+ assert(len(input) == 3 && input[0] == 1337 && input[1] == 1337
+ && input[2] == 7331);
+ free(input);
+};
+
+// Inserts an item, or multiple items, to a slice, in O(n) time.
+export fn insertinto(
+ sl: *[]void,
+ itemsz: size,
+ idx: size,
+ items: const *void...
+) void = {
if (len(items) == 0) {
return;
};
let sl = sl: *types::slice;
- let end = sl.length;
sl.length += len(items);
rt::ensure(sl, itemsz);
let data = sl.data: *[*]u8;
+ rt::memmove(&data[(idx + len(items)) * itemsz], &data[idx * itemsz],
+ (sl.length - len(items) - idx) * itemsz);
for (let i = 0z; i < len(items); i += 1) {
- rt::memcpy(&data[(end + i) * itemsz], items[i], itemsz);
+ rt::memcpy(&data[(idx + i) * itemsz], items[i], itemsz);
};
};
-@test fn appendto() void = {
- let input: []int = [];
- let num = 1337;
- appendto(&input: *[]void, size(int), &num, &num);
- assert(len(input) == 2 && input[0] == 1337 && input[1] == 1337);
+@test fn insertinto() void = {
+ let input: []int = alloc([1, 3], 2);
+ let num = 2;
+ insertinto(&input: *[]void, size(int), 1, &num, &num);
+ assert(len(input) == 4 && input[0] == 1 && input[1] == 2
+ && input[2] == 2 && input[3] == 3);
+ free(input);
+};
+
+// Deletes a range of items from a slice, in O(n) time, without freeing memory.
+export fn deletefrom(sl: *[]void, itemsz: size, start: size, end: size) void = {
+ assert(start <= end);
+ if (start == end) {
+ return;
+ };
+ let sl = sl: *types::slice;
+ let data = sl.data: *[*]u8;
+ rt::memmove(&data[start * itemsz], &data[end * itemsz],
+ (sl.length - start) * itemsz);
+ sl.length -= end - start;
+};
+
+@test fn deletefrom() void = {
+ let input: []int = alloc([1, 2, 3, 4, 5], 5);
+ deletefrom(&input: *[]void, size(int), 1, 1);
+ assert(len(input) == 5);
+ deletefrom(&input: *[]void, size(int), 1, 3);
+ assert(len(input) == 3 && input[0] == 1 && input[1] == 4
+ && input[2] == 5);
free(input);
};