//! Crate that implements a semi-doubly linked list via a vector. //! //! See [`VecList`] for more information. //! //! # Features //! //! By default, this crate uses the Rust standard library. To disable this, disable the default //! `no_std` feature. Without this feature, certain methods will not be available. #![allow(unsafe_code)] #![cfg_attr(coverage_nightly, feature(coverage_attribute))] #![cfg_attr(not(any(feature = "std", test)), no_std)] extern crate alloc; use alloc::{collections::LinkedList, vec::Vec}; use core::{ cmp::Ordering, fmt::{self, Debug, Formatter}, hash::{Hash, Hasher}, hint::unreachable_unchecked, iter::{FromIterator, FusedIterator}, marker::PhantomData, mem, num::NonZeroUsize, ops, }; #[cfg(feature = "std")] use std::collections::HashMap; #[cfg(feature = "serde")] mod serde; /// Number type that's capable of representing [0, usize::MAX - 1] #[repr(transparent)] #[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)] struct NonMaxUsize(NonZeroUsize); impl Debug for NonMaxUsize { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "{}", self.get()) } } impl NonMaxUsize { /// Convert an index to a usize #[cfg_attr(mutants, mutants::skip)] #[inline] const fn get(&self) -> usize { self.0.get() - 1 } /// Create a new index from a usize, if `index` is `usize::MAX` then `None` is returned #[inline] const fn new(index: usize) -> Option { match NonZeroUsize::new(index.wrapping_add(1)) { Some(index) => Some(Self(index)), None => None, } } /// Create a new index from a usize, without checking if `index` is `usize::MAX`. /// /// # Safety /// /// `index` must not be `usize::MAX` #[cfg(feature = "std")] #[inline] const unsafe fn new_unchecked(index: usize) -> Self { Self(unsafe { NonZeroUsize::new_unchecked(index + 1) }) } /// Add an unsigned integer to a index. Check for bound violation and return `None` if the result will be larger than or equal to `usize::MAX` #[cfg(feature = "std")] #[inline] fn checked_add(&self, rhs: usize) -> Option { self.0.checked_add(rhs).map(Self) } /// Subtract an unsigned integer from a index. Check for bound violation and return `None` if the result will be less than 0. #[cfg(feature = "std")] #[inline] fn checked_sub(&self, rhs: usize) -> Option { // Safety: `self` is less than `usize::MAX`, so `self - rhs` can only be less than `usize::MAX` self .get() .checked_sub(rhs) .map(|i| unsafe { Self::new_unchecked(i) }) } #[cfg(feature = "std")] #[inline] const fn zero() -> Self { Self(unsafe { NonZeroUsize::new_unchecked(1) }) } } impl PartialEq for NonMaxUsize { fn eq(&self, other: &usize) -> bool { self.get() == *other } } impl PartialOrd for NonMaxUsize { fn partial_cmp(&self, other: &usize) -> Option { self.get().partial_cmp(other) } } /// 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. pub struct VecList { /// The backing storage for the list. This includes both used and unused indices. entries: Vec>, /// The current generation of the list. This is used to avoid the ABA problem. generation: u64, /// The index of the head of the list. head: Option, /// The length of the list since we cannot rely on the length of [`VecList::entries`] because it includes unused /// indices. length: usize, /// The index of the tail of the list. tail: Option, /// The index of the head of the vacant indices. vacant_head: Option, } impl Clone for VecList { fn clone(&self) -> Self { Self { entries: self.entries.clone(), generation: self.generation, head: self.head, length: self.length, tail: self.tail, vacant_head: self.vacant_head, } } fn clone_from(&mut self, source: &Self) { self.entries.clone_from(&source.entries); self.generation = source.generation; self.head = source.head; self.length = source.length; self.tail = source.tail; self.vacant_head = source.vacant_head; } } impl VecList { /// 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)); /// ``` #[must_use] pub fn back(&self) -> Option<&T> { let index = self.tail?.get(); match &self.entries[index] { Entry::Occupied(entry) => Some(&entry.value), _ => None, } } /// 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)); /// ``` #[must_use] pub fn back_index(&self) -> Option> { let index = self.tail?; let entry = self.entries[index.get()].occupied_ref(); let index = Index::new(index, entry.generation); Some(index) } /// 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)); /// ``` #[must_use] pub fn back_mut(&mut self) -> Option<&mut T> { let index = self.tail?.get(); match &mut self.entries[index] { Entry::Occupied(entry) => Some(&mut entry.value), _ => None, } } /// Returns the capacity of the list. /// /// # Examples /// /// ``` /// use dlv_list::VecList; /// /// let list: VecList = VecList::new(); /// assert_eq!(list.capacity(), 0); /// /// let list: VecList = VecList::with_capacity(10); /// assert_eq!(list.capacity(), 10); /// ``` #[must_use] pub fn capacity(&self) -> usize { self.entries.capacity() } /// 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()); /// ``` pub fn clear(&mut self) { self.entries.clear(); self.generation = self.generation.wrapping_add(1); self.head = None; self.length = 0; self.tail = None; self.vacant_head = None; } /// 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)); /// ``` #[must_use] pub fn contains(&self, value: &T) -> bool where T: PartialEq, { self.iter().any(|entry| entry == value) } /// 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()); /// ``` pub fn drain(&mut self) -> Drain<'_, T> { Drain { head: self.head, remaining: self.length, tail: self.tail, list: self, } } /// 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)); /// ``` #[must_use] pub fn front(&self) -> Option<&T> { let index = self.head?.get(); match &self.entries[index] { Entry::Occupied(entry) => Some(&entry.value), _ => None, } } /// 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)); /// ``` #[must_use] pub fn front_index(&self) -> Option> { let index = self.head?; let entry = self.entries[index.get()].occupied_ref(); let index = Index::new(index, entry.generation); Some(index) } /// 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)); /// ``` #[must_use] pub fn front_mut(&mut self) -> Option<&mut T> { let index = self.head?.get(); match &mut self.entries[index] { Entry::Occupied(entry) => Some(&mut entry.value), _ => None, } } /// 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)); /// ``` #[must_use] pub fn get(&self, index: Index) -> Option<&T> { match self.entries.get(index.index())? { Entry::Occupied(entry) if entry.generation == index.generation => Some(&entry.value), _ => None, } } /// 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. #[must_use] pub unsafe fn get_unchecked(&self, index: Index) -> &T { match unsafe { self.entries.get_unchecked(index.index()) } { Entry::Occupied(entry) => &entry.value, _ => unsafe { unreachable_unchecked() }, } } /// 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)); /// ``` #[must_use] pub fn get_mut(&mut self, index: Index) -> Option<&mut T> { match self.entries.get_mut(index.index())? { Entry::Occupied(entry) if entry.generation == index.generation => Some(&mut entry.value), _ => None, } } /// 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) #[must_use] pub unsafe fn get_unchecked_mut(&mut self, index: Index) -> &mut T { match unsafe { self.entries.get_unchecked_mut(index.index()) } { Entry::Occupied(entry) => &mut entry.value, _ => unsafe { unreachable_unchecked() }, } } /// 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)); /// ``` #[must_use] pub fn get_next_index(&self, index: Index) -> Option> { match self.entries.get(index.index())? { Entry::Occupied(entry) if entry.generation == index.generation => { let next_index = entry.next?; let next_entry = self.entries[next_index.get()].occupied_ref(); Some(Index::new(next_index, next_entry.generation)) } _ => None, } } /// 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)); /// ``` #[must_use] pub fn get_previous_index(&self, index: Index) -> Option> { match self.entries.get(index.index())? { Entry::Occupied(entry) if entry.generation == index.generation => { let previous_index = entry.previous?; let previous_entry = self.entries[previous_index.get()].occupied_ref(); Some(Index::new(previous_index, previous_entry.generation)) } _ => None, } } /// Connect the node at `index` to the node at `next`. If `index` is `None`, then the head will be /// set to `next`; if `next` is `None`, then the tail will be set to `index`. #[inline] fn update_link(&mut self, index: Option, next: Option) { if let Some(index) = index { let entry = self.entries[index.get()].occupied_mut(); entry.next = next; } else { self.head = next } if let Some(next) = next { let entry = self.entries[next.get()].occupied_mut(); entry.previous = index; } else { self.tail = index; } } /// 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![1, 2, 0, 3]); /// assert_eq!(list.iter().rev().copied().collect::>(), vec![3, 0, 2, 1]); /// ``` pub fn move_after(&mut self, index: Index, target: Index) { let (previous_index, next_index) = match &self.entries[index.index()] { Entry::Occupied(entry) if entry.generation == index.generation => { (entry.previous, entry.next) } _ => panic!("expected occupied entry with correct generation at `index`"), }; let target_next_index = match &self.entries[target.index()] { Entry::Occupied(entry) if entry.generation == target.generation => entry.next, _ => panic!("expected occupied entry with correct generation at `target`"), }; if target.index == index.index { panic!("cannot move after `index` itself"); } if previous_index == Some(target.index) { // Already in the right place return; } self.update_link(previous_index, next_index); self.update_link(Some(target.index), Some(index.index)); self.update_link(Some(index.index), target_next_index); } /// 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![1, 0, 2, 3]); /// assert_eq!(list.iter().rev().copied().collect::>(), vec![3, 2, 0, 1]); /// ``` pub fn move_before(&mut self, index: Index, target: Index) { let (previous_index, next_index) = match &self.entries[index.index()] { Entry::Occupied(entry) if entry.generation == index.generation => { (entry.previous, entry.next) } _ => panic!("expected occupied entry with correct generation at `index`"), }; let target_previous_index = match &self.entries[target.index()] { Entry::Occupied(entry) if entry.generation == target.generation => entry.previous, _ => panic!("expected occupied entry with correct generation at `target`"), }; if target.index == index.index { panic!("cannot move before `index` itself"); } if next_index == Some(target.index) { // Already in the right place return; } self.update_link(previous_index, next_index); self.update_link(Some(index.index), Some(target.index)); self.update_link(target_previous_index, Some(index.index)); } /// 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); /// ``` #[must_use] pub fn indices(&self) -> Indices<'_, T> { Indices { entries: &self.entries, head: self.head, remaining: self.length, tail: self.tail, } } /// 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)); /// ``` pub fn insert_after(&mut self, index: Index, value: T) -> Index { let next_index = match &mut self.entries[index.index()] { Entry::Occupied(entry) if entry.generation == index.generation => entry.next, _ => panic!("expected occupied entry with correct generation"), }; let new_index = self.insert_new(value, Some(index.index), next_index); let entry = self.entries[index.index()].occupied_mut(); entry.next = Some(new_index); if Some(index.index) == self.tail { self.tail = Some(new_index); } if let Some(next_index) = next_index { self.entries[next_index.get()].occupied_mut().previous = Some(new_index); } Index::new(new_index, self.generation) } /// 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)); /// ``` pub fn insert_before(&mut self, index: Index, value: T) -> Index { let previous_index = match &mut self.entries[index.index()] { Entry::Occupied(entry) if entry.generation == index.generation => entry.previous, _ => panic!("expected occupied entry with correct generation"), }; let new_index = self.insert_new(value, previous_index, Some(index.index)); let entry = self.entries[index.index()].occupied_mut(); entry.previous = Some(new_index); if Some(index.index) == self.head { self.head = Some(new_index); } if let Some(previous_index) = previous_index { self.entries[previous_index.get()].occupied_mut().next = Some(new_index); } Index::new(new_index, self.generation) } /// Inserts the given value into the list with the assumption that it is currently empty. /// /// # Panics /// /// Panics if the new capacity overflows `usize`. fn insert_empty(&mut self, value: T) -> Index { let generation = self.generation; let index = self.insert_new(value, None, None); self.head = Some(index); self.tail = Some(index); Index::new(index, generation) } /// Inserts the given value into the list with its expected previous and next value indices. /// /// # Panics /// /// Panics if the new capacity overflows `usize`. fn insert_new( &mut self, value: T, previous: Option, next: Option, ) -> NonMaxUsize { self.length += 1; if self.length == usize::max_value() { panic!("reached maximum possible length"); } match self.vacant_head { Some(index) => { self.vacant_head = self.entries[index.get()].vacant_ref().next; self.entries[index.get()] = Entry::Occupied(OccupiedEntry::new(self.generation, previous, next, value)); index } None => { self.entries.push(Entry::Occupied(OccupiedEntry::new( self.generation, previous, next, value, ))); NonMaxUsize::new(self.entries.len() - 1).unwrap() } } } /// 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()); /// ``` #[must_use] pub fn is_empty(&self) -> bool { self.length == 0 } /// 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); /// ``` #[must_use] pub fn iter(&self) -> Iter<'_, T> { Iter { entries: &self.entries, head: self.head, remaining: self.length, tail: self.tail, } } /// 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); /// ``` #[must_use] pub fn iter_mut(&mut self) -> IterMut<'_, T> { IterMut { entries: &mut self.entries, head: self.head, phantom: PhantomData, remaining: self.length, tail: self.tail, } } /// 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); /// ``` #[must_use] pub fn len(&self) -> usize { self.length } /// 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)); /// ``` #[must_use] pub fn new() -> Self { VecList::default() } /// 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); /// ``` #[cfg(feature = "std")] pub fn pack_to(&mut self, minimum_capacity: usize) -> HashMap, Index> { assert!( minimum_capacity >= self.length, "cannot shrink to capacity lower than current length" ); let mut count = NonMaxUsize::zero(); let mut entries = Vec::with_capacity(minimum_capacity); let generation = create_initial_generation(); let length = self.length; let mut map = HashMap::with_capacity(length); let mut next_index = self.head; while let Some(index) = next_index { let mut entry = self.remove_entry(index).expect("expected occupied entry"); next_index = entry.next; let _ = map.insert( Index::new(index, entry.generation), Index::new(count, generation), ); entry.generation = generation; entry.previous = if count > 0 { Some(count.checked_sub(1).unwrap()) } else { None }; entry.next = if count < length - 1 { Some(count.checked_add(1).expect("overflow")) } else { None }; entries.push(Entry::Occupied(entry)); count = count.checked_add(1).expect("overflow"); } self.entries = entries; self.generation = generation; self.length = length; self.vacant_head = None; if self.length > 0 { self.head = Some(NonMaxUsize::zero()); // Safety: `self.length - 1` is always less than `usize::MAX`. self.tail = Some(unsafe { NonMaxUsize::new_unchecked(length - 1) }); } else { self.head = None; self.tail = None; } map } /// 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); /// ``` #[cfg(feature = "std")] pub fn pack_to_fit(&mut self) -> HashMap, Index> { self.pack_to(self.length) } /// 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); /// ``` pub fn pop_back(&mut self) -> Option { self.remove_entry(self.tail?).map(|entry| entry.value) } /// 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); /// ``` pub fn pop_front(&mut self) -> Option { self.remove_entry(self.head?).map(|entry| entry.value) } /// 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)); /// ``` pub fn push_back(&mut self, value: T) -> Index { let tail_index = match self.tail { Some(index) => index, None => return self.insert_empty(value), }; let index = self.insert_new(value, Some(tail_index), None); self.entries[tail_index.get()].occupied_mut().next = Some(index); self.tail = Some(index); Index::new(index, self.generation) } /// 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)); /// ``` pub fn push_front(&mut self, value: T) -> Index { let head_index = match self.head { Some(index) => index, None => return self.insert_empty(value), }; let index = self.insert_new(value, None, Some(head_index)); self.entries[head_index.get()].occupied_mut().previous = Some(index); self.head = Some(index); Index::new(index, self.generation) } /// 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); /// ``` pub fn remove(&mut self, index: Index) -> Option { let (previous_index, next_index) = match &self.entries[index.index()] { Entry::Occupied(entry) if entry.generation == index.generation => { (entry.previous, entry.next) } _ => return None, }; Some( self .remove_helper(previous_index, index.index, next_index) .value, ) } /// Removes and returns the entry 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. fn remove_entry(&mut self, index: NonMaxUsize) -> Option> { let (previous_index, next_index) = match &self.entries[index.get()] { Entry::Occupied(entry) => (entry.previous, entry.next), Entry::Vacant(_) => return None, }; Some(self.remove_helper(previous_index, index, next_index)) } /// Removes and returns the entry at the given index with the entries previous and next index /// values. /// /// It is assumed that there is an entry at the given index. /// /// # Panics /// /// Panics if called when the list is empty. Behavior is undefined if provided indices do not follow the expected /// constraints. fn remove_helper( &mut self, previous_index: Option, index: NonMaxUsize, next_index: Option, ) -> OccupiedEntry { let head_index = self.head.expect("expected head index"); let tail_index = self.tail.expect("expected tail index"); let vacant_head = self.vacant_head; let removed_entry = mem::replace( &mut self.entries[index.get()], Entry::Vacant(VacantEntry::new(vacant_head)), ); self.generation = self.generation.wrapping_add(1); self.length -= 1; self.vacant_head = Some(index); if index == head_index && index == tail_index { self.head = None; self.tail = None; } else if index == head_index { self.entries[next_index.expect("expected next entry to exist").get()] .occupied_mut() .previous = None; self.head = next_index; } else if index == tail_index { self.entries[previous_index .expect("expected previous entry to exist") .get()] .occupied_mut() .next = None; self.tail = previous_index; } else { self.entries[next_index.expect("expected next entry to exist").get()] .occupied_mut() .previous = previous_index; self.entries[previous_index .expect("expected previous entry to exist") .get()] .occupied_mut() .next = next_index; } removed_entry.occupied() } /// 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 = VecList::new(); /// assert_eq!(list.capacity(), 0); /// /// list.reserve(10); /// assert!(list.capacity() >= 10); /// ``` pub fn reserve(&mut self, additional_capacity: usize) { self.entries.reserve(additional_capacity); } /// 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); /// ``` pub fn retain(&mut self, mut predicate: Predicate) where Predicate: FnMut(&mut T) -> bool, { let mut next_index = self.head; while let Some(index) = next_index { let entry = self.entries[index.get()].occupied_mut(); next_index = entry.next; if !predicate(&mut entry.value) { let _ = self.remove_entry(index); } } } /// Creates a new list with the given capacity. /// /// # Examples /// /// ``` /// use dlv_list::VecList; /// /// let mut list: VecList = VecList::new(); /// assert_eq!(list.capacity(), 0); /// /// let mut list: VecList = VecList::with_capacity(10); /// assert_eq!(list.capacity(), 10); /// ``` #[must_use] pub fn with_capacity(capacity: usize) -> Self { VecList { entries: Vec::with_capacity(capacity), generation: create_initial_generation(), head: None, length: 0, tail: None, vacant_head: None, } } } impl Debug for VecList where T: Debug, { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { formatter.debug_list().entries(self.iter()).finish() } } impl Default for VecList { fn default() -> Self { VecList { entries: Vec::default(), generation: create_initial_generation(), head: None, length: 0, tail: None, vacant_head: None, } } } impl Eq for VecList where T: Eq {} impl Extend for VecList { fn extend(&mut self, iter: Iter) where Iter: IntoIterator, { let iter = iter.into_iter(); self.reserve(iter.size_hint().0); for value in iter { let _ = self.push_back(value); } } } impl<'a, T> Extend<&'a T> for VecList where T: 'a + Copy, { fn extend(&mut self, iter: Iter) where Iter: IntoIterator, { self.extend(iter.into_iter().copied()); } } impl FromIterator for VecList { fn from_iter(iter: Iter) -> Self where Iter: IntoIterator, { let mut list = VecList::new(); list.extend(iter); list } } impl Hash for VecList where T: Hash, { fn hash(&self, state: &mut StateHasher) where StateHasher: Hasher, { self.len().hash(state); for value in self { value.hash(state); } } } impl ops::Index> for VecList { type Output = T; fn index(&self, index: Index) -> &Self::Output { self.get(index).expect("expected entry at index") } } impl ops::IndexMut> for VecList { fn index_mut(&mut self, index: Index) -> &mut Self::Output { self.get_mut(index).expect("expected entry at index") } } impl IntoIterator for VecList { type IntoIter = IntoIter; type Item = T; fn into_iter(self) -> Self::IntoIter { IntoIter { head: self.head, remaining: self.length, tail: self.tail, list: self, } } } impl<'a, T> IntoIterator for &'a VecList { type IntoIter = Iter<'a, T>; type Item = &'a T; fn into_iter(self) -> Self::IntoIter { Iter { entries: &self.entries, head: self.head, remaining: self.length, tail: self.tail, } } } impl<'a, T> IntoIterator for &'a mut VecList { type IntoIter = IterMut<'a, T>; type Item = &'a mut T; fn into_iter(self) -> Self::IntoIter { IterMut { entries: &mut self.entries, head: self.head, phantom: PhantomData, remaining: self.length, tail: self.tail, } } } impl Ord for VecList where T: Ord, { fn cmp(&self, other: &Self) -> Ordering { self.iter().cmp(other) } } impl PartialEq for VecList where T: PartialEq, { fn eq(&self, other: &Self) -> bool { self.len() == other.len() && self.iter().eq(other) } } impl PartialEq> for VecList where T: PartialEq, { fn eq(&self, other: &LinkedList) -> bool { self.len() == other.len() && self.iter().eq(other) } } impl PartialEq> for LinkedList where T: PartialEq, { fn eq(&self, other: &VecList) -> bool { other == self } } impl PartialEq> for VecList where T: PartialEq, { fn eq(&self, other: &Vec) -> bool { self.len() == other.len() && self.iter().eq(other) } } impl PartialEq> for Vec where T: PartialEq, { fn eq(&self, other: &VecList) -> bool { other == self } } impl PartialEq<[T; N]> for VecList where T: PartialEq, { fn eq(&self, other: &[T; N]) -> bool { self.len() == other.len() && self.iter().eq(other.iter()) } } impl PartialEq> for [T; N] where T: PartialEq, { fn eq(&self, other: &VecList) -> bool { other == self } } impl<'a, T> PartialEq<&'a [T]> for VecList where T: PartialEq, { fn eq(&self, other: &&'a [T]) -> bool { self.len() == other.len() && self.iter().eq(other.iter()) } } impl PartialEq> for &'_ [T] where T: PartialEq, { fn eq(&self, other: &VecList) -> bool { other == self } } impl PartialOrd for VecList where T: PartialOrd, { fn partial_cmp(&self, other: &Self) -> Option { self.iter().partial_cmp(other) } } /// A wrapper type that indicates an index into the list. /// /// This index may be invalidated by operations on the list itself. pub struct Index { /// The generation of the entry currently at this index. This is used to avoid the ABA problem. generation: u64, /// The actual index into the entry list. index: NonMaxUsize, /// This type is parameterized on the entry data type to avoid indices being used across differently typed lists. phantom: PhantomData, } impl Clone for Index { fn clone(&self) -> Self { *self } } impl Copy for Index {} impl Debug for Index { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { formatter .debug_tuple("Index") .field(&self.index) .field(&self.generation) .finish() } } impl Eq for Index {} impl Hash for Index { fn hash(&self, hasher: &mut StateHasher) where StateHasher: Hasher, { self.index.hash(hasher); self.generation.hash(hasher); } } impl PartialEq for Index { fn eq(&self, other: &Self) -> bool { self.generation == other.generation && self.index == other.index } } impl Index { /// Convenience function for creating new index. #[must_use] pub(self) fn new(index: NonMaxUsize, generation: u64) -> Index { Index { generation, index, phantom: PhantomData, } } /// Get the index as usize #[inline] pub(self) fn index(&self) -> usize { self.index.get() } } /// An entry in the list. This can be either occupied or vacant. #[derive(Clone)] enum Entry { /// An occupied entry contains actual entry data inserted by the user. Occupied(OccupiedEntry), /// A vacant entry is one that can be reused. Vacant(VacantEntry), } impl Entry { /// Returns the occupied entry by moving it out of the entry. /// /// # Panics /// /// Panics if the variant is actually [`Entry::Vacant`]. #[must_use] pub fn occupied(self) -> OccupiedEntry { match self { Entry::Occupied(entry) => entry, Entry::Vacant(_) => panic!("expected occupied entry"), } } /// Returns an immutable reference to the occupied entry. /// /// # Panics /// /// Panics if the variant is actually [`Entry::Vacant`]. #[must_use] pub fn occupied_ref(&self) -> &OccupiedEntry { match self { Entry::Occupied(entry) => entry, Entry::Vacant(_) => panic!("expected occupied entry"), } } /// Returns a mutable reference to the occupied entry. /// /// # Panics /// /// Panics if the variant is actually [`Entry::Vacant`]. #[must_use] pub fn occupied_mut(&mut self) -> &mut OccupiedEntry { match self { Entry::Occupied(entry) => entry, Entry::Vacant(_) => panic!("expected occupied entry"), } } /// Returns an immutable reference to the vacant entry. /// /// # Panics /// /// Panics if the variant is actually [`Entry::Occupied`]. #[must_use] pub fn vacant_ref(&self) -> &VacantEntry { match self { Entry::Vacant(entry) => entry, Entry::Occupied(_) => panic!("expected vacant entry"), } } } /// An occupied entry in the list. #[derive(Clone)] struct OccupiedEntry { /// The generation of when this entry was inserted. This is used to avoid the ABA problem. generation: u64, /// The index of the next occupied entry in the list. next: Option, /// The index of the previous occupied entry in the list. previous: Option, /// The actual value being stored in this entry. value: T, } impl OccupiedEntry { /// Convenience function for creating a new occupied entry. #[must_use] pub fn new( generation: u64, previous: Option, next: Option, value: T, ) -> OccupiedEntry { OccupiedEntry { generation, next, previous, value, } } } /// A vacant entry in the list. #[derive(Clone, Debug)] struct VacantEntry { /// The index of the next vacant entry in the list. next: Option, } impl VacantEntry { /// Convenience function for creating a new vacant entry. #[must_use] pub fn new(next: Option) -> VacantEntry { VacantEntry { next } } } /// An iterator that yields and removes all entries from the list. pub struct Drain<'a, T> { /// The index of the head of the unvisited portion of the list. head: Option, /// A reference to the entry list. list: &'a mut VecList, /// The number of entries that have not been visited. remaining: usize, /// The index of the tail of the unvisited portion of the list. tail: Option, } impl Drain<'_, T> { /// Creates an iterator that yields immutable references to entries in the list. #[must_use] pub fn iter(&self) -> Iter<'_, T> { Iter { entries: &self.list.entries, head: self.head, remaining: self.remaining, tail: self.tail, } } } impl Debug for Drain<'_, T> where T: Debug, { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { formatter.write_str("Drain(")?; formatter.debug_list().entries(self.iter()).finish()?; formatter.write_str(")") } } impl DoubleEndedIterator for Drain<'_, T> { fn next_back(&mut self) -> Option { if self.remaining == 0 { None } else { self.tail.map(|index| { let entry = self .list .remove_entry(index) .expect("expected occupied entry"); self.tail = entry.previous; self.remaining -= 1; entry.value }) } } } impl Drop for Drain<'_, T> { fn drop(&mut self) { self.list.clear(); } } impl ExactSizeIterator for Drain<'_, T> {} impl FusedIterator for Drain<'_, T> {} impl Iterator for Drain<'_, T> { type Item = T; fn next(&mut self) -> Option { if self.remaining == 0 { None } else { self.head.map(|index| { let entry = self .list .remove_entry(index) .expect("expected occupied entry"); self.head = entry.next; self.remaining -= 1; entry.value }) } } fn size_hint(&self) -> (usize, Option) { (self.remaining, Some(self.remaining)) } } /// An iterator that yields all indices in the list. pub struct Indices<'a, T> { /// A reference to the actual storage for the entry list. entries: &'a Vec>, /// The index of the head of the unvisited portion of the list. head: Option, /// The number of entries that have not been visited. remaining: usize, /// The index of the tail of the unvisited portion of the list. tail: Option, } impl Clone for Indices<'_, T> { fn clone(&self) -> Self { Indices { entries: self.entries, head: self.head, remaining: self.remaining, tail: self.tail, } } } impl Debug for Indices<'_, T> where T: Debug, { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { formatter.write_str("Indices(")?; formatter.debug_list().entries(self.clone()).finish()?; formatter.write_str(")") } } impl DoubleEndedIterator for Indices<'_, T> { fn next_back(&mut self) -> Option { if self.remaining == 0 { None } else { self.tail.map(|index| { let entry = self.entries[index.get()].occupied_ref(); let index = Index::new(index, entry.generation); self.tail = entry.previous; self.remaining -= 1; index }) } } } impl ExactSizeIterator for Indices<'_, T> {} impl FusedIterator for Indices<'_, T> {} impl Iterator for Indices<'_, T> { type Item = Index; fn next(&mut self) -> Option { if self.remaining == 0 { None } else { self.head.map(|index| { let entry = self.entries[index.get()].occupied_ref(); let index = Index::new(index, entry.generation); self.head = entry.next; self.remaining -= 1; index }) } } fn size_hint(&self) -> (usize, Option) { (self.remaining, Some(self.remaining)) } } /// An iterator that moves all entries out of the entry list. #[derive(Clone)] pub struct IntoIter { /// The index of the head of the unvisited portion of the list. head: Option, /// The entry list from which entries are yielded. list: VecList, /// The number of entries that have not been visited. remaining: usize, /// The index of the tail of the unvisited portion of the list. tail: Option, } impl IntoIter { /// Creates an iterator that yields immutable references to entries in the list. #[must_use] pub fn iter(&self) -> Iter<'_, T> { Iter { entries: &self.list.entries, head: self.head, remaining: self.remaining, tail: self.tail, } } } impl Debug for IntoIter where T: Debug, { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { formatter.write_str("IntoIter(")?; formatter.debug_list().entries(self.iter()).finish()?; formatter.write_str(")") } } impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option { if self.remaining == 0 { None } else { self.tail.map(|index| { let entry = self .list .remove_entry(index) .expect("expected occupied entry"); self.tail = entry.previous; self.remaining -= 1; entry.value }) } } } impl ExactSizeIterator for IntoIter {} impl FusedIterator for IntoIter {} impl Iterator for IntoIter { type Item = T; fn next(&mut self) -> Option { if self.remaining == 0 { None } else { self.head.map(|index| { let entry = self .list .remove_entry(index) .expect("expected occupied entry"); self.head = entry.next; self.remaining -= 1; entry.value }) } } fn size_hint(&self) -> (usize, Option) { (self.remaining, Some(self.remaining)) } } /// An iterator that yields immutable references to entries in the list. pub struct Iter<'a, T> { /// A reference to the actual storage for the entry list. entries: &'a Vec>, /// The index of the head of the unvisited portion of the list. head: Option, /// The number of entries that have not been visited. remaining: usize, /// The index of the tail of the unvisited portion of the list. tail: Option, } impl<'a, T> Clone for Iter<'a, T> { fn clone(&self) -> Iter<'a, T> { Iter { entries: self.entries, head: self.head, remaining: self.remaining, tail: self.tail, } } } impl Debug for Iter<'_, T> where T: Debug, { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { formatter.write_str("Iter(")?; formatter.debug_list().entries(self.clone()).finish()?; formatter.write_str(")") } } impl DoubleEndedIterator for Iter<'_, T> { fn next_back(&mut self) -> Option { if self.remaining == 0 { None } else { self.tail.map(|index| { let entry = self.entries[index.get()].occupied_ref(); self.tail = entry.previous; self.remaining -= 1; &entry.value }) } } } impl ExactSizeIterator for Iter<'_, T> {} impl FusedIterator for Iter<'_, T> {} impl<'a, T> Iterator for Iter<'a, T> { type Item = &'a T; fn next(&mut self) -> Option { if self.remaining == 0 { None } else { self.head.map(|index| { let entry = self.entries[index.get()].occupied_ref(); self.head = entry.next; self.remaining -= 1; &entry.value }) } } fn size_hint(&self) -> (usize, Option) { (self.remaining, Some(self.remaining)) } } /// An iterator that yields mutable references to entries in the list. pub struct IterMut<'a, T> { entries: *mut Vec>, /// The index of the head of the unvisited portion of the list. head: Option, /// Because [`IterMut::entries`] is a pointer, we need to have a phantom data here for the lifetime parameter. phantom: PhantomData<&'a mut Vec>>, /// The number of entries that have not been visited. remaining: usize, /// The index of the tail of the unvisited portion of the list. tail: Option, } impl IterMut<'_, T> { /// Creates an iterator that yields immutable references to entries in the list. #[must_use] pub fn iter(&self) -> Iter<'_, T> { Iter { entries: unsafe { &*self.entries }, head: self.head, remaining: self.remaining, tail: self.tail, } } } impl Debug for IterMut<'_, T> where T: Debug, { fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result { formatter.write_str("IterMut(")?; formatter.debug_list().entries(self.iter()).finish()?; formatter.write_str(")") } } impl DoubleEndedIterator for IterMut<'_, T> { fn next_back(&mut self) -> Option { if self.remaining == 0 { None } else { self.tail.map(|index| { let entry = unsafe { &mut (*self.entries)[index.get()] }.occupied_mut(); self.tail = entry.previous; self.remaining -= 1; &mut entry.value }) } } } impl ExactSizeIterator for IterMut<'_, T> {} impl FusedIterator for IterMut<'_, T> {} impl<'a, T> Iterator for IterMut<'a, T> { type Item = &'a mut T; fn next(&mut self) -> Option { if self.remaining == 0 { None } else { self.head.map(|index| { let entry = unsafe { &mut (*self.entries)[index.get()] }.occupied_mut(); self.head = entry.next; self.remaining -= 1; &mut entry.value }) } } fn size_hint(&self) -> (usize, Option) { (self.remaining, Some(self.remaining)) } } unsafe impl Send for IterMut<'_, T> where T: Send {} unsafe impl Sync for IterMut<'_, T> where T: Sync {} /// Creates the initial generation seeded by the current time. #[must_use] fn create_initial_generation() -> u64 { #[cfg(feature = "std")] { use std::{collections::hash_map::RandomState, hash::BuildHasher}; let mut hasher = RandomState::new().build_hasher(); hasher.write_u32(0); hasher.finish() } #[cfg(not(feature = "std"))] { use core::sync::atomic::{AtomicU32, Ordering}; // Generate a u32 randomly. #[cfg_attr(mutants, mutants::skip)] fn gen_u32() -> u32 { static SEED: AtomicU32 = AtomicU32::new({ // Random seed generated at compile time. const_random::const_random!(u32) }); // Xorshift is "good enough" in most cases. let mut x = SEED.load(Ordering::Relaxed); loop { let mut random = x; random ^= random << 13; random ^= random >> 17; random ^= random << 5; // Put the new seed in. if let Err(actual) = SEED.compare_exchange(x, random, Ordering::SeqCst, Ordering::SeqCst) { x = actual; } else { return random; } } } // Put two u32's together gen_u32() as u64 | ((gen_u32() as u64) << 32) } } #[allow(unused_results)] #[cfg(test)] mod test { use coverage_helper::test; use super::*; use alloc::{format, vec}; #[cfg(feature = "std")] use std::{collections::hash_map::RandomState, hash::BuildHasher}; #[test] fn test_bounds() { fn check_bounds() {} check_bounds::>(); check_bounds::>(); check_bounds::>(); check_bounds::>(); check_bounds::>(); check_bounds::>(); check_bounds::>(); } #[cfg(feature = "std")] #[test] fn test_non_max_usize_eq() { let zero = NonMaxUsize::zero(); assert_eq!(zero, 0usize); assert_ne!(zero, 1usize); } #[test] fn test_drain_debug() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let drain = list.drain(); assert_eq!(format!("{drain:?}"), "Drain([0, 1, -1, 2, -2])"); } #[test] fn test_drain_double_ended() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let mut drain = list.drain(); assert_eq!(drain.next(), Some(0)); assert_eq!(drain.next_back(), Some(-2)); assert_eq!(drain.next(), Some(1)); assert_eq!(drain.next_back(), Some(2)); assert_eq!(drain.next(), Some(-1)); assert_eq!(drain.next_back(), None); } #[test] fn test_drain_empty() { let mut list: VecList = VecList::new(); let mut drain = list.drain(); assert_eq!(drain.next(), None); } #[test] fn test_drain_fused() { let mut list: VecList = VecList::new(); list.push_back(0); let mut drain = list.drain(); assert_eq!(drain.next(), Some(0)); assert_eq!(drain.next(), None); assert_eq!(drain.next(), None); assert_eq!(drain.next(), None); } #[test] fn test_drain_size_hint() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let mut drain = list.drain(); assert_eq!(drain.size_hint(), (5, Some(5))); drain.next(); assert_eq!(drain.size_hint(), (4, Some(4))); drain.next(); assert_eq!(drain.size_hint(), (3, Some(3))); drain.next(); assert_eq!(drain.size_hint(), (2, Some(2))); drain.next(); assert_eq!(drain.size_hint(), (1, Some(1))); drain.next(); assert_eq!(drain.size_hint(), (0, Some(0))); } #[test] fn test_index_debug() { let mut list = VecList::new(); let index = list.push_back(5); assert_eq!( format!("{index:?}"), format!("Index(0, {})", index.generation) ); } #[test] fn test_index_equality() { let mut list = VecList::new(); let index_1 = list.push_back(0); let index_2 = list.indices().next().unwrap(); assert_eq!(index_1, index_2); let index_3 = list.push_back(1); assert_ne!(index_1, index_3); } #[cfg(feature = "std")] #[test] fn test_index_hash() { let state = RandomState::new(); fn hash(state: &RandomState, value: &Index) -> u64 { let mut hasher = state.build_hasher(); value.hash(&mut hasher); hasher.finish() } let mut list = VecList::new(); let index_1 = list.push_back(0); let index_2 = list.push_back(2); assert_eq!(hash(&state, &index_1), hash(&state, &index_1)); assert_ne!(hash(&state, &index_1), hash(&state, &index_2)); } #[test] fn test_indices_debug() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let indices = list.indices(); assert_eq!( format!("{indices:?}"), format!( "Indices([Index(0, {}), Index(1, {}), Index(2, {}), Index(3, {}), Index(4, {})])", list.generation, list.generation, list.generation, list.generation, list.generation ) ); } #[test] fn test_indices_double_ended() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let mut indices = list.indices(); assert_eq!(indices.next().unwrap().index.get(), 0); assert_eq!(indices.next_back().unwrap().index.get(), 4); assert_eq!(indices.next().unwrap().index.get(), 1); assert_eq!(indices.next_back().unwrap().index.get(), 3); assert_eq!(indices.next().unwrap().index.get(), 2); assert_eq!(indices.next_back(), None); } #[test] fn test_indices_empty() { let list: VecList = VecList::new(); let mut indices = list.indices(); assert_eq!(indices.next(), None); } #[test] fn test_indices_fused() { let mut list: VecList = VecList::new(); list.push_back(0); let mut indices = list.indices(); assert_eq!(indices.next().unwrap().index.get(), 0); assert_eq!(indices.next(), None); assert_eq!(indices.next(), None); assert_eq!(indices.next(), None); } #[test] fn test_indices_size_hint() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let mut indices = list.indices(); assert_eq!(indices.size_hint(), (5, Some(5))); indices.next(); assert_eq!(indices.size_hint(), (4, Some(4))); indices.next(); assert_eq!(indices.size_hint(), (3, Some(3))); indices.next(); assert_eq!(indices.size_hint(), (2, Some(2))); indices.next(); assert_eq!(indices.size_hint(), (1, Some(1))); indices.next(); assert_eq!(indices.size_hint(), (0, Some(0))); } #[test] fn test_into_iter_debug() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let iter = list.into_iter(); assert_eq!(format!("{iter:?}"), "IntoIter([0, 1, -1, 2, -2])"); } #[test] fn test_into_iter_double_ended() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let mut iter = list.into_iter(); assert_eq!(iter.next(), Some(0)); assert_eq!(iter.next_back(), Some(-2)); assert_eq!(iter.next(), Some(1)); assert_eq!(iter.next_back(), Some(2)); assert_eq!(iter.next(), Some(-1)); assert_eq!(iter.next_back(), None); } #[test] fn test_into_iter_empty() { let list: VecList = VecList::new(); let mut iter = list.into_iter(); assert_eq!(iter.next(), None); } #[test] fn test_into_iter_fused() { let mut list: VecList = VecList::new(); list.push_back(0); let mut iter = list.into_iter(); assert_eq!(iter.next(), Some(0)); assert_eq!(iter.next(), None); assert_eq!(iter.next(), None); assert_eq!(iter.next(), None); } #[test] fn test_into_iter_size_hint() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let mut iter = list.into_iter(); assert_eq!(iter.size_hint(), (5, Some(5))); iter.next(); assert_eq!(iter.size_hint(), (4, Some(4))); iter.next(); assert_eq!(iter.size_hint(), (3, Some(3))); iter.next(); assert_eq!(iter.size_hint(), (2, Some(2))); iter.next(); assert_eq!(iter.size_hint(), (1, Some(1))); iter.next(); assert_eq!(iter.size_hint(), (0, Some(0))); } #[test] fn test_iter_debug() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let iter = list.iter(); assert_eq!(format!("{iter:?}"), "Iter([0, 1, -1, 2, -2])"); } #[test] fn test_iter_double_ended() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let mut iter = list.iter(); assert_eq!(iter.next(), Some(&0)); assert_eq!(iter.next_back(), Some(&-2)); assert_eq!(iter.next(), Some(&1)); assert_eq!(iter.next_back(), Some(&2)); assert_eq!(iter.next(), Some(&-1)); assert_eq!(iter.next_back(), None); } #[test] fn test_iter_empty() { let list: VecList = VecList::new(); let mut iter = list.iter(); assert_eq!(iter.next(), None); } #[test] fn test_iter_fused() { let mut list: VecList = VecList::new(); list.push_back(0); let mut iter = list.iter(); assert_eq!(iter.next(), Some(&0)); assert_eq!(iter.next(), None); assert_eq!(iter.next(), None); assert_eq!(iter.next(), None); } #[test] fn test_iter_size_hint() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let mut iter = list.iter(); assert_eq!(iter.size_hint(), (5, Some(5))); iter.next(); assert_eq!(iter.size_hint(), (4, Some(4))); iter.next(); assert_eq!(iter.size_hint(), (3, Some(3))); iter.next(); assert_eq!(iter.size_hint(), (2, Some(2))); iter.next(); assert_eq!(iter.size_hint(), (1, Some(1))); iter.next(); assert_eq!(iter.size_hint(), (0, Some(0))); } #[test] fn test_iter_mut_debug() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let iter = list.iter_mut(); assert_eq!(format!("{iter:?}"), "IterMut([0, 1, -1, 2, -2])"); } #[test] fn test_iter_mut_double_ended() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let mut iter = list.iter_mut(); assert_eq!(iter.next(), Some(&mut 0)); assert_eq!(iter.next_back(), Some(&mut -2)); assert_eq!(iter.next(), Some(&mut 1)); assert_eq!(iter.next_back(), Some(&mut 2)); assert_eq!(iter.next(), Some(&mut -1)); assert_eq!(iter.next_back(), None); } #[test] fn test_iter_mut_empty() { let mut list: VecList = VecList::new(); let mut iter = list.iter_mut(); assert_eq!(iter.next(), None); } #[test] fn test_iter_mut_fused() { let mut list: VecList = VecList::new(); list.push_back(0); let mut iter = list.iter_mut(); assert_eq!(iter.next(), Some(&mut 0)); assert_eq!(iter.next(), None); assert_eq!(iter.next(), None); assert_eq!(iter.next(), None); } #[test] fn test_iter_mut_size_hint() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); let mut iter = list.iter_mut(); assert_eq!(iter.size_hint(), (5, Some(5))); iter.next(); assert_eq!(iter.size_hint(), (4, Some(4))); iter.next(); assert_eq!(iter.size_hint(), (3, Some(3))); iter.next(); assert_eq!(iter.size_hint(), (2, Some(2))); iter.next(); assert_eq!(iter.size_hint(), (1, Some(1))); iter.next(); assert_eq!(iter.size_hint(), (0, Some(0))); } #[test] fn test_vec_list_back() { let mut list = VecList::new(); assert_eq!(list.back(), None); let index_1 = list.push_back(0); assert_eq!(list.back(), Some(&0)); let index_2 = list.push_back(1); assert_eq!(list.back(), Some(&1)); list.remove(index_2); assert_eq!(list.back(), Some(&0)); list.remove(index_1); assert_eq!(list.back(), None); } #[test] fn test_vec_list_back_mut() { let mut list = VecList::new(); assert_eq!(list.back_mut(), None); let index_1 = list.push_back(0); assert_eq!(list.back_mut(), Some(&mut 0)); let index_2 = list.push_back(1); assert_eq!(list.back_mut(), Some(&mut 1)); list.remove(index_2); assert_eq!(list.back_mut(), Some(&mut 0)); list.remove(index_1); assert_eq!(list.back_mut(), None); } #[test] fn test_vec_list_capacity() { let list: VecList = VecList::new(); assert_eq!(list.capacity(), 0); } #[test] fn test_vec_list_clear() { let mut list = VecList::new(); let index = list.push_back(0); list.clear(); assert!(list.is_empty()); assert_eq!(list.get(index), None); } #[test] fn test_vec_list_contains() { let mut list = VecList::new(); assert!(!list.contains(&0)); let index = list.push_back(0); assert!(list.contains(&0)); list.remove(index); assert!(!list.contains(&0)); } #[test] fn test_vec_list_drain() { let mut list = VecList::new(); list.drain(); assert!(list.is_empty()); list.push_back(0); list.push_back(1); list.push_back(-1); list.drain(); assert!(list.is_empty()); } #[test] fn test_vec_list_debug() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); assert_eq!(format!("{list:?}"), "[0, 1, -1, 2, -2]"); } #[test] fn test_vec_list_equality() { let mut list_1 = VecList::new(); list_1.push_back(0); list_1.push_back(1); list_1.push_back(-1); list_1.push_back(2); list_1.push_back(-2); assert_eq!(list_1, Vec::from_iter([0, 1, -1, 2, -2])); assert_eq!(Vec::from_iter([0, 1, -1, 2, -2]), list_1); assert_ne!(list_1, Vec::new()); assert_ne!(Vec::new(), list_1); assert_eq!(list_1, LinkedList::from_iter([0, 1, -1, 2, -2])); assert_eq!(LinkedList::from_iter([0, 1, -1, 2, -2]), list_1); assert_ne!(list_1, LinkedList::new()); assert_ne!(LinkedList::new(), list_1); assert_eq!(list_1, [0, 1, -1, 2, -2]); assert_eq!([0, 1, -1, 2, -2], list_1); assert_ne!(list_1, []); assert_ne!([], list_1); assert_eq!(list_1, [0, 1, -1, 2, -2].as_slice()); assert_eq!([0, 1, -1, 2, -2].as_slice(), list_1); assert_ne!(list_1, [].as_slice()); assert_ne!([].as_slice(), list_1); let mut list_2 = list_1.clone(); list_2.pop_back(); assert_ne!(list_1, list_2); list_2.push_back(-2); assert_eq!(list_1, list_2); } #[cfg(feature = "std")] #[test] fn test_vec_list_hash() { let state = RandomState::new(); fn hash(state: &RandomState, value: &VecList) -> u64 { let mut hasher = state.build_hasher(); value.hash(&mut hasher); hasher.finish() } let mut list_1 = VecList::new(); list_1.push_back(0); let list_2 = VecList::new(); assert_eq!(hash(&state, &list_1), hash(&state, &list_1)); assert_ne!(hash(&state, &list_1), hash(&state, &list_2)); } #[test] fn test_vec_list_extend() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.extend([-1, 2, -2].iter()); assert_eq!(list, &[0, 1, -1, 2, -2][..]); } #[test] fn test_vec_list_from_iterator() { let list = VecList::from_iter([0, 1, -1, 2, -2].iter().cloned()); assert_eq!(list, &[0, 1, -1, 2, -2][..]); } #[test] fn test_vec_list_front() { let mut list = VecList::new(); assert_eq!(list.front(), None); let index_1 = list.push_front(0); assert_eq!(list.front(), Some(&0)); let index_2 = list.push_front(1); assert_eq!(list.front(), Some(&1)); list.remove(index_2); assert_eq!(list.front(), Some(&0)); list.remove(index_1); assert_eq!(list.front(), None); } #[test] fn test_vec_list_front_mut() { let mut list = VecList::new(); assert_eq!(list.front_mut(), None); let index_1 = list.push_front(0); assert_eq!(list.front_mut(), Some(&mut 0)); let index_2 = list.push_front(1); assert_eq!(list.front_mut(), Some(&mut 1)); list.remove(index_2); assert_eq!(list.front_mut(), Some(&mut 0)); list.remove(index_1); assert_eq!(list.front_mut(), None); } #[cfg(feature = "std")] #[test] fn test_vec_list_get() { let mut list = VecList::new(); let index = list.push_back(0); assert_eq!(list.get(index), Some(&0)); list.remove(index); assert_eq!(list.get(index), None); 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); list.remove(index_1); list.pack_to_fit(); assert_eq!(list.get(index_1), None); assert_eq!(list.get(index_2), None); assert_eq!(list.get(index_3), None); } #[cfg(feature = "std")] #[test] fn test_vec_list_get_mut() { let mut list = VecList::new(); let index = list.push_back(0); assert_eq!(list.get_mut(index), Some(&mut 0)); list.remove(index); assert_eq!(list.get_mut(index), None); 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); list.remove(index_1); list.pack_to_fit(); assert_eq!(list.get_mut(index_1), None); assert_eq!(list.get_mut(index_2), None); assert_eq!(list.get_mut(index_3), None); } #[test] fn test_vec_list_get_unchecked() { let mut list = VecList::new(); let index = list.push_back(0); assert_eq!(unsafe { list.get_unchecked(index) }, &0); 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); list.remove(index_1); assert_eq!(unsafe { list.get_unchecked(index_2) }, &1); assert_eq!(unsafe { list.get_unchecked(index_3) }, &2); } #[test] fn test_vec_list_get_unchecked_mut() { let mut list = VecList::new(); let index = list.push_back(0); assert_eq!(unsafe { list.get_unchecked_mut(index) }, &mut 0); 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); list.remove(index_1); assert_eq!(unsafe { list.get_unchecked_mut(index_2) }, &mut 1); assert_eq!(unsafe { list.get_unchecked_mut(index_3) }, &mut 2); } #[test] fn test_vec_list_get_next_index() { let mut list = VecList::new(); let index = list.push_back(0); assert_eq!(list.get_next_index(index), None); list.push_back(1); assert_eq!(list.get_next_index(index).unwrap().index.get(), 1); } #[test] fn test_vec_list_get_previous_index() { let mut list = VecList::new(); let index = list.push_front(0); assert_eq!(list.get_previous_index(index), None); list.push_front(1); assert_eq!(list.get_previous_index(index).unwrap().index.get(), 1); } #[test] fn test_vec_list_index() { let mut list = VecList::new(); let index = list.push_back(5); assert_eq!(list[index], 5); list[index] = 10; assert_eq!(list[index], 10); } #[should_panic] #[test] fn test_vec_list_index_panic() { let mut list = VecList::new(); let index = list.push_back(0); list.pop_back(); let _ = list[index]; } #[cfg(feature = "std")] #[test] fn test_vec_list_indices() { let mut list = VecList::new(); let mut iter = list.indices(); assert_eq!(iter.next(), None); list.push_back(0); let index = list.push_back(1); list.push_back(-1); list.remove(index); let mut iter = list.indices(); assert_eq!(iter.next().unwrap().index.get(), 0); assert_eq!(iter.next().unwrap().index.get(), 2); assert_eq!(iter.next(), None); list.pack_to_fit(); let mut iter = list.indices(); assert_eq!(iter.next().unwrap().index.get(), 0); assert_eq!(iter.next().unwrap().index.get(), 1); assert_eq!(iter.next(), None); } #[test] fn test_vec_list_insert_after() { let mut list = VecList::new(); let index_1 = list.push_front(0); let index_2 = list.insert_after(index_1, 1); assert_eq!(list.back(), Some(&1)); assert_eq!(list.get_previous_index(index_2), Some(index_1)); assert_eq!(list.get_next_index(index_1), Some(index_2)); let index_3 = list.insert_after(index_1, 2); assert_eq!(list.get_previous_index(index_3), Some(index_1)); assert_eq!(list.get_next_index(index_1), Some(index_3)); assert_eq!(list.get_next_index(index_3), Some(index_2)); } #[should_panic] #[test] fn test_vec_list_insert_after_panic_index_invalidated() { let mut list = VecList::new(); let index = list.push_front(0); list.remove(index); list.insert_after(index, 1); } #[cfg(feature = "std")] #[should_panic] #[test] fn test_vec_list_insert_after_panic_index_out_of_bounds() { let mut list = VecList::new(); let index_1 = list.push_back(0); list.push_back(1); let index_2 = list.push_back(2); list.remove(index_1); list.pack_to_fit(); list.insert_after(index_2, 3); } #[test] fn test_vec_list_insert_before() { let mut list = VecList::new(); let index_1 = list.push_back(0); let index_2 = list.insert_before(index_1, 1); assert_eq!(list.front(), Some(&1)); assert_eq!(list.get_previous_index(index_1), Some(index_2)); assert_eq!(list.get_next_index(index_2), Some(index_1)); let index_3 = list.insert_before(index_1, 2); assert_eq!(list.get_previous_index(index_1), Some(index_3)); assert_eq!(list.get_next_index(index_3), Some(index_1)); assert_eq!(list.get_next_index(index_2), Some(index_3)); } #[should_panic] #[test] fn test_vec_list_insert_before_panic_index_invalidated() { let mut list = VecList::new(); let index = list.push_front(0); list.remove(index); list.insert_before(index, 1); } #[cfg(feature = "std")] #[should_panic] #[test] fn test_vec_list_insert_before_panic_index_out_of_bounds() { let mut list = VecList::new(); let index_1 = list.push_back(0); list.push_back(1); let index_2 = list.push_back(2); list.remove(index_1); list.pack_to_fit(); list.insert_before(index_2, 3); } #[test] fn test_vec_list_into_iterator() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); assert_eq!(list.into_iter().collect::>(), [0, 1, -1, 2, -2]); } #[test] fn test_vec_list_is_empty() { let mut list = VecList::new(); assert!(list.is_empty()); list.push_back(0); assert!(!list.is_empty()); } #[test] fn test_vec_list_iter() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(2); let mut iter = list.iter(); assert_eq!(iter.next(), Some(&0)); assert_eq!(iter.next(), Some(&1)); assert_eq!(iter.next(), Some(&2)); assert_eq!(iter.next(), None); } #[test] fn test_vec_list_iter_mut() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(2); let mut iter = list.iter_mut(); let value = iter.next().unwrap(); *value = 100; assert_eq!(iter.next(), Some(&mut 1)); assert_eq!(iter.next(), Some(&mut 2)); assert_eq!(iter.next(), None); assert_eq!(list.front(), Some(&100)); } #[test] fn test_vec_list_len() { let mut list = VecList::new(); assert_eq!(list.len(), 0); let index = list.push_back(0); assert_eq!(list.len(), 1); list.remove(index); assert_eq!(list.len(), 0); } #[test] fn test_vec_list_new() { let list: VecList = VecList::new(); assert_eq!(list.capacity(), 0); assert_eq!(list.len(), 0); } #[test] fn test_vec_list_ordering() { let mut list_1 = VecList::new(); list_1.push_back(0); list_1.push_back(1); list_1.push_back(-1); list_1.push_back(2); list_1.push_back(-2); let mut list_2 = list_1.clone(); list_2.push_back(5); assert!(list_1 < list_2); list_2.pop_back(); list_2.pop_back(); assert!(list_1 > list_2); list_2.push_back(3); assert!(list_1 < list_2); list_2.pop_back(); list_2.push_back(-3); assert!(list_1 > list_2); } #[test] fn test_vec_list_pop_back() { let mut list = VecList::new(); assert_eq!(list.pop_back(), None); list.push_back(0); assert_eq!(list.pop_back(), Some(0)); } #[test] fn test_vec_list_pop_front() { let mut list = VecList::new(); assert_eq!(list.pop_front(), None); list.push_front(0); assert_eq!(list.pop_front(), Some(0)); } #[test] fn test_vec_list_push_back() { let mut list = VecList::new(); list.push_back(0); assert_eq!(list.back(), Some(&0)); list.push_back(1); assert_eq!(list.back(), Some(&1)); list.push_back(2); assert_eq!(list.back(), Some(&2)); } #[test] fn test_vec_list_push_back_capacity_increases() { let mut list = VecList::with_capacity(1); assert_eq!(list.capacity(), 1); let index = list.push_back(0); assert_eq!(list.capacity(), 1); list.remove(index); assert_eq!(list.capacity(), 1); list.push_back(0); assert_eq!(list.capacity(), 1); list.push_back(1); assert!(list.capacity() > 1); } #[test] fn test_vec_list_push_front() { let mut list = VecList::new(); list.push_front(0); assert_eq!(list.front(), Some(&0)); list.push_front(1); assert_eq!(list.front(), Some(&1)); list.push_front(2); assert_eq!(list.front(), Some(&2)); } #[test] fn test_vec_list_remove() { let mut list = VecList::new(); let index = list.push_back(0); assert_eq!(list.remove(index), Some(0)); assert_eq!(list.remove(index), None); } #[test] fn test_vec_list_reserve() { let mut list: VecList = VecList::new(); assert_eq!(list.capacity(), 0); list.reserve(10); let capacity = list.capacity(); assert!(capacity >= 10); list.reserve(5); assert_eq!(list.capacity(), capacity); } #[test] fn test_vec_list_retain() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(-1); list.push_back(2); list.push_back(-2); list.retain(|&mut value| value >= 0); assert_eq!(list.into_iter().collect::>(), [0, 1, 2]); } #[cfg(feature = "std")] #[test] fn test_vec_list_pack_to() { 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); assert!(list.capacity() >= 3); list.remove(index_1); assert!(list.capacity() >= 3); let indices = list.indices(); assert_eq!( indices.map(|index| index.index.get()).collect::>(), [1, 2] ); let map = list.pack_to(5); assert_eq!(list.capacity(), 5); let indices = list.indices(); assert_eq!( indices.map(|index| index.index.get()).collect::>(), [0, 1] ); assert_eq!(map.len(), 2); assert_eq!(map.get(&index_2).unwrap().index.get(), 0); assert_eq!(map.get(&index_3).unwrap().index.get(), 1); } #[cfg(feature = "std")] #[test] fn test_vec_list_pack_to_empty() { let mut list: VecList = VecList::with_capacity(5); list.pack_to(0); assert_eq!(list.capacity(), 0); } #[cfg(feature = "std")] #[should_panic] #[test] fn test_vec_list_pack_to_panic() { let mut list = VecList::new(); list.push_back(0); list.push_back(1); list.push_back(2); list.pack_to(2); } #[cfg(feature = "std")] #[test] fn test_vec_list_pack_to_fit() { 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); assert!(list.capacity() >= 3); list.remove(index_1); assert!(list.capacity() >= 3); let indices = list.indices(); assert_eq!( indices.map(|index| index.index.get()).collect::>(), [1, 2] ); let map = list.pack_to_fit(); assert_eq!(list.capacity(), 2); let indices = list.indices(); assert_eq!( indices.map(|index| index.index.get()).collect::>(), [0, 1] ); assert_eq!(map.len(), 2); assert_eq!(map.get(&index_2).unwrap().index.get(), 0); assert_eq!(map.get(&index_3).unwrap().index.get(), 1); } #[test] fn test_vec_list_with_capacity() { let list: VecList = VecList::with_capacity(10); assert_eq!(list.capacity(), 10); } #[test] fn test_vec_list_clone_from() { 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 mut list2 = VecList::new(); list2.clone_from(&list); assert_eq!(list2.get(index_1), Some(&0)); assert_eq!(list2.get(index_2), Some(&1)); assert_eq!(list2.get(index_3), Some(&2)); } #[test] fn test_move_individual_elements() { 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); // Move to tail list.move_after(index_1, index_4); assert_eq!(list.iter().copied().collect::>(), vec![1, 2, 3, 0]); assert_eq!( list.iter().rev().copied().collect::>(), vec![0, 3, 2, 1] ); assert_eq!(list.back(), list.get(index_1)); // Move to head list.move_before(index_1, index_2); assert_eq!(list.iter().copied().collect::>(), vec![0, 1, 2, 3]); assert_eq!( list.iter().rev().copied().collect::>(), vec![3, 2, 1, 0] ); // Move non-tail/head node list.move_before(index_3, index_2); assert_eq!(list.iter().copied().collect::>(), vec![0, 2, 1, 3]); assert_eq!( list.iter().rev().copied().collect::>(), vec![3, 1, 2, 0] ); } #[test] fn test_move_back_index_front_index() { let mut list = VecList::new(); let index_1 = list.push_back(0); list.push_back(1); list.push_back(2); list.push_back(3); // Move to tail list.move_after(index_1, list.back_index().unwrap()); assert_eq!(list.iter().copied().collect::>(), vec![1, 2, 3, 0]); assert_eq!( list.iter().rev().copied().collect::>(), vec![0, 3, 2, 1] ); assert_eq!(list.back(), list.get(index_1)); // Move to head list.move_before(index_1, list.front_index().unwrap()); assert_eq!(list.iter().copied().collect::>(), vec![0, 1, 2, 3]); assert_eq!( list.iter().rev().copied().collect::>(), vec![3, 2, 1, 0] ); } #[should_panic] #[test] fn test_move_after_panic1() { let mut list = VecList::new(); let index_1 = list.push_back(0); let index_2 = list.push_back(1); list.remove(index_1); list.move_after(index_1, index_2); } #[should_panic] #[test] fn test_move_after_panic2() { let mut list = VecList::new(); let index_1 = list.push_back(0); let index_2 = list.push_back(1); list.remove(index_1); list.move_after(index_2, index_1); } #[should_panic] #[test] fn test_move_after_panic3() { let mut list = VecList::new(); let index_1 = list.push_back(0); list.move_after(index_1, index_1); } #[should_panic] #[test] fn test_move_before_panic1() { let mut list = VecList::new(); let index_1 = list.push_back(0); let index_2 = list.push_back(1); list.remove(index_1); list.move_before(index_1, index_2); } #[should_panic] #[test] fn test_move_before_panic2() { let mut list = VecList::new(); let index_1 = list.push_back(0); let index_2 = list.push_back(1); list.remove(index_1); list.move_before(index_2, index_1); } #[should_panic] #[test] fn test_move_before_panic3() { let mut list = VecList::new(); let index_1 = list.push_back(0); list.move_before(index_1, index_1); } }