Lindenii Project Forge
Warning: Due to various recent migrations, viewing non-HEAD refs may be broken.
/ds/map/hashmap/iter.ha (raw)
// SPDX-License-Identifier: MPL-2.0
// SPDX-FileCopyrightText: 2024 Drew DeVault <drew@ddevault.org>
// SPDX-FileCopyrightText: 2025 Runxi Yu <me@runxiyu.org>
use ds::map;
export type iterator = struct {
vt: map::iterator,
m: *map,
bi: size,
cur: nullable *map::iterator,
};
const _itvt: map::vtable_iterator = map::vtable_iterator {
nexter = &vt_next,
};
fn vt_next(it: *map::iterator) (([]u8, *opaque) | done) = next(it: *iterator);
export fn iter(m: *map) (*map::iterator | nomem) = {
let it = alloc(iterator {
vt = &_itvt,
m = m,
bi = 0,
cur = null,
})?;
for (it.bi < m.n) {
let b = m.buckets[it.bi];
it.bi += 1;
match (map::iter(b)) {
case let i: *map::iterator =>
it.cur = i;
break;
case nomem =>
abort("hashmap::iter: nomem");
};
};
return (it: *map::iterator);
};
export fn next(it: *iterator) (([]u8, *opaque) | done) = {
for (true) {
match (it.cur) {
case null =>
if (it.bi >= it.m.n) return done;
let b = it.m.buckets[it.bi];
it.bi += 1;
match (map::iter(b)) {
case let i: *map::iterator =>
it.cur = i;
case nomem =>
abort("hashmap::iter: nomem");
};
case let curi: *map::iterator =>
match (map::next(curi)) {
case let kv: ([]u8, *opaque) =>
return kv;
case done =>
it.cur = null;
};
};
};
};