From e3c188c8a89de0f4a01f8941dbbef20536e84436 Mon Sep 17 00:00:00 2001 From: "kr.angelov" Date: Mon, 19 Aug 2013 12:13:47 +0000 Subject: [PATCH] added GuEnum interface for iterating over maps in the C runtime --- src/runtime/c/gu/map.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/runtime/c/gu/map.h | 10 +++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) 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 #include #include +#include -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;