pub struct VecList<T> { /* private fields */ }
Expand description
A semi-doubly linked list implemented with a vector.
This provides many of the benefits of an actual linked list with a few tradeoffs. First, due to the use of an underlying vector, an individual insert operation may be O(n) due to allocating more space for the vector. However, it is amortized O(1) and it avoids the frequent allocations that traditional linked lists suffer from.
Another tradeoff is that extending a traditional linked list with another list is O(1) but a vector based implementation is O(n). Splicing has a similar disadvantage.
Lastly, the vector based implementation is likely to have better cache locality in general.
Implementations§
source§impl<T> VecList<T>
impl<T> VecList<T>
sourcepub fn back(&self) -> Option<&T>
pub fn back(&self) -> Option<&T>
Returns an immutable reference to the value at the back of the list, if it exists.
Complexity: O(1)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
assert_eq!(list.back(), None);
list.push_back(0);
list.push_back(5);
assert_eq!(list.back(), Some(&5));
sourcepub fn back_index(&self) -> Option<Index<T>>
pub fn back_index(&self) -> Option<Index<T>>
Returns the index of the value at the back of the list, if it exists.
Complexity: O(1)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
assert_eq!(list.back_index(), None);
list.push_back(0);
let index = list.push_back(5);
assert_eq!(list.back_index(), Some(index));
sourcepub fn back_mut(&mut self) -> Option<&mut T>
pub fn back_mut(&mut self) -> Option<&mut T>
Returns a mutable reference to the value at the back of the list, if it exists.
Complexity: O(1)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
assert_eq!(list.back_mut(), None);
list.push_back(0);
list.push_back(5);
let mut back = list.back_mut().unwrap();
assert_eq!(back, &mut 5);
*back *= 2;
assert_eq!(list.back(), Some(&10));
sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Returns the capacity of the list.
Examples
use dlv_list::VecList;
let list: VecList<u32> = VecList::new();
assert_eq!(list.capacity(), 0);
let list: VecList<u32> = VecList::with_capacity(10);
assert_eq!(list.capacity(), 10);
sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Removes all values from the list and invalidates all existing indices.
Complexity: O(n)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
list.push_back(5);
assert!(!list.is_empty());
list.clear();
assert!(list.is_empty());
sourcepub fn contains(&self, value: &T) -> boolwhere
T: PartialEq,
pub fn contains(&self, value: &T) -> boolwhere T: PartialEq,
Returns whether or not the list contains the given value.
Complexity: O(n)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
assert!(!list.contains(&0));
list.push_back(0);
assert!(list.contains(&0));
sourcepub fn drain(&mut self) -> Drain<'_, T> ⓘ
pub fn drain(&mut self) -> Drain<'_, T> ⓘ
Creates a draining iterator that removes all values from the list and yields them in order.
All values are removed even if the iterator is only partially consumed or not consumed at all.
Examples
use dlv_list::VecList;
let mut list = VecList::new();
list.push_back(0);
list.push_back(5);
{
let mut iter = list.drain();
assert_eq!(iter.next(), Some(0));
assert_eq!(iter.next(), Some(5));
assert_eq!(iter.next(), None);
}
println!("{}", list.len());
assert!(list.is_empty());
sourcepub fn front(&self) -> Option<&T>
pub fn front(&self) -> Option<&T>
Returns an immutable reference to the value at the front of the list, if it exists.
Complexity: O(1)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
assert_eq!(list.front(), None);
list.push_front(0);
list.push_front(5);
assert_eq!(list.front(), Some(&5));
sourcepub fn front_index(&self) -> Option<Index<T>>
pub fn front_index(&self) -> Option<Index<T>>
Returns the index of the value at the front of the list, if it exists.
Complexity: O(1)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
assert_eq!(list.front_index(), None);
list.push_front(0);
let index = list.push_front(5);
assert_eq!(list.front_index(), Some(index));
sourcepub fn front_mut(&mut self) -> Option<&mut T>
pub fn front_mut(&mut self) -> Option<&mut T>
Returns a mutable reference to the value at the front of the list, if it exists.
Complexity: O(1)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
assert_eq!(list.front_mut(), None);
list.push_front(0);
list.push_front(5);
let mut front = list.front_mut().unwrap();
assert_eq!(front, &mut 5);
*front *= 2;
assert_eq!(list.front(), Some(&10));
sourcepub fn get(&self, index: Index<T>) -> Option<&T>
pub fn get(&self, index: Index<T>) -> Option<&T>
Returns an immutable reference to the value at the given index.
If the index refers to an index not in the list anymore or if the index has been invalidated, then None
will
be returned.
Complexity: O(1)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
let index = list.push_front(0);
assert_eq!(list.get(index), Some(&0));
let index = list.push_front(5);
assert_eq!(list.get(index), Some(&5));
sourcepub unsafe fn get_unchecked(&self, index: Index<T>) -> &T
pub unsafe fn get_unchecked(&self, index: Index<T>) -> &T
Returns an immutable reference to the value at the given index.
Complexity: O(1)
Safety
Caller needs to guarantee that the index is in bound, and has never been removed from the list. This function does not perform generation checks. So if an element is removed then a new element is added at the same index, then the returned reference will be to the new element.
sourcepub fn get_mut(&mut self, index: Index<T>) -> Option<&mut T>
pub fn get_mut(&mut self, index: Index<T>) -> Option<&mut T>
Returns a mutable reference to the value at the given index.
If the index refers to an index not in the list anymore or if the index has been invalidated, then None
will
be returned.
Complexity: O(1)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
let index = list.push_front(0);
let value = list.get_mut(index).unwrap();
*value = 100;
assert_eq!(list.get(index), Some(&100));
sourcepub unsafe fn get_unchecked_mut(&mut self, index: Index<T>) -> &mut T
pub unsafe fn get_unchecked_mut(&mut self, index: Index<T>) -> &mut T
Returns an mutable reference to the value at the given index.
Safety
Caller needs to guarantee that the index is in bound, and has never been removed from the list.
See also: VecList::get_unchecked
.
Complexity: O(1)
sourcepub fn get_next_index(&self, index: Index<T>) -> Option<Index<T>>
pub fn get_next_index(&self, index: Index<T>) -> Option<Index<T>>
Returns the index of the value next to the value at the given index.
If the index refers to an index not in the list anymore or if the index has been invalidated, then None
will
be returned.
Complexity: O(1)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
let index_1 = list.push_back(0);
assert_eq!(list.get_next_index(index_1), None);
let index_2 = list.push_back(5);
assert_eq!(list.get_next_index(index_1), Some(index_2));
sourcepub fn get_previous_index(&self, index: Index<T>) -> Option<Index<T>>
pub fn get_previous_index(&self, index: Index<T>) -> Option<Index<T>>
Returns the index of the value previous to the value at the given index.
If the index refers to an index not in the list anymore or if the index has been invalidated, then None
will
be returned.
Complexity: O(1)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
let index_1 = list.push_front(0);
assert_eq!(list.get_previous_index(index_1), None);
let index_2 = list.push_front(5);
assert_eq!(list.get_previous_index(index_1), Some(index_2));
sourcepub fn move_after(&mut self, index: Index<T>, target: Index<T>)
pub fn move_after(&mut self, index: Index<T>, target: Index<T>)
Move the node at index
to after the node at target
.
Panics
Panics if either index
or target
is invalidated. Also panics if index
is the same as target
.
Examples
use dlv_list::VecList;
let mut list = VecList::new();
let index_1 = list.push_back(0);
let index_2 = list.push_back(1);
let index_3 = list.push_back(2);
let index_4 = list.push_back(3);
list.move_after(index_1, index_3);
assert_eq!(list.iter().copied().collect::<Vec<_>>(), vec![1, 2, 0, 3]);
assert_eq!(list.iter().rev().copied().collect::<Vec<_>>(), vec![3, 0, 2, 1]);
sourcepub fn move_before(&mut self, index: Index<T>, target: Index<T>)
pub fn move_before(&mut self, index: Index<T>, target: Index<T>)
Move the node at index
to before the node at target
.
Panics
Panics if either index
or target
is invalidated. Also panics if index
is the same as target
.
Examples
use dlv_list::VecList;
let mut list = VecList::new();
let index_1 = list.push_back(0);
let index_2 = list.push_back(1);
let index_3 = list.push_back(2);
let index_4 = list.push_back(3);
list.move_before(index_1, index_3);
assert_eq!(list.iter().copied().collect::<Vec<_>>(), vec![1, 0, 2, 3]);
assert_eq!(list.iter().rev().copied().collect::<Vec<_>>(), vec![3, 2, 0, 1]);
sourcepub fn indices(&self) -> Indices<'_, T> ⓘ
pub fn indices(&self) -> Indices<'_, T> ⓘ
Creates an indices iterator which will yield all indices of the list in order.
Examples
use dlv_list::VecList;
let mut list = VecList::new();
list.push_front(0);
list.push_front(5);
let mut indices = list.indices();
let index = indices.next().unwrap();
assert_eq!(list.get(index), Some(&5));
let index = indices.next().unwrap();
assert_eq!(list.get(index), Some(&0));
assert_eq!(indices.next(), None);
sourcepub fn insert_after(&mut self, index: Index<T>, value: T) -> Index<T>
pub fn insert_after(&mut self, index: Index<T>, value: T) -> Index<T>
Inserts the given value after the value at the given index.
The index of the newly inserted value will be returned.
Complexity: amortized O(1)
Panics
Panics if the index refers to an index not in the list anymore or if the index has been invalidated. This is enforced because this function will consume the value to be inserted, and if it cannot be inserted (due to the index not being valid), then it will be lost.
Also panics if the new capacity overflows usize
.
Examples
use dlv_list::VecList;
let mut list = VecList::new();
list.push_front(0);
let index_1 = list.push_front(5);
list.push_front(10);
let index_2 = list.insert_after(index_1, 1000);
assert_eq!(list.get_next_index(index_1), Some(index_2));
sourcepub fn insert_before(&mut self, index: Index<T>, value: T) -> Index<T>
pub fn insert_before(&mut self, index: Index<T>, value: T) -> Index<T>
Inserts the given value before the value at the given index.
The index of the newly inserted value will be returned.
Complexity: amortized O(1)
Panics
Panics if the index refers to an index not in the list anymore or if the index has been invalidated. This is enforced because this function will consume the value to be inserted, and if it cannot be inserted (due to the index not being valid), then it will be lost.
Also panics if the new capacity overflows usize
.
Examples
use dlv_list::VecList;
let mut list = VecList::new();
list.push_front(0);
let index_1 = list.push_front(5);
list.push_front(10);
let index_2 = list.insert_before(index_1, 1000);
assert_eq!(list.get_previous_index(index_1), Some(index_2));
sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns whether or not the list is empty.
Examples
use dlv_list::VecList;
let mut list = VecList::new();
assert!(list.is_empty());
list.push_back(0);
assert!(!list.is_empty());
sourcepub fn iter(&self) -> Iter<'_, T> ⓘ
pub fn iter(&self) -> Iter<'_, T> ⓘ
Creates an iterator that yields immutable references to values in the list in order.
Examples
use dlv_list::VecList;
let mut list = VecList::new();
list.push_back(0);
list.push_back(10);
list.push_back(200);
list.push_back(-10);
let mut iter = list.iter();
assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.next(), Some(&10));
assert_eq!(iter.next(), Some(&200));
assert_eq!(iter.next(), Some(&-10));
assert_eq!(iter.next(), None);
sourcepub fn iter_mut(&mut self) -> IterMut<'_, T> ⓘ
pub fn iter_mut(&mut self) -> IterMut<'_, T> ⓘ
Creates an iterator that yields mutable references to values in the list in order.
Examples
use dlv_list::VecList;
let mut list = VecList::new();
list.push_back(0);
list.push_back(10);
list.push_back(200);
list.push_back(-10);
let mut iter = list.iter_mut();
assert_eq!(iter.next(), Some(&mut 0));
assert_eq!(iter.next(), Some(&mut 10));
assert_eq!(iter.next(), Some(&mut 200));
assert_eq!(iter.next(), Some(&mut -10));
assert_eq!(iter.next(), None);
sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of values in the list.
Examples
use dlv_list::VecList;
let mut list = VecList::new();
assert_eq!(list.len(), 0);
list.push_back(0);
list.push_back(1);
list.push_back(2);
assert_eq!(list.len(), 3);
sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new list with no initial capacity.
Examples
use dlv_list::VecList;
let mut list = VecList::new();
let index = list.push_back(0);
assert_eq!(list.get(index), Some(&0));
sourcepub fn pack_to(
&mut self,
minimum_capacity: usize
) -> HashMap<Index<T>, Index<T>>
pub fn pack_to( &mut self, minimum_capacity: usize ) -> HashMap<Index<T>, Index<T>>
Reorganizes the existing values to ensure maximum cache locality and shrinks the list such that the capacity is
exactly [minimum_capacity
].
This function can be used to actually increase the capacity of the list.
Complexity: O(n)
Panics
Panics if the given minimum capacity is less than the current length of the list.
Examples
use dlv_list::VecList;
let mut list = VecList::new();
let index_1 = list.push_back(5);
let index_2 = list.push_back(10);
let index_3 = list.push_front(100);
list.remove(index_1);
assert!(list.capacity() >= 3);
let mut map = list.pack_to(list.len() + 5);
assert_eq!(list.capacity(), 7);
assert_eq!(map.len(), 2);
let index_2 = map.remove(&index_2).unwrap();
let index_3 = map.remove(&index_3).unwrap();
assert_eq!(list.get(index_2), Some(&10));
assert_eq!(list.get(index_3), Some(&100));
let mut iter = list.iter();
assert_eq!(iter.next(), Some(&100));
assert_eq!(iter.next(), Some(&10));
assert_eq!(iter.next(), None);
sourcepub fn pack_to_fit(&mut self) -> HashMap<Index<T>, Index<T>>
pub fn pack_to_fit(&mut self) -> HashMap<Index<T>, Index<T>>
Reorganizes the existing values to ensure maximum cache locality and shrinks the list such that no additional capacity exists.
This is equivalent to calling VecList::pack_to
with the current length.
Complexity: O(n)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
let index_1 = list.push_back(5);
let index_2 = list.push_back(10);
let index_3 = list.push_front(100);
list.remove(index_1);
assert!(list.capacity() >= 3);
let mut map = list.pack_to_fit();
assert_eq!(list.capacity(), 2);
assert_eq!(map.len(), 2);
let index_2 = map.remove(&index_2).unwrap();
let index_3 = map.remove(&index_3).unwrap();
assert_eq!(list.get(index_2), Some(&10));
assert_eq!(list.get(index_3), Some(&100));
let mut iter = list.iter();
assert_eq!(iter.next(), Some(&100));
assert_eq!(iter.next(), Some(&10));
assert_eq!(iter.next(), None);
sourcepub fn pop_back(&mut self) -> Option<T>
pub fn pop_back(&mut self) -> Option<T>
Removes and returns the value at the back of the list, if it exists.
Complexity: O(1)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
assert_eq!(list.pop_back(), None);
list.push_back(0);
list.push_back(1);
list.push_back(2);
assert_eq!(list.len(), 3);
assert_eq!(list.pop_back(), Some(2));
assert_eq!(list.len(), 2);
sourcepub fn pop_front(&mut self) -> Option<T>
pub fn pop_front(&mut self) -> Option<T>
Removes and returns the value at the front of the list, if it exists.
Complexity: O(1)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
assert_eq!(list.pop_front(), None);
list.push_front(0);
list.push_front(1);
list.push_front(2);
assert_eq!(list.len(), 3);
assert_eq!(list.pop_front(), Some(2));
assert_eq!(list.len(), 2);
sourcepub fn push_back(&mut self, value: T) -> Index<T>
pub fn push_back(&mut self, value: T) -> Index<T>
Inserts the given value to the back of the list.
The index of the newly inserted value will be returned.
Complexity: amortized O(1)
Panics
Panics if the new capacity overflows usize
.
Examples
use dlv_list::VecList;
let mut list = VecList::new();
let index = list.push_back(0);
assert_eq!(list.get(index), Some(&0));
sourcepub fn push_front(&mut self, value: T) -> Index<T>
pub fn push_front(&mut self, value: T) -> Index<T>
Inserts the given value to the front of the list.
The index of the newly inserted value will be returned.
Complexity: amortized O(1)
Panics
Panics if the new capacity overflows usize
.
Examples
use dlv_list::VecList;
let mut list = VecList::new();
let index = list.push_front(0);
assert_eq!(list.get(index), Some(&0));
sourcepub fn remove(&mut self, index: Index<T>) -> Option<T>
pub fn remove(&mut self, index: Index<T>) -> Option<T>
Removes and returns the value at the given index, if it exists.
If the index refers to an index not in the list anymore or if the index has been invalidated, then None
will
be returned and the list will be unaffected.
Complexity: O(1)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
let index = list.push_back(0);
assert_eq!(list.remove(index), Some(0));
assert_eq!(list.remove(index), None);
sourcepub fn reserve(&mut self, additional_capacity: usize)
pub fn reserve(&mut self, additional_capacity: usize)
Reserves capacity for the given expected size increase.
The collection may reserve more space to avoid frequent reallocations. After calling this function, capacity will
be greater than or equal to self.len() + additional_capacity
. Does nothing if the current capacity is already
sufficient.
Panics
Panics if the new capacity overflows usize
.
Examples
use dlv_list::VecList;
let mut list: VecList<u32> = VecList::new();
assert_eq!(list.capacity(), 0);
list.reserve(10);
assert!(list.capacity() >= 10);
sourcepub fn retain<Predicate>(&mut self, predicate: Predicate)where
Predicate: FnMut(&mut T) -> bool,
pub fn retain<Predicate>(&mut self, predicate: Predicate)where Predicate: FnMut(&mut T) -> bool,
Removes all elements from the list not satisfying the given predicate.
Complexity: O(n)
Examples
use dlv_list::VecList;
let mut list = VecList::new();
list.push_back(0);
list.push_back(-1);
list.push_back(1);
list.push_back(-2);
list.retain(|&mut value| value >= 0);
let mut iter = list.iter();
assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), None);
sourcepub fn with_capacity(capacity: usize) -> Self
pub fn with_capacity(capacity: usize) -> Self
Creates a new list with the given capacity.
Examples
use dlv_list::VecList;
let mut list: VecList<u32> = VecList::new();
assert_eq!(list.capacity(), 0);
let mut list: VecList<u32> = VecList::with_capacity(10);
assert_eq!(list.capacity(), 10);
Trait Implementations§
source§impl<'a, T> Extend<&'a T> for VecList<T>where
T: 'a + Copy,
impl<'a, T> Extend<&'a T> for VecList<T>where T: 'a + Copy,
source§fn extend<Iter>(&mut self, iter: Iter)where
Iter: IntoIterator<Item = &'a T>,
fn extend<Iter>(&mut self, iter: Iter)where Iter: IntoIterator<Item = &'a T>,
source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)source§impl<T> Extend<T> for VecList<T>
impl<T> Extend<T> for VecList<T>
source§fn extend<Iter>(&mut self, iter: Iter)where
Iter: IntoIterator<Item = T>,
fn extend<Iter>(&mut self, iter: Iter)where Iter: IntoIterator<Item = T>,
source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)source§impl<T> FromIterator<T> for VecList<T>
impl<T> FromIterator<T> for VecList<T>
source§fn from_iter<Iter>(iter: Iter) -> Selfwhere
Iter: IntoIterator<Item = T>,
fn from_iter<Iter>(iter: Iter) -> Selfwhere Iter: IntoIterator<Item = T>,
source§impl<'a, T> IntoIterator for &'a VecList<T>
impl<'a, T> IntoIterator for &'a VecList<T>
source§impl<'a, T> IntoIterator for &'a mut VecList<T>
impl<'a, T> IntoIterator for &'a mut VecList<T>
source§impl<T> IntoIterator for VecList<T>
impl<T> IntoIterator for VecList<T>
source§impl<T> Ord for VecList<T>where
T: Ord,
impl<T> Ord for VecList<T>where T: Ord,
source§impl<'a, T> PartialEq<&'a [T]> for VecList<T>where
T: PartialEq,
impl<'a, T> PartialEq<&'a [T]> for VecList<T>where T: PartialEq,
source§impl<T, const N: usize> PartialEq<[T; N]> for VecList<T>where
T: PartialEq,
impl<T, const N: usize> PartialEq<[T; N]> for VecList<T>where T: PartialEq,
source§impl<T> PartialEq<LinkedList<T>> for VecList<T>where
T: PartialEq,
impl<T> PartialEq<LinkedList<T>> for VecList<T>where T: PartialEq,
source§fn eq(&self, other: &LinkedList<T>) -> bool
fn eq(&self, other: &LinkedList<T>) -> bool
self
and other
values to be equal, and is used
by ==
.source§impl<T> PartialEq<Vec<T>> for VecList<T>where
T: PartialEq,
impl<T> PartialEq<Vec<T>> for VecList<T>where T: PartialEq,
source§impl<T> PartialEq<VecList<T>> for &[T]where
T: PartialEq,
impl<T> PartialEq<VecList<T>> for &[T]where T: PartialEq,
source§impl<T, const N: usize> PartialEq<VecList<T>> for [T; N]where
T: PartialEq,
impl<T, const N: usize> PartialEq<VecList<T>> for [T; N]where T: PartialEq,
source§impl<T> PartialEq<VecList<T>> for LinkedList<T>where
T: PartialEq,
impl<T> PartialEq<VecList<T>> for LinkedList<T>where T: PartialEq,
source§impl<T> PartialEq<VecList<T>> for Vec<T>where
T: PartialEq,
impl<T> PartialEq<VecList<T>> for Vec<T>where T: PartialEq,
source§impl<T> PartialEq for VecList<T>where
T: PartialEq,
impl<T> PartialEq for VecList<T>where T: PartialEq,
source§impl<T> PartialOrd for VecList<T>where
T: PartialOrd<T>,
impl<T> PartialOrd for VecList<T>where T: PartialOrd<T>,
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self
and other
) and is used by the <=
operator. Read more