From a56cdabf5ef9ac3e65f626ce4d266d2cff22dee3 Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 20 Jul 2022 01:57:19 -0700 Subject: [PATCH] coremem_types: List: add an `apply_at` method --- crates/types/src/compound.rs | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/crates/types/src/compound.rs b/crates/types/src/compound.rs index af9fb45..59a45b3 100644 --- a/crates/types/src/compound.rs +++ b/crates/types/src/compound.rs @@ -31,6 +31,12 @@ impl LLNode { trait ListOp { /// apply `f` to all elements in the list. fn apply(&self, f: F); + /// apply `f` *only* to the element at the provided index + fn apply_at(&self, i: u32, f: F) { + self.apply_at_rel(i, 0, f); + } + // helper: tracks the current index into the list to know when to call `f` + fn apply_at_rel(&self, i: u32, cur: u32, f: F); } /// some operation which can be applied to the provided element type `T`. @@ -46,12 +52,24 @@ impl, E, N: ListOp> ListOp> for LLNode ListOp for Null { fn apply(&self, _f: F) { // the tail element simply terminates recursion } + fn apply_at_rel(&self, i: u32, cur: u32, _f: F) { + if i >= cur { + // if the requested index was past the length of the list, undef + unreachable!(); + } + } } #[cfg(test)] @@ -144,6 +162,27 @@ mod test { assert_eq!(acc.delayed2.into_inner(), V0(2u32).to_flat()); assert_eq!(acc.delayed1.into_inner(), V1(4f32).to_flat()); assert_eq!(acc.delayed0.into_inner(), V0(5u32).to_flat()); + } + #[test] + fn test_apply_at() { + let list = LLNode::new(V0(5u32)) + .prepend(V1(4f32)) + .prepend(V0(2u32)); + + let acc = ApplyAccumulator::default(); + list.apply_at(0, &acc); + assert_eq!(acc.delayed0.into_inner(), V0(2u32).to_flat()); + assert_eq!(acc.delayed1.into_inner(), Flat::default()); + + let acc = ApplyAccumulator::default(); + list.apply_at(1, &acc); + assert_eq!(acc.delayed0.into_inner(), V1(4f32).to_flat()); + assert_eq!(acc.delayed1.into_inner(), Flat::default()); + + let acc = ApplyAccumulator::default(); + list.apply_at(2, &acc); + assert_eq!(acc.delayed0.into_inner(), V0(5u32).to_flat()); + assert_eq!(acc.delayed1.into_inner(), Flat::default()); } }