[map] Add hb_map_next()

This commit is contained in:
Behdad Esfahbod 2023-01-04 12:55:59 -07:00
parent 3e471bbc08
commit ffafcf9633
5 changed files with 82 additions and 1 deletions

View File

@ -546,6 +546,7 @@ hb_map_get_population
hb_map_is_empty
hb_map_is_equal
hb_map_hash
hb_map_next
HB_MAP_VALUE_INVALID
hb_map_t
</SECTION>

View File

@ -335,9 +335,32 @@ hb_map_is_equal (const hb_map_t *map,
*
* Since: 4.4.0
**/
HB_EXTERN unsigned int
unsigned int
hb_map_hash (const hb_map_t *map)
{
return map->hash ();
}
/**
* hb_map_next:
* @map: A map
* @idx: (inout): Iterator internal state
* @key: (out): Key retrieved
* @value: (out): Value retrieved
*
* Fetches the next key/value paire in @map.
*
* Set @idx to -1 to get started.
*
* Return value: `true` if there was a next value, `false` otherwise
*
* Since: REPLACEME
**/
hb_bool_t
hb_map_next (const hb_map_t *map,
int *idx,
hb_codepoint_t *key,
hb_codepoint_t *value)
{
return map->next (idx, key, value);
}

View File

@ -118,6 +118,12 @@ HB_EXTERN hb_bool_t
hb_map_has (const hb_map_t *map,
hb_codepoint_t key);
/* Pass -1 in for idx to get started. */
HB_EXTERN hb_bool_t
hb_map_next (const hb_map_t *map,
int *idx,
hb_codepoint_t *key,
hb_codepoint_t *value);
HB_END_DECLS

View File

@ -348,6 +348,30 @@ struct hb_hashmap_t
| hb_map (hb_ridentity)
)
/* C iterator. */
bool next (int *idx,
K *key,
V *value) const
{
unsigned i = (unsigned) (*idx + 1);
unsigned count = size ();
while (i <= count && !items[i].is_real ())
i++;
if (i >= count)
{
*idx = -1;
return false;
}
*key = items[i].key;
*value = items[i].value;
*idx = (signed) i;
return true;
}
/* Sink interface. */
hb_hashmap_t& operator << (const hb_pair_t<K, V>& v)
{ set (v.first, v.second); return *this; }

View File

@ -301,6 +301,33 @@ main (int argc, char **argv)
m.set (1, hb_set_t {1, 2, 3});
m.reset ();
}
/* Test iteration. */
{
hb_map_t m;
m.set (1, 1);
m.set (4, 3);
m.set (5, 5);
m.set (2, 1);
m.set (3, 2);
m.set (6, 8);
hb_codepoint_t k;
hb_codepoint_t v;
unsigned pop = 0;
for (signed i;
m.next (&i, &k, &v);)
{
pop++;
if (k == 1) assert (v == 1);
else if (k == 2) assert (v == 1);
else if (k == 3) assert (v == 2);
else if (k == 4) assert (v == 3);
else if (k == 5) assert (v == 5);
else if (k == 6) assert (v == 8);
else assert (false);
}
assert (pop = m.get_population ());
}
return 0;
}