coremem_types: list: switch to parameter-based indexing; add apply method
This commit is contained in:
@@ -154,24 +154,30 @@ impl<Output, F> ListOp<F, Null, Output> for Null {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait SameType<T> { }
|
||||
impl<T> SameType<T> for T { }
|
||||
|
||||
/// implemented on a list AND index, allowing potentially non-generic code to fetch a
|
||||
/// compile-time-constant element.
|
||||
trait IndexOp<List, Index, Elem> {
|
||||
// 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<List, Index, Elem> {
|
||||
fn apply<I: SameType<Index>, R, F: Fn(&Elem) -> R>(&self, f: F) -> R;
|
||||
fn get<I: SameType<Index>>(&self) -> &Elem;
|
||||
fn get_mut<I: SameType<Index>>(&mut self) -> &mut Elem;
|
||||
fn set<I: SameType<Index>>(&mut self, el: Elem) {
|
||||
*self.get_mut::<I>() = el;
|
||||
}
|
||||
}
|
||||
|
||||
/// zero-index into Self
|
||||
impl<H, T> IndexOp<Node<H, T>, P0, H> for Node<H, T>
|
||||
{
|
||||
fn get(&self, _idx: P0) -> &H {
|
||||
fn apply<I: SameType<P0>, R, F: Fn(&H) -> R>(&self, f: F) -> R {
|
||||
f(&self.head)
|
||||
}
|
||||
fn get<I: SameType<P0>>(&self) -> &H {
|
||||
&self.head
|
||||
}
|
||||
fn get_mut(&mut self, _idx: P0) -> &mut H {
|
||||
fn get_mut<I: SameType<P0>>(&mut self) -> &mut H {
|
||||
&mut self.head
|
||||
}
|
||||
}
|
||||
@@ -182,11 +188,14 @@ where
|
||||
P: Peano,
|
||||
T: IndexOp<T, P, ElemAtP>
|
||||
{
|
||||
fn get(&self, _idx: PNext<P>) -> &ElemAtP {
|
||||
self.tail.get(P::default())
|
||||
fn apply<I: SameType<PNext<P>>, R, F: Fn(&ElemAtP) -> R>(&self, f: F) -> R {
|
||||
self.tail.apply::<P, R, F>(f)
|
||||
}
|
||||
fn get_mut(&mut self, _idx: PNext<P>) -> &mut ElemAtP {
|
||||
self.tail.get_mut(P::default())
|
||||
fn get<I: SameType<PNext<P>>>(&self) -> &ElemAtP {
|
||||
self.tail.get::<P>()
|
||||
}
|
||||
fn get_mut<I: SameType<PNext<P>>>(&mut self) -> &mut ElemAtP {
|
||||
self.tail.get_mut::<P>()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::<P0>(), &5u32);
|
||||
assert_eq!(list.get::<P1>(), &4i32);
|
||||
assert_eq!(list.get::<P2>(), &3f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set() {
|
||||
let mut list = List::<(u32, i32, f32)>::default();
|
||||
|
||||
list.set(P0, 5u32);
|
||||
list.set::<P0>(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::<P0>(), &5u32);
|
||||
assert_eq!(list.get::<P1>(), &0i32);
|
||||
assert_eq!(list.get::<P2>(), &0f32);
|
||||
|
||||
list.set(P2::default(), 3f32);
|
||||
list.set(P1::default(), 4i32);
|
||||
list.set::<P2>(3f32);
|
||||
list.set::<P1>(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::<P0>(), &5u32);
|
||||
assert_eq!(list.get::<P1>(), &4i32);
|
||||
assert_eq!(list.get::<P2>(), &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::<P0>(), &5u32);
|
||||
assert_eq!(list.get::<P1>(), &4i32);
|
||||
assert_eq!(list.get::<P2>(), &3f32);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user