coremem_types: list: allow Peano-based index operation
This commit is contained in:
parent
159fa1b9a1
commit
3a235fe47e
|
@ -1,3 +1,5 @@
|
|||
use crate::compound::peano::{P0, Peano, PNext};
|
||||
|
||||
#[derive(Copy, Clone, Default, PartialEq)]
|
||||
struct Null;
|
||||
|
||||
|
@ -77,6 +79,13 @@ trait ElementOp<T> {
|
|||
fn call(&self, el: &T) -> Self::Output;
|
||||
}
|
||||
|
||||
impl<T, R, F: Fn(&T) -> R> ElementOp<T> for F {
|
||||
type Output = R;
|
||||
fn call(&self, el: &T) -> Self::Output {
|
||||
(self)(el)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Output, F, E, N> ListOp<F, LLNode<E, N>, Output> for LLNode<E, N>
|
||||
where
|
||||
F: ElementOp<E, Output=Output>,
|
||||
|
@ -101,15 +110,42 @@ impl<Output, F> ListOp<F, Null, Output> for Null {
|
|||
fn apply_all(&self, _f: F) {
|
||||
// the tail element simply terminates recursion
|
||||
}
|
||||
fn apply_at_rel(&self, i: u32, cur: u32, _f: F) -> Output {
|
||||
fn apply_at_rel(&self, _i: u32, _cur: u32, _f: F) -> Output {
|
||||
// it's expected that the element was found by now
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
/// implemented on a list AND index, allowing potentially non-generic code to fetch a
|
||||
/// compile-time-constant element.
|
||||
trait IndexOp<List, Index, Elem> {
|
||||
fn get(&self, idx: Index) -> &Elem;
|
||||
}
|
||||
|
||||
/// zero-index into Self
|
||||
impl<E, N> IndexOp<LLNode<E, N>, P0, E> for LLNode<E, N>
|
||||
{
|
||||
fn get(&self, _idx: P0) -> &E {
|
||||
&self.e
|
||||
}
|
||||
}
|
||||
|
||||
/// index N+1 into Self given that we know how to index N into Self::next
|
||||
impl<E, N, P, ElemAtP> IndexOp<LLNode<E, N>, PNext<P>, ElemAtP> for LLNode<E, N>
|
||||
where
|
||||
P: Peano,
|
||||
N: IndexOp<N, P, ElemAtP>
|
||||
{
|
||||
fn get(&self, _idx: PNext<P>) -> &ElemAtP {
|
||||
self.next.get(P::default())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::compound::peano::{P1, P2};
|
||||
use core::cell::Cell;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -242,6 +278,16 @@ mod test {
|
|||
assert_eq!(list.apply_at(2, ApplyAtRetOp), V0(5u32).to_flat());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get() {
|
||||
let list = LLNode::new(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);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list_builder() {
|
||||
let type_level = List::<(i32, f32, u32)>::default();
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
#[derive(Default)]
|
||||
pub struct PNext<P>(P);
|
||||
#[derive(Default)]
|
||||
pub struct P0;
|
||||
pub type P1 = PNext<P0>;
|
||||
pub type P2 = PNext<P1>;
|
||||
pub type P3 = PNext<P2>;
|
||||
pub type P4 = PNext<P3>;
|
||||
pub type P5 = PNext<P4>;
|
||||
pub type P6 = PNext<P5>;
|
||||
pub type P7 = PNext<P6>;
|
||||
|
||||
pub trait Peano {
|
||||
pub trait Peano: Default {
|
||||
type Next: PeanoNonZero;
|
||||
}
|
||||
|
||||
pub trait PeanoNonZero {
|
||||
pub trait PeanoNonZero: Peano {
|
||||
type Prev: Peano;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue