//! A singly-linked list. //! //! Using this data structure only makes sense under very specific //! circumstances: //! //! - If you have a list that rarely stores more than one element, then this //! data-structure can store the element without allocating and only uses as //! much space as an `Option<(T, usize)>`. If T can double as the `Option` //! discriminant, it will even only be as large as `T, usize`. //! //! If you expect to store more than 1 element in the common case, steer clear //! and use a `Vec`, `Box<[T]>`, or a `SmallVec`. #[cfg(test)] mod tests; #[derive(Clone)] pub struct TinyList { head: Option>, } impl TinyList { #[inline] pub fn new() -> TinyList { TinyList { head: None } } #[inline] pub fn new_single(data: T) -> TinyList { TinyList { head: Some(Element { data, next: None }) } } #[inline] pub fn insert(&mut self, data: T) { self.head = Some(Element { data, next: self.head.take().map(Box::new) }); } #[inline] pub fn remove(&mut self, data: &T) -> bool { self.head = match self.head { Some(ref mut head) if head.data == *data => head.next.take().map(|x| *x), Some(ref mut head) => return head.remove_next(data), None => return false, }; true } #[inline] pub fn contains(&self, data: &T) -> bool { let mut elem = self.head.as_ref(); while let Some(ref e) = elem { if &e.data == data { return true; } elem = e.next.as_deref(); } false } } #[derive(Clone)] struct Element { data: T, next: Option>>, } impl Element { fn remove_next(&mut self, data: &T) -> bool { let mut n = self; loop { match n.next { Some(ref mut next) if next.data == *data => { n.next = next.next.take(); return true; } Some(ref mut next) => n = next, None => return false, } } } }