use super::{Either, List, Slist, SlistSum};
pub trait SlistAsRef<'a, T: 'a>: Slist<T> {
type Result: Slist<&'a T>;
type ResultMut: Slist<&'a mut T>;
fn as_ref(&'a self) -> Self::Result;
fn as_mut(&'a mut self) -> Self::ResultMut;
}
impl<'a, T: 'a> SlistAsRef<'a, T> for () {
type Result = ();
type ResultMut = ();
#[inline]
fn as_ref(&'a self) -> Self::Result {}
#[inline]
fn as_mut(&'a mut self) -> Self::ResultMut {}
}
impl<'a, T: 'a, N, M, O> SlistAsRef<'a, T> for List<T, N>
where
N: SlistAsRef<'a, T, Result = M, ResultMut = O> + Slist<T>,
M: Slist<&'a T>,
O: Slist<&'a mut T>,
N::Filter: SlistSum<T, Next = N>,
M::Filter: SlistSum<&'a T, Next = M>,
O::Filter: SlistSum<&'a mut T, Next = O>,
{
type Result = List<&'a T, N::Result>;
type ResultMut = List<&'a mut T, N::ResultMut>;
#[inline]
fn as_ref(&'a self) -> Self::Result {
List {
head: &self.head,
tail: self.tail.as_ref(),
}
}
#[inline]
fn as_mut(&'a mut self) -> Self::ResultMut {
List {
head: &mut self.head,
tail: self.tail.as_mut(),
}
}
}
impl<'a, T: 'a, N: SlistAsRef<'a, T>, M: SlistAsRef<'a, T>> SlistAsRef<'a, T> for Either<N, M> {
type Result = Either<N::Result, M::Result>;
type ResultMut = Either<N::ResultMut, M::ResultMut>;
#[inline]
fn as_ref(&'a self) -> Self::Result {
match self {
Either::Left(n) => Either::Left(n.as_ref()),
Either::Right(m) => Either::Right(m.as_ref()),
}
}
#[inline]
fn as_mut(&'a mut self) -> Self::ResultMut {
match self {
Either::Left(n) => Either::Left(n.as_mut()),
Either::Right(m) => Either::Right(m.as_mut()),
}
}
}