Add ElementMap::map

This commit is contained in:
2026-09-19 17:59:27 +02:00
parent 038e984c97
commit 345dbc0d5d
+41
View File
@@ -52,6 +52,32 @@ impl<E: Copy, T: Clone> ElementMap<E, T> {
pub fn reserve(&mut self, additional: usize) {
self.data.reserve(additional);
}
/// Returns a new map over the same elements with values transformed by `f`.
///
/// The default value of the new map is `f` applied to the original default, so reads beyond the
/// current capacity of the new map behave consistently with the transformation.
///
/// # Examples
///
/// ```
/// # use grapherity::maps::ElementMap;
/// let mut map: ElementMap<usize, Option<i32>> = ElementMap::new(None, |e| e, 0);
/// map[1] = Some(42);
///
/// let bools = map.map(|v| v.is_some());
/// assert_eq!(bools[0], false);
/// assert_eq!(bools[1], true);
/// // Returns mapped default for reads beyond capacity.
/// assert_eq!(bools[9], false);
/// ```
pub fn map<U: Clone>(&self, f: impl Fn(&T) -> U) -> ElementMap<E, U> {
ElementMap {
data: self.data.iter().map(|v| f(v)).collect(),
default: f(&self.default),
to_index: self.to_index,
}
}
}
impl<E: Copy, T: Clone> Index<E> for ElementMap<E, T> {
@@ -131,4 +157,19 @@ mod tests {
assert_eq!(map[1], 7, "unexpected read value after write");
assert_eq!(map[0], 0, "initial read should be default");
}
#[test]
fn map() {
let mut source: ElementMap<usize, Option<i32>> = ElementMap::new(None, |e| e, 0);
source[1] = Some(42);
source[2] = None;
let mapped = source.map(|v| v.is_some());
assert_eq!(mapped[0], false, "unset entry should map to false");
assert_eq!(mapped[1], true, "Some entry should map to true");
assert_eq!(mapped[2], false, "explicit None entry should map to false");
assert_eq!(
mapped[9], false,
"read beyond capacity should return mapped default"
);
}
}