pub struct List<T: Clone>(_);Expand description
A persistent list.
This list is suitable for a single threaded environment. If you would like an immutable list that can be shared
across threads (i.e., is Send + Sync, see SharedList).
It’s implemented as an unrolled linked list, which is a single linked list which stores a variable amount of elements in each node. The capacity of any individual node for now is set to to be 256 elements, which means that until more than 256 elements are cons’d onto a list, it will remain a vector under the hood.
The list is also designed to leverage in place mutations whenever possible - if the number of references pointing to either a cell containing a vector or the shared vector is one, then that mutation is done in place. Otherwise, it is copy-on-write, maintaining our persistent invariant.
Performance Notes
The algorithmic complexity of an unrolled linked list matches that of a normal linked list - however in practice we have a decrease by the factor of the capacity of a node that gives us practical performance wins. For a list that is fully filled, iteration becomes O(n / 256), rather than the typical O(n). In addition, the unrolled linked list is able to avoid the costly cache misses that a typical linked list suffers from, seeing very realistic performance gains.
Let n be the number of elements in the list, and m is the capacity of a node. In the worst case, a node will be on average half filled. In the best case, all nodes are completely full. This means for operations that for a normal linked list may take linear time Θ(n), we get a constant factor decrease of either a factor of m or m / 2.
Implementations
sourceimpl<T: Clone> List<T>
impl<T: Clone> List<T>
sourcepub fn strong_count(&self) -> usize
pub fn strong_count(&self) -> usize
Get the number of strong references pointing to this list
Time: O(1)
sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Get the length of the list
Examples
let list = list![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
assert_eq!(list.len(), 10);sourcepub fn reverse(self) -> Self
pub fn reverse(self) -> Self
Reverses the input list and returns a new list
Examples
let list = list![1, 2, 3, 4, 5].reverse();
assert_eq!(list, list![5, 4, 3, 2, 1])sourcepub fn last(&self) -> Option<&T>
pub fn last(&self) -> Option<&T>
Get the last element of the list. Returns None if the list is empty.
Examples
let list = list![1, 2, 3, 4, 5];
assert_eq!(list.last().cloned(), Some(5));sourcepub fn car(&self) -> Option<T>
pub fn car(&self) -> Option<T>
Get the first element of the list. Returns None if the list is empty.
Examples
let list = list![1, 2, 3, 4, 5];
let car = list.car();
assert_eq!(car, Some(1));
let list: List<usize> = list![];
let car = list.car();
assert!(car.is_none());sourcepub fn first(&self) -> Option<&T>
pub fn first(&self) -> Option<&T>
Returns a reference to the first element of the list. Returns None if the list is empty.
Examples
let list = list![1, 2, 3, 4, 5];
let first = list.first().cloned();
assert_eq!(first, Some(1));
let list: List<usize> = list![];
let first = list.first();
assert!(first.is_none());sourcepub fn cdr(&self) -> Option<List<T>>
pub fn cdr(&self) -> Option<List<T>>
Get the “rest” of the elements as a list, excluding the first element
Examples
let list = list![1, 2, 3, 4, 5];
let cdr = list.cdr().unwrap();
assert_eq!(cdr, list![2, 3, 4, 5]);
let list = list![5];
let cdr = list.cdr();
assert!(cdr.is_none());sourcepub fn cdr_mut(&mut self) -> Option<&mut Self>
pub fn cdr_mut(&mut self) -> Option<&mut Self>
Gets the cdr of the list, mutably. Returns None if the next is empty - otherwise updates self to be the rest
Examples
let mut list = list![1, 2, 3, 4, 5];
list.cdr_mut().expect("This list has a tail");
assert_eq!(list, list![2, 3, 4, 5]);
let mut list = list![1, 2, 3];
assert!(list.cdr_mut().is_some());
assert_eq!(list, list![2, 3]);
assert!(list.cdr_mut().is_some());
assert_eq!(list, list![3]);
assert!(list.cdr_mut().is_none());
assert_eq!(list, list![]);sourcepub fn rest_mut(&mut self) -> Option<&mut Self>
pub fn rest_mut(&mut self) -> Option<&mut Self>
Gets the rest of the list, mutably.
Alias for cdr_mut
sourcepub fn cons(value: T, other: List<T>) -> List<T>
pub fn cons(value: T, other: List<T>) -> List<T>
Pushes an element onto the front of the list, returning a new list
Examples
let list = List::cons(1, List::cons(2, List::cons(3, List::cons(4, List::new()))));
assert_eq!(list, list![1, 2, 3, 4]);sourcepub fn cons_mut(&mut self, value: T)
pub fn cons_mut(&mut self, value: T)
Mutably pushes an element onto the front of the list, in place
Examples
let mut list = list![];
list.cons_mut(3);
list.cons_mut(2);
list.cons_mut(1);
list.cons_mut(0);
assert_eq!(list, list![0, 1, 2, 3])sourcepub fn push_front(&mut self, value: T)
pub fn push_front(&mut self, value: T)
Alias for cons_mut
Examples
let mut list = list![];
list.push_front(3);
list.push_front(2);
list.push_front(1);
list.push_front(0);
assert_eq!(list, list![0, 1, 2, 3])sourcepub fn pop_front(&mut self) -> Option<T>
pub fn pop_front(&mut self) -> Option<T>
Mutably pop the first value off of the list
Examples
let mut list = list![1, 2, 3];
assert_eq!(list.pop_front().unwrap(), 1);
assert_eq!(list.pop_front().unwrap(), 2);
assert_eq!(list.pop_front().unwrap(), 3);
assert!(list.pop_front().is_none())sourcepub fn push_back(&mut self, value: T)
pub fn push_back(&mut self, value: T)
Push one value to the back of the list
Time: O(n)
Examples
let mut list = list![];
list.push_back(0);
list.push_back(1);
list.push_back(2);
list.push_back(3);
assert_eq!(list, list![0, 1, 2, 3])sourcepub fn take(&self, count: usize) -> Self
pub fn take(&self, count: usize) -> Self
Construct a new list from the first count elements from the current list
Examples
let list = list![0, 1, 2, 3, 4, 5];
let new_list = list.take(3);
assert_eq!(new_list, list![0, 1, 2]);sourcepub fn tail(&self, len: usize) -> Option<Self>
pub fn tail(&self, len: usize) -> Option<Self>
Returns the list after the first len elements of lst.
If the list has fewer then len elements, then this returns None.
Examples
let list = list![0, 1, 2, 3, 4, 5];
let new_list = list.tail(2);
assert_eq!(new_list.unwrap(), list![2, 3, 4, 5]);
let no_list = list.tail(100);
assert!(no_list.is_none())sourcepub fn get(&self, index: usize) -> Option<&T>
pub fn get(&self, index: usize) -> Option<&T>
Get a reference to the value at index index in a list.
Returns None if the index is out of bounds.
sourcepub fn append(self, other: Self) -> Self
pub fn append(self, other: Self) -> Self
Append the list other to the end of the current list. Returns a new list.
Examples
let left = list![1usize, 2, 3];
let right = list![4usize, 5, 6];
assert_eq!(left.append(right), list![1, 2, 3, 4, 5, 6])sourcepub fn append_mut(&mut self, other: Self)
pub fn append_mut(&mut self, other: Self)
Append the list ‘other’ to the end of the current list in place.
Examples
let mut left = list![1usize, 2, 3];
let right = list![4usize, 5, 6];
left.append_mut(right);
assert_eq!(left, list![1, 2, 3, 4, 5, 6])sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Checks whether a list is empty
Examples
let mut list = List::new();
assert!(list.is_empty());
list.cons_mut("applesauce");
assert!(!list.is_empty());Trait Implementations
sourceimpl<T: Clone> Extend<T> for List<T>
impl<T: Clone> Extend<T> for List<T>
sourcefn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
Extends a collection with the contents of an iterator. Read more
sourcefn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one)Extends a collection with exactly one element.
sourcefn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one)Reserves capacity in a collection for the given number of additional elements. Read more
sourceimpl<'a, T: 'a + Clone> FromIterator<&'a List<T>> for List<T>
impl<'a, T: 'a + Clone> FromIterator<&'a List<T>> for List<T>
sourcefn from_iter<I: IntoIterator<Item = &'a List<T>>>(iter: I) -> Self
fn from_iter<I: IntoIterator<Item = &'a List<T>>>(iter: I) -> Self
Creates a value from an iterator. Read more
sourceimpl<T: Clone> FromIterator<List<T>> for List<T>
impl<T: Clone> FromIterator<List<T>> for List<T>
sourcefn from_iter<I: IntoIterator<Item = List<T>>>(iter: I) -> Self
fn from_iter<I: IntoIterator<Item = List<T>>>(iter: I) -> Self
Creates a value from an iterator. Read more
sourceimpl<T: Clone> FromIterator<T> for List<T>
impl<T: Clone> FromIterator<T> for List<T>
sourcefn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self
Creates a value from an iterator. Read more
sourceimpl<'a, T: Clone> IntoIterator for &'a List<T>
impl<'a, T: Clone> IntoIterator for &'a List<T>
sourceimpl<T: Clone> IntoIterator for List<T>
impl<T: Clone> IntoIterator for List<T>
sourceimpl<T: Clone + Ord> Ord for List<T>
impl<T: Clone + Ord> Ord for List<T>
sourceimpl<T: Clone + PartialOrd> PartialOrd<List<T>> for List<T>
impl<T: Clone + PartialOrd> PartialOrd<List<T>> for List<T>
sourcefn partial_cmp(&self, other: &Self) -> Option<Ordering>
fn partial_cmp(&self, other: &Self) -> Option<Ordering>
This method returns an ordering between self and other values if one exists. Read more
1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
fn lt(&self, other: &Rhs) -> bool
This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self and other) and is used by the <=
operator. Read more
impl<T: Clone + Eq> Eq for List<T>
Auto Trait Implementations
impl<T> RefUnwindSafe for List<T> where
T: RefUnwindSafe,
impl<T> !Send for List<T>
impl<T> !Sync for List<T>
impl<T> Unpin for List<T>
impl<T> UnwindSafe for List<T> where
T: RefUnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcefn clone_into(&self, target: &mut T)
fn clone_into(&self, target: &mut T)
toowned_clone_into)Uses borrowed data to replace owned data, usually by cloning. Read more