aboutsummaryrefslogtreecommitdiff
path: root/builtins
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-08-15 02:39:35 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-08-15 02:39:35 -0400
commit66ae30ac29d93ac7346bbb465e6c49f540ec4079 (patch)
treee4a2b839fed20e8a4a5efe6103ecf2a765eeda6c /builtins
parented1667cb377dd8da51583e703c6677969addc993 (diff)
Add method for array:remove_item(item) and rename
array:remove(index)->array:remove_at(index) to avoid confusion. Also hook up array:has()
Diffstat (limited to 'builtins')
-rw-r--r--builtins/array.c26
-rw-r--r--builtins/array.h7
-rw-r--r--builtins/channel.c2
-rw-r--r--builtins/table.c2
4 files changed, 30 insertions, 7 deletions
diff --git a/builtins/array.c b/builtins/array.c
index 84a0b7a0..b310e43d 100644
--- a/builtins/array.c
+++ b/builtins/array.c
@@ -157,7 +157,7 @@ public void Array$insert_all(array_t *arr, array_t to_insert, Int_t int_index, i
}
}
-public void Array$remove(array_t *arr, Int_t int_index, Int_t int_count, int64_t padded_item_size)
+public void Array$remove_at(array_t *arr, Int_t int_index, Int_t int_count, int64_t padded_item_size)
{
int64_t index = Int_to_Int64(int_index, false);
if (index < 1) index = arr->length + index + 1;
@@ -192,6 +192,25 @@ public void Array$remove(array_t *arr, Int_t int_index, Int_t int_count, int64_t
if (arr->length == 0) arr->data = NULL;
}
+public void Array$remove_item(array_t *arr, void *item, Int_t max_removals, const TypeInfo *type)
+{
+ int64_t padded_item_size = get_padded_item_size(type);
+ const Int_t ZERO = (Int_t){.small=(0<<2)|1};
+ const Int_t ONE = (Int_t){.small=(1<<2)|1};
+ const TypeInfo *item_type = type->ArrayInfo.item;
+ for (int64_t i = 0; i < arr->length; ) {
+ if (max_removals.small == ZERO.small) // zero
+ break;
+
+ if (generic_equal(item, arr->data + i*arr->stride, item_type)) {
+ Array$remove_at(arr, I(i+1), ONE, padded_item_size);
+ max_removals = Int$minus(max_removals, ONE);
+ } else {
+ i++;
+ }
+ }
+}
+
public void Array$sort(array_t *arr, closure_t comparison, int64_t padded_item_size)
{
if (arr->data_refcount != 0 || (int64_t)arr->stride != padded_item_size)
@@ -442,12 +461,13 @@ public array_t Array$concat(array_t x, array_t y, int64_t padded_item_size)
};
}
-public bool Array$contains(array_t array, void *item, const TypeInfo *type)
+public bool Array$has(array_t array, void *item, const TypeInfo *type)
{
const TypeInfo *item_type = type->ArrayInfo.item;
- for (int64_t i = 0; i < array.length; i++)
+ for (int64_t i = 0; i < array.length; i++) {
if (generic_equal(array.data + i*array.stride, item, item_type))
return true;
+ }
return false;
}
diff --git a/builtins/array.h b/builtins/array.h
index 7d779677..856bd07b 100644
--- a/builtins/array.h
+++ b/builtins/array.h
@@ -58,7 +58,9 @@
#define Array$insert_value(arr, item_expr, index, padded_item_size) ({ __typeof(item_expr) item = item_expr; Array$insert(arr, &item, index, padded_item_size); })
void Array$insert(array_t *arr, const void *item, Int_t index, int64_t padded_item_size);
void Array$insert_all(array_t *arr, array_t to_insert, Int_t index, int64_t padded_item_size);
-void Array$remove(array_t *arr, Int_t index, Int_t count, int64_t padded_item_size);
+void Array$remove_at(array_t *arr, Int_t index, Int_t count, int64_t padded_item_size);
+void Array$remove_item(array_t *arr, void *item, Int_t max_removals, const TypeInfo *type);
+#define Array$remove_item_value(arr, item_expr, max, type) ({ __typeof(item_expr) item = item_expr; Array$remove_item(arr, &item, max, type); })
void Array$sort(array_t *arr, closure_t comparison, int64_t padded_item_size);
array_t Array$sorted(array_t arr, closure_t comparison, int64_t padded_item_size);
void Array$shuffle(array_t *arr, int64_t padded_item_size);
@@ -69,7 +71,8 @@ array_t Array$sample(array_t arr, Int_t n, array_t weights, int64_t padded_item_
table_t Array$counts(array_t arr, const TypeInfo *type);
void Array$clear(array_t *array);
void Array$compact(array_t *arr, int64_t padded_item_size);
-bool Array$contains(array_t array, void *item, const TypeInfo *type);
+bool Array$has(array_t array, void *item, const TypeInfo *type);
+#define Array$has_value(arr, item_expr, type) ({ __typeof(item_expr) item = item_expr; Array$has(arr, &item, type); })
array_t Array$from(array_t array, Int_t first);
array_t Array$to(array_t array, Int_t last);
array_t Array$by(array_t array, Int_t stride, int64_t padded_item_size);
diff --git a/builtins/channel.c b/builtins/channel.c
index dd49163c..d64f22c9 100644
--- a/builtins/channel.c
+++ b/builtins/channel.c
@@ -63,7 +63,7 @@ public void Channel$pop(channel_t *channel, void *out, int64_t item_size, int64_
while (channel->items.length == 0)
pthread_cond_wait(&channel->cond, &channel->mutex);
memcpy(out, channel->items.data, item_size);
- Array$remove(&channel->items, I(1), I(1), padded_item_size);
+ Array$remove_at(&channel->items, I(1), I(1), padded_item_size);
(void)pthread_mutex_unlock(&channel->mutex);
(void)pthread_cond_signal(&channel->cond);
}
diff --git a/builtins/table.c b/builtins/table.c
index f99ffc86..8de6532c 100644
--- a/builtins/table.c
+++ b/builtins/table.c
@@ -350,7 +350,7 @@ public void Table$remove(table_t *t, const void *key, const TypeInfo *type)
// Last entry is being removed, so clear it out to be safe:
memset(GET_ENTRY(*t, last_entry), 0, entry_size(type));
- Array$remove(&t->entries, I(t->entries.length), I(1), entry_size(type));
+ Array$remove_at(&t->entries, I(t->entries.length), I(1), entry_size(type));
int64_t bucket_to_clear;
if (prev) { // Middle (or end) of a chain