diff options
| author | kr.angelov <kr.angelov@gmail.com> | 2013-08-19 12:13:47 +0000 |
|---|---|---|
| committer | kr.angelov <kr.angelov@gmail.com> | 2013-08-19 12:13:47 +0000 |
| commit | 308e1445ca5396327d9e78d68cc45e8e008a4876 (patch) | |
| tree | 15a6532f1e16279f562d44bc93241b9313780d5c /src/runtime/c/gu/map.c | |
| parent | 87e34b11dc9cb7a09734f18326c2e4b1dc7560b1 (diff) | |
added GuEnum interface for iterating over maps in the C runtime
Diffstat (limited to 'src/runtime/c/gu/map.c')
| -rw-r--r-- | src/runtime/c/gu/map.c | 41 |
1 files changed, 41 insertions, 0 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) { |
