From d0ae25e28bf562463e5498539fa46b6447e519fe Mon Sep 17 00:00:00 2001 From: colin Date: Wed, 20 Jul 2022 14:31:20 -0700 Subject: [PATCH] coremem_types: list: switch to parameter-based indexing; add apply method --- crates/types/src/compound/list.rs | 63 ++++++++++++++++++------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/crates/types/src/compound/list.rs b/crates/types/src/compound/list.rs index bafa88b..e781c36 100644 --- a/crates/types/src/compound/list.rs +++ b/crates/types/src/compound/list.rs @@ -154,24 +154,30 @@ impl ListOp for Null { } } +pub trait SameType { } +impl SameType for T { } + /// implemented on a list AND index, allowing potentially non-generic code to fetch a /// compile-time-constant element. -trait IndexOp { - // TODO: would be nice to make idx a fn parameter - fn get(&self, idx: Index) -> &Elem; - fn get_mut(&mut self, idx: Index) -> &mut Elem; - fn set(&mut self, idx: Index, el: Elem) { - *self.get_mut(idx) = el; +pub trait IndexOp { + fn apply, R, F: Fn(&Elem) -> R>(&self, f: F) -> R; + fn get>(&self) -> &Elem; + fn get_mut>(&mut self) -> &mut Elem; + fn set>(&mut self, el: Elem) { + *self.get_mut::() = el; } } /// zero-index into Self impl IndexOp, P0, H> for Node { - fn get(&self, _idx: P0) -> &H { + fn apply, R, F: Fn(&H) -> R>(&self, f: F) -> R { + f(&self.head) + } + fn get>(&self) -> &H { &self.head } - fn get_mut(&mut self, _idx: P0) -> &mut H { + fn get_mut>(&mut self) -> &mut H { &mut self.head } } @@ -182,11 +188,14 @@ where P: Peano, T: IndexOp { - fn get(&self, _idx: PNext

) -> &ElemAtP { - self.tail.get(P::default()) + fn apply>, R, F: Fn(&ElemAtP) -> R>(&self, f: F) -> R { + self.tail.apply::(f) } - fn get_mut(&mut self, _idx: PNext

) -> &mut ElemAtP { - self.tail.get_mut(P::default()) + fn get>>(&self) -> &ElemAtP { + self.tail.get::

() + } + fn get_mut>>(&mut self) -> &mut ElemAtP { + self.tail.get_mut::

() } } @@ -332,27 +341,27 @@ mod test { let list = Node::new_terminal(3f32) .prepend(4i32) .prepend(5u32); - assert_eq!(list.get(P0), &5u32); - assert_eq!(list.get(P1::default()), &4i32); - assert_eq!(list.get(P2::default()), &3f32); + assert_eq!(list.get::(), &5u32); + assert_eq!(list.get::(), &4i32); + assert_eq!(list.get::(), &3f32); } #[test] fn set() { let mut list = List::<(u32, i32, f32)>::default(); - list.set(P0, 5u32); + list.set::(5u32); - assert_eq!(list.get(P0), &5u32); - assert_eq!(list.get(P1::default()), &0i32); - assert_eq!(list.get(P2::default()), &0f32); + assert_eq!(list.get::(), &5u32); + assert_eq!(list.get::(), &0i32); + assert_eq!(list.get::(), &0f32); - list.set(P2::default(), 3f32); - list.set(P1::default(), 4i32); + list.set::(3f32); + list.set::(4i32); - assert_eq!(list.get(P0), &5u32); - assert_eq!(list.get(P1::default()), &4i32); - assert_eq!(list.get(P2::default()), &3f32); + assert_eq!(list.get::(), &5u32); + assert_eq!(list.get::(), &4i32); + assert_eq!(list.get::(), &3f32); } #[test] @@ -369,8 +378,8 @@ mod test { fn test_into_list() { let list = (5u32, 4i32, 3f32).into_list(); - assert_eq!(list.get(P0), &5u32); - assert_eq!(list.get(P1::default()), &4i32); - assert_eq!(list.get(P2::default()), &3f32); + assert_eq!(list.get::(), &5u32); + assert_eq!(list.get::(), &4i32); + assert_eq!(list.get::(), &3f32); } }