summaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorkr.angelov <kr.angelov@gmail.com>2013-08-19 12:13:47 +0000
committerkr.angelov <kr.angelov@gmail.com>2013-08-19 12:13:47 +0000
commit308e1445ca5396327d9e78d68cc45e8e008a4876 (patch)
tree15a6532f1e16279f562d44bc93241b9313780d5c /src/runtime
parent87e34b11dc9cb7a09734f18326c2e4b1dc7560b1 (diff)
added GuEnum interface for iterating over maps in the C runtime
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/c/gu/map.c41
-rw-r--r--src/runtime/c/gu/map.h10
2 files changed, 50 insertions, 1 deletions
diff --git a/src/runtime/c/gu/map.c b/src/runtime/c/gu/map.c
index 2a818d8be..cc3b7e829 100644
--- a/src/runtime/c/gu/map.c
+++ b/src/runtime/c/gu/map.c
@@ -303,6 +303,47 @@ gu_map_iter(GuMap* map, GuMapItor* itor, GuExn* err)
}
}
+typedef struct {
+ GuEnum en;
+ GuMap* ht;
+ size_t i;
+ GuMapKeyValue x;
+} GuMapEnum;
+
+static void
+gu_map_enum_next(GuEnum* self, void* to, GuPool* pool)
+{
+ *((GuMapKeyValue**) to) = NULL;
+
+ size_t i;
+ GuMapEnum* en = (GuMapEnum*) self;
+ for (i = en->i; i < en->ht->data.n_entries; i++) {
+ if (gu_map_entry_is_free(en->ht, &en->ht->data, i)) {
+ continue;
+ }
+ en->x.key = &en->ht->data.keys[i * en->ht->key_size];
+ en->x.value = &en->ht->data.values[i * en->ht->value_size];
+ if (en->ht->kind == GU_MAP_ADDR) {
+ en->x.key = *(const void* const*) en->x.key;
+ }
+
+ *((GuMapKeyValue**) to) = &en->x;
+ break;
+ }
+
+ en->i = i+1;
+}
+
+GuEnum*
+gu_map_enum(GuMap* ht, GuPool* pool)
+{
+ GuMapEnum* en = gu_new(GuMapEnum, pool);
+ en->en.next = gu_map_enum_next;
+ en->ht = ht;
+ en->i = 0;
+ return &en->en;
+}
+
size_t
gu_map_count(GuMap* map)
{
diff --git a/src/runtime/c/gu/map.h b/src/runtime/c/gu/map.h
index 327d6ea6a..33edc2a00 100644
--- a/src/runtime/c/gu/map.h
+++ b/src/runtime/c/gu/map.h
@@ -4,8 +4,9 @@
#include <gu/hash.h>
#include <gu/mem.h>
#include <gu/exn.h>
+#include <gu/enum.h>
-typedef const struct GuMapItor GuMapItor;
+typedef struct GuMapItor GuMapItor;
struct GuMapItor {
void (*fn)(GuMapItor* self, const void* key, void* value,
@@ -67,6 +68,13 @@ gu_map_insert(GuMap* ht, const void* key);
void
gu_map_iter(GuMap* ht, GuMapItor* itor, GuExn* err);
+typedef struct {
+ const void* key;
+ void* value;
+} GuMapKeyValue;
+
+GuEnum*
+gu_map_enum(GuMap* ht, GuPool* pool);
typedef GuMap GuIntMap;