a more reasonable API to iterate over a map

This commit is contained in:
krangelov
2019-08-30 08:12:15 +02:00
parent 394d033d19
commit 72cfc1f48a
2 changed files with 16 additions and 42 deletions

View File

@@ -321,47 +321,26 @@ gu_map_iter(GuMap* map, GuMapItor* itor, GuExn* err)
} }
} }
typedef struct { GU_API bool
GuEnum en; gu_map_next(GuMap* map, size_t i, const void** pkey, void** pvalue)
GuMap* ht;
size_t i;
GuMapKeyValue x;
} GuMapEnum;
static void
gu_map_enum_next(GuEnum* self, void* to, GuPool* pool)
{ {
*((GuMapKeyValue**) to) = NULL; while (i < map->data.n_entries) {
if (gu_map_entry_is_free(map, &map->data, i)) {
size_t i; 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; continue;
} }
en->x.key = &en->ht->data.keys[i * en->ht->key_size];
en->x.value = &en->ht->data.values[i * en->ht->cell_size]; *pkey = &map->data.keys[i * map->key_size];
if (en->ht->hasher == gu_addr_hasher) { *pvalue = &map->data.values[i * map->cell_size];
en->x.key = *(const void* const*) en->x.key; if (map->hasher == gu_addr_hasher) {
} else if (en->ht->hasher == gu_string_hasher) { *pkey = *(const void* const*) *pkey;
en->x.key = *(GuString*) en->x.key; } else if (map->hasher == gu_string_hasher) {
*pkey = *(GuString*) *pkey;
}
return true;
} }
*((GuMapKeyValue**) to) = &en->x; return false;
break;
}
en->i = i+1;
}
GU_API 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;
} }
GU_API size_t GU_API size_t

View File

@@ -74,13 +74,8 @@ gu_map_delete(GuMap* ht, const void* key);
GU_API_DECL void GU_API_DECL void
gu_map_iter(GuMap* ht, GuMapItor* itor, GuExn* err); gu_map_iter(GuMap* ht, GuMapItor* itor, GuExn* err);
typedef struct { GU_API bool
const void* key; gu_map_next(GuMap* ht, size_t i, const void** pkey, void** pvalue);
void* value;
} GuMapKeyValue;
GU_API_DECL GuEnum*
gu_map_enum(GuMap* ht, GuPool* pool);
typedef GuMap GuIntMap; typedef GuMap GuIntMap;