// Copyright (c) 2026 moonbit-bimap contributors
// SPDX-License-Identifier: Apache-2.0
// Fail-fast iterators over a BiMap, in left-key insertion order. Each iterator
// snapshots the map's `version` at creation; any structural mutation bumps the
// version, so a subsequent `next()` aborts (genuine fail-fast, as fixed in
// indexmap 0.3.3).
///|
/// Return a lazy iterator over `(left, right)` pairs in left-key insertion
/// order. Supports `for (l, r) in m { ... }`. Aborts if the map is mutated
/// during iteration.
pub fn[L : Hash + Eq, R] BiMap::iter(self : BiMap[L, R]) -> Iter[(L, R)] {
let mut pos = 0
let len = self.order.length()
let version = self.version
Iter::new(
fn() -> (L, R)? {
if self.version != version {
abort("BiMap: map mutated during iteration")
}
while pos < len {
let l = self.order[pos]
pos = pos + 1
match self.forward.get(l) {
Some(r) => return Some((l, r))
None => continue
}
}
None
},
size_hint=len,
)
}
///|
/// Return a lazy iterator over the left keys in insertion order. Aborts if the
/// map is mutated during iteration.
pub fn[L : Hash + Eq, R] BiMap::lefts(self : BiMap[L, R]) -> Iter[L] {
let mut pos = 0
let len = self.order.length()
let version = self.version
Iter::new(
fn() -> L? {
if self.version != version {
abort("BiMap: map mutated during iteration")
}
while pos < len {
let l = self.order[pos]
pos = pos + 1
if self.forward.contains(l) {
return Some(l)
}
}
None
},
size_hint=len,
)
}
///|
/// Return a lazy iterator over the right values in insertion order. Aborts if
/// the map is mutated during iteration.
pub fn[L : Hash + Eq, R] BiMap::rights(self : BiMap[L, R]) -> Iter[R] {
let mut pos = 0
let len = self.order.length()
let version = self.version
Iter::new(
fn() -> R? {
if self.version != version {
abort("BiMap: map mutated during iteration")
}
while pos < len {
let l = self.order[pos]
pos = pos + 1
match self.forward.get(l) {
Some(r) => return Some(r)
None => continue
}
}
None
},
size_hint=len,
)
}