#![allow(unsafe_code)]
use std::{
alloc::{Allocator, Global},
collections::TryReserveError,
fmt,
hash::{Hash, Hasher},
marker::PhantomData,
mem,
ops::{Deref, DerefMut, Index, IndexMut},
};
use crate::SparseSetIndex;
pub struct SparseVec<I, T, A: Allocator = Global> {
values: Vec<Option<T>, A>,
_marker: PhantomData<I>,
}
impl<I, T> SparseVec<I, T> {
#[must_use]
pub const fn new() -> Self {
Self::new_in(Global)
}
#[cfg(not(no_global_oom_handling))]
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self::with_capacity_in(capacity, Global)
}
}
impl<I, T, A: Allocator> SparseVec<I, T, A> {
#[must_use]
pub const fn new_in(alloc: A) -> Self {
Self {
values: Vec::new_in(alloc),
_marker: PhantomData,
}
}
#[cfg(not(no_global_oom_handling))]
pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
Self {
values: Vec::with_capacity_in(capacity, alloc),
_marker: PhantomData,
}
}
}
impl<I, T, A: Allocator> SparseVec<I, T, A> {
#[must_use]
pub fn allocator(&self) -> &A {
self.values.allocator()
}
#[must_use]
pub fn as_slice(&self) -> &[Option<T>] {
&self.values
}
#[must_use]
pub fn as_mut_slice(&mut self) -> &mut [Option<T>] {
&mut self.values
}
#[must_use]
pub fn as_ptr(&self) -> *const Option<T> {
self.values.as_ptr()
}
#[must_use]
pub fn as_mut_ptr(&mut self) -> *mut Option<T> {
self.values.as_mut_ptr()
}
#[must_use]
pub fn capacity(&self) -> usize {
self.values.capacity()
}
pub fn clear(&mut self) {
self.values.clear();
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn iter(&self) -> impl Iterator<Item = &Option<T>> {
self.values.iter()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Option<T>> {
self.values.iter_mut()
}
#[must_use]
pub fn len(&self) -> usize {
self.values.len()
}
#[cfg(not(no_global_oom_handling))]
pub fn reserve(&mut self, additional: usize) {
self.values.reserve(additional);
}
#[cfg(not(no_global_oom_handling))]
pub fn reserve_exact(&mut self, additional: usize) {
self.values.reserve_exact(additional);
}
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.values.try_reserve(additional)
}
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.values.try_reserve_exact(additional)
}
#[cfg(not(no_global_oom_handling))]
pub fn shrink_to_fit(&mut self) {
self.values.truncate(self.max_index());
self.values.shrink_to_fit();
}
#[cfg(not(no_global_oom_handling))]
pub fn shrink_to(&mut self, min_capacity: usize) {
let len = self.max_index();
if min_capacity < len {
self.values.truncate(len);
}
self.values.shrink_to(min_capacity);
}
#[must_use]
fn max_index(&self) -> usize {
for (index, value) in self.values.iter().rev().enumerate() {
if value.is_some() {
return self.values.len() - index;
}
}
0
}
}
impl<I: SparseSetIndex, T, A: Allocator> SparseVec<I, T, A> {
#[must_use]
pub fn contains(&self, index: I) -> bool {
self.get(index).is_some()
}
#[must_use]
pub fn get(&self, index: I) -> Option<&T> {
self.values.get(index.into()).and_then(Option::as_ref)
}
#[must_use]
pub fn get_mut(&mut self, index: I) -> Option<&mut T> {
self.values.get_mut(index.into()).and_then(Option::as_mut)
}
#[cfg(not(no_global_oom_handling))]
pub fn insert(&mut self, index: I, value: T) -> Option<T> {
let index = index.into();
if index >= self.len() {
self.values.resize_with(index + 1, || None);
}
unsafe { self.values.get_unchecked_mut(index) }.replace(value)
}
#[must_use]
pub fn remove(&mut self, index: I) -> Option<T> {
let index = index.into();
self.values.get_mut(index).and_then(Option::take)
}
}
impl<I, T, A: Allocator> AsRef<Self> for SparseVec<I, T, A> {
fn as_ref(&self) -> &Self {
self
}
}
impl<I, T, A: Allocator> AsMut<Self> for SparseVec<I, T, A> {
fn as_mut(&mut self) -> &mut Self {
self
}
}
impl<I, T, A: Allocator> AsRef<[Option<T>]> for SparseVec<I, T, A> {
fn as_ref(&self) -> &[Option<T>] {
&self.values
}
}
impl<I, T, A: Allocator> AsMut<[Option<T>]> for SparseVec<I, T, A> {
fn as_mut(&mut self) -> &mut [Option<T>] {
&mut self.values
}
}
impl<I, T: Clone, A: Allocator + Clone> Clone for SparseVec<I, T, A> {
fn clone(&self) -> Self {
Self {
values: self.values.clone(),
_marker: PhantomData,
}
}
}
impl<I, T> Default for SparseVec<I, T> {
fn default() -> Self {
Self::new()
}
}
impl<I, T, A: Allocator> Deref for SparseVec<I, T, A> {
type Target = [Option<T>];
fn deref(&self) -> &[Option<T>] {
&self.values
}
}
impl<I, T, A: Allocator> DerefMut for SparseVec<I, T, A> {
fn deref_mut(&mut self) -> &mut [Option<T>] {
&mut self.values
}
}
impl<I, T: fmt::Debug, A: Allocator> fmt::Debug for SparseVec<I, T, A> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
self.values.fmt(formatter)
}
}
#[cfg(not(no_global_oom_handling))]
impl<'a, I: SparseSetIndex, T: Copy + 'a, A: Allocator + 'a> Extend<(I, &'a T)>
for SparseVec<I, T, A>
{
fn extend<Iter: IntoIterator<Item = (I, &'a T)>>(&mut self, iter: Iter) {
for (index, &value) in iter {
let _ = self.insert(index, value);
}
}
}
#[cfg(not(no_global_oom_handling))]
impl<I: SparseSetIndex, T, A: Allocator> Extend<(I, T)> for SparseVec<I, T, A> {
fn extend<Iter: IntoIterator<Item = (I, T)>>(&mut self, iter: Iter) {
for (index, value) in iter {
mem::drop(self.insert(index, value));
}
}
}
#[cfg(not(no_global_oom_handling))]
impl<I: SparseSetIndex, T, const N: usize> From<[(I, T); N]> for SparseVec<I, T> {
fn from(slice: [(I, T); N]) -> Self {
let mut vec = Self::with_capacity(slice.len());
for (index, value) in slice {
mem::drop(vec.insert(index, value));
}
vec
}
}
#[cfg(not(no_global_oom_handling))]
impl<I: SparseSetIndex, T> FromIterator<(I, T)> for SparseVec<I, T> {
fn from_iter<Iter: IntoIterator<Item = (I, T)>>(iter: Iter) -> Self {
let iter = iter.into_iter();
let capacity = iter
.size_hint()
.1
.map_or_else(|| iter.size_hint().0, |size_hint| size_hint);
let mut vec = Self::with_capacity(capacity);
for (index, value) in iter {
mem::drop(vec.insert(index, value));
}
vec
}
}
impl<I, T: Hash, A: Allocator> Hash for SparseVec<I, T, A> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.values.hash(state);
}
}
impl<I: SparseSetIndex, T, A: Allocator> Index<I> for SparseVec<I, T, A> {
type Output = T;
fn index(&self, index: I) -> &Self::Output {
self.get(index).unwrap()
}
}
impl<I: SparseSetIndex, T, A: Allocator> IndexMut<I> for SparseVec<I, T, A> {
fn index_mut(&mut self, index: I) -> &mut Self::Output {
self.get_mut(index).unwrap()
}
}
impl<I, T, A: Allocator> IntoIterator for SparseVec<I, T, A> {
type Item = Option<T>;
type IntoIter = impl Iterator<Item = Self::Item>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.values.into_iter()
}
}
impl<'a, I, T, A: Allocator> IntoIterator for &'a SparseVec<I, T, A> {
type Item = &'a Option<T>;
type IntoIter = impl Iterator<Item = Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, I, T, A: Allocator> IntoIterator for &'a mut SparseVec<I, T, A> {
type Item = &'a mut Option<T>;
type IntoIter = impl Iterator<Item = Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<I, T: PartialEq, A: Allocator> PartialEq for SparseVec<I, T, A> {
fn eq(&self, other: &Self) -> bool {
self.values == other.values
}
}
impl<I, T: Eq, A: Allocator> Eq for SparseVec<I, T, A> {}
#[cfg(test)]
mod test {
use std::{cell::RefCell, collections::hash_map::DefaultHasher, rc::Rc};
use coverage_helper::test;
use super::*;
#[derive(Clone)]
struct Value(Rc<RefCell<u32>>);
impl Drop for Value {
fn drop(&mut self) {
*self.0.borrow_mut() += 1;
}
}
#[test]
fn test_new() {
let vec: SparseVec<usize, usize> = SparseVec::new();
assert!(vec.is_empty());
assert_eq!(vec.capacity(), 0);
}
#[test]
fn test_with_capacity() {
let vec: SparseVec<usize, usize> = SparseVec::with_capacity(10);
assert_eq!(vec.capacity(), 10);
}
#[test]
fn test_with_capacity_zero() {
let vec: SparseVec<usize, usize> = SparseVec::with_capacity(0);
assert_eq!(vec.capacity(), 0);
}
#[should_panic]
#[test]
fn test_with_capacity_overflow() {
let _set: SparseVec<usize, usize> = SparseVec::with_capacity(usize::MAX);
}
#[test]
fn test_allocator() {
let vec: SparseVec<usize, usize> = SparseVec::new();
let _ = vec.allocator();
}
#[test]
fn test_as_slice() {
let mut vec: SparseVec<usize, usize> = SparseVec::new();
let _ = vec.insert(0, 1);
assert_eq!(vec.as_slice(), &[Some(1)]);
}
#[test]
fn test_as_mut_slice() {
let mut vec: SparseVec<usize, usize> = SparseVec::new();
let _ = vec.insert(0, 1);
assert_eq!(vec.as_mut_slice(), &mut [Some(1)]);
}
#[test]
fn test_as_ptr() {
let vec: SparseVec<usize, usize> = SparseVec::with_capacity(10);
assert_eq!(vec.as_ptr(), vec.as_slice().as_ptr());
}
#[test]
fn test_as_mut_ptr() {
let mut vec: SparseVec<usize, usize> = SparseVec::with_capacity(10);
assert_eq!(vec.as_mut_ptr(), vec.as_mut_slice().as_mut_ptr());
}
#[test]
fn test_clear() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
vec.clear();
assert!(vec.is_empty());
}
#[test]
fn test_contains() {
let mut vec = SparseVec::new();
assert!(!vec.contains(0));
let _ = vec.insert(0, 1);
assert!(vec.contains(0));
let _ = vec.remove(0);
assert!(!vec.contains(0));
}
#[test]
fn test_get() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
assert_eq!(vec.get(0), Some(&1));
assert_eq!(vec.get(2), Some(&3));
assert_eq!(vec.get(100), None);
}
#[test]
fn test_get_mut() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
let value = vec.get_mut(2);
assert_eq!(value, Some(&mut 3));
*value.unwrap() = 10;
assert_eq!(vec.get(2), Some(&10));
}
#[test]
fn test_insert_capacity_increases() {
let mut vec = SparseVec::with_capacity(1);
let _ = vec.insert(0, 1);
assert_eq!(vec.capacity(), 1);
let _ = vec.insert(1, 2);
assert!(vec.capacity() >= 2);
assert_eq!(vec.get(0), Some(&1));
assert_eq!(vec.get(1), Some(&2));
}
#[test]
fn test_insert_len_increases() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
assert_eq!(vec.len(), 1);
let _ = vec.insert(1, 2);
assert_eq!(vec.len(), 2);
let _ = vec.insert(100, 101);
assert_eq!(vec.len(), 101);
}
#[test]
fn test_insert_overwrites() {
let mut vec = SparseVec::new();
let value = vec.insert(0, 1);
assert!(value.is_none());
assert_eq!(vec.get(0), Some(&1));
let value = vec.insert(0, 2);
assert_eq!(value, Some(1));
assert_eq!(vec.get(0), Some(&2));
}
#[test]
fn test_is_empty() {
let mut vec = SparseVec::new();
assert!(vec.is_empty());
let _ = vec.insert(0, 1);
assert!(!vec.is_empty());
let _ = vec.remove(0);
vec.shrink_to_fit();
assert!(vec.is_empty());
}
#[test]
fn test_len() {
let mut vec = SparseVec::new();
assert_eq!(vec.len(), 0);
let _ = vec.insert(0, 1);
assert_eq!(vec.len(), 1);
}
#[test]
fn test_remove_can_return_none() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
assert_eq!(vec.remove(1), None);
assert_eq!(vec.remove(100), None);
}
#[test]
fn test_remove_can_return_some() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
assert_eq!(vec.remove(0), Some(1));
}
#[test]
fn test_remove_len_cannot_decreases() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
assert_eq!(vec.len(), 2);
assert_eq!(vec.remove(0), Some(1));
assert_eq!(vec.len(), 2);
assert_eq!(vec.remove(0), None);
assert_eq!(vec.len(), 2);
}
#[test]
fn test_reserve() {
let mut vec = SparseVec::new();
assert_eq!(vec.capacity(), 0);
vec.reserve(3);
let capacity = vec.capacity();
assert!(capacity >= 2);
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
vec.reserve(1);
assert_eq!(vec.capacity(), capacity);
}
#[test]
fn test_reserve_exact() {
let mut vec = SparseVec::new();
assert_eq!(vec.capacity(), 0);
vec.reserve_exact(3);
let capacity = vec.capacity();
assert!(capacity >= 2);
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
vec.reserve_exact(1);
assert_eq!(vec.capacity(), capacity);
}
#[test]
fn test_shrink_to_fit() {
let mut vec = SparseVec::with_capacity(3);
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
assert_eq!(vec.capacity(), 3);
let _ = vec.remove(2);
vec.shrink_to_fit();
assert_eq!(vec.capacity(), 2);
}
#[test]
fn test_shrink_to_fit_max_index_zero() {
let mut vec: SparseVec<usize, usize> = SparseVec::with_capacity(3);
assert_eq!(vec.capacity(), 3);
assert_eq!(vec.len(), 0);
vec.shrink_to_fit();
assert_eq!(vec.capacity(), 0);
assert_eq!(vec.len(), 0);
}
#[test]
fn test_shrink_to_can_reduce() {
let mut vec = SparseVec::with_capacity(3);
let _ = vec.insert(0, 1);
assert_eq!(vec.capacity(), 3);
vec.shrink_to(1);
assert_eq!(vec.capacity(), 1);
}
#[test]
fn test_shrink_to_cannot_reduce() {
let mut vec = SparseVec::with_capacity(3);
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
assert_eq!(vec.capacity(), 3);
vec.shrink_to(0);
assert_eq!(vec.capacity(), 3);
}
#[test]
fn test_shrink_to_max_index_zero() {
let mut vec: SparseVec<usize, usize> = SparseVec::with_capacity(3);
assert_eq!(vec.capacity(), 3);
assert_eq!(vec.len(), 0);
vec.shrink_to(0);
assert_eq!(vec.capacity(), 0);
assert_eq!(vec.len(), 0);
}
#[test]
fn test_try_reserve_succeeds() {
let mut vec = SparseVec::new();
assert_eq!(vec.capacity(), 0);
assert!(vec.try_reserve(3).is_ok());
let capacity = vec.capacity();
assert!(capacity >= 2);
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
assert!(vec.try_reserve(1).is_ok());
assert_eq!(vec.capacity(), capacity);
}
#[test]
fn test_try_reserve_exact_succeeds() {
let mut vec = SparseVec::new();
assert_eq!(vec.capacity(), 0);
assert!(vec.try_reserve_exact(3).is_ok());
let capacity = vec.capacity();
assert!(capacity >= 2);
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
assert!(vec.try_reserve_exact(1).is_ok());
assert_eq!(vec.capacity(), capacity);
}
#[test]
fn test_values() {
let mut vec = SparseVec::new();
assert!(vec.iter().eq(&[]));
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
assert!(vec.iter().eq(&[Some(1), Some(2), Some(3)]));
}
#[test]
fn test_values_mut() {
let mut vec = SparseVec::new();
assert!(vec.iter_mut().eq(&[]));
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
assert!(vec.iter_mut().eq(&[Some(1), Some(2), Some(3)]));
let value = vec.iter_mut().next().unwrap();
*value = Some(100);
assert_eq!(vec.get(0), Some(&100));
}
#[test]
fn test_as_ref() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
let reference: &SparseVec<_, _> = vec.as_ref();
assert_eq!(reference.get(0), Some(&1));
let reference: &[Option<usize>] = vec.as_ref();
assert_eq!(reference.get(0), Some(&Some(1)));
}
#[test]
fn test_as_mut() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
let reference: &mut SparseVec<_, _> = vec.as_mut();
assert_eq!(reference.get(0), Some(&1));
let reference: &mut [Option<usize>] = vec.as_mut();
assert_eq!(reference.get(0), Some(&Some(1)));
}
#[test]
fn test_clone() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
let cloned_vec = vec.clone();
assert_eq!(vec, cloned_vec);
}
#[allow(clippy::redundant_clone)]
#[test]
fn test_clone_zero_capacity() {
let vec: SparseVec<usize, usize> = SparseVec::new();
assert_eq!(vec.capacity(), 0);
let cloned_vec = vec.clone();
assert_eq!(vec, cloned_vec);
}
#[test]
fn test_clone_drops_are_separate() {
let num_dropped = Rc::new(RefCell::new(0));
{
let mut vec = SparseVec::new();
let value = Value(num_dropped.clone());
mem::drop(vec.insert(0, value.clone()));
mem::drop(vec.insert(1, value.clone()));
mem::drop(vec.insert(2, value));
let _cloned_vec = vec.clone();
}
assert_eq!(*num_dropped.borrow(), 6);
}
#[test]
fn test_debug() {
let mut vec = SparseVec::new();
assert_eq!(format!("{:?}", vec), "[]");
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
assert_eq!(format!("{:?}", vec), "[Some(1), Some(2), Some(3)]");
}
#[test]
fn test_default() {
let vec: SparseVec<usize, usize> = SparseVec::default();
assert!(vec.is_empty());
assert_eq!(vec.capacity(), 0);
}
#[test]
fn test_deref() {
let mut vec: SparseVec<usize, usize> = SparseVec::default();
let _ = vec.insert(0, 1);
}
#[test]
fn test_deref_mut() {
let mut vec: SparseVec<usize, usize> = SparseVec::default();
let _ = vec.insert(0, 1);
assert_eq!(&mut *vec, &mut [Some(1)]);
}
#[test]
fn test_drop() {
let num_dropped = Rc::new(RefCell::new(0));
{
let mut vec = SparseVec::new();
let value = Value(num_dropped.clone());
mem::drop(vec.insert(0, value.clone()));
mem::drop(vec.insert(1, value.clone()));
mem::drop(vec.insert(2, value));
}
assert_eq!(*num_dropped.borrow(), 3);
}
#[test]
fn test_extend() {
let mut vec = SparseVec::new();
vec.extend([(0, 1), (1, 2), (2, 3)]);
assert!(vec.iter().eq(&[Some(1), Some(2), Some(3)]));
}
#[test]
fn test_extend_ref() {
let mut vec: SparseVec<usize, usize> = SparseVec::new();
vec.extend([(0, &1), (1, &2), (2, &3)]);
assert!(vec.iter().eq(&[Some(1), Some(2), Some(3)]));
}
#[test]
fn test_from_array() {
let vec = SparseVec::from([(0, 1), (1, 2), (2, 3)]);
assert!(vec.iter().eq(&[Some(1), Some(2), Some(3)]));
}
#[test]
fn test_from_iterator() {
let vec = SparseVec::from_iter([(0, 1), (1, 2), (2, 3)]);
assert!(vec.iter().eq(&[Some(1), Some(2), Some(3)]));
}
#[test]
fn test_hash() {
#[derive(Default)]
struct TestHasher {
writes_made: usize,
delegate: DefaultHasher,
}
impl Hasher for TestHasher {
fn finish(&self) -> u64 {
self.delegate.finish()
}
fn write(&mut self, bytes: &[u8]) {
self.delegate.write(bytes);
self.writes_made += 1;
}
}
fn hash(value: &SparseVec<usize, usize>) -> u64 {
let mut hasher = TestHasher::default();
value.hash(&mut hasher);
assert!(hasher.writes_made >= value.len());
hasher.finish()
}
let mut vec_1 = SparseVec::new();
let mut vec_2 = SparseVec::new();
assert_eq!(vec_1, vec_2);
assert_eq!(hash(&vec_1), hash(&vec_2));
let _ = vec_1.insert(0, 1);
assert_ne!(vec_1, vec_2);
let _ = vec_2.insert(0, 2);
assert_ne!(vec_1, vec_2);
let _ = vec_2.remove(0);
let _ = vec_2.insert(1, 2);
assert_ne!(vec_1, vec_2);
let _ = vec_1.insert(1, 2);
let _ = vec_2.insert(0, 1);
assert_eq!(vec_1, vec_2);
assert_eq!(hash(&vec_1), hash(&vec_2));
let _ = vec_1.remove(0);
let _ = vec_2.remove(0);
assert_eq!(vec_1, vec_2);
assert_eq!(hash(&vec_1), hash(&vec_2));
}
#[test]
fn test_index() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
assert_eq!(vec[0], 1);
assert_eq!(vec[2], 3);
}
#[should_panic]
#[test]
fn test_index_panics() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
let _ = &vec[100];
}
#[test]
fn test_index_mut() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
let value = &mut vec[2];
assert_eq!(value, &mut 3);
*value = 10;
assert_eq!(vec[2], 10);
}
#[should_panic]
#[test]
fn test_index_mut_panics() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
let _ = &mut vec[100];
}
#[test]
fn test_into_iterator() {
let mut vec = SparseVec::new();
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
assert!(vec.into_iter().eq([Some(1), Some(2), Some(3)]));
}
#[test]
fn test_into_iterator_ref() {
let mut vec = SparseVec::new();
assert!((&vec).into_iter().eq(&[]));
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
assert!((&vec).into_iter().eq(&[Some(1), Some(2), Some(3)]));
}
#[test]
fn test_into_iterator_mut() {
let mut vec = SparseVec::new();
assert!((&mut vec).into_iter().eq(&[]));
let _ = vec.insert(0, 1);
let _ = vec.insert(1, 2);
let _ = vec.insert(2, 3);
assert!((&mut vec).into_iter().eq(&[Some(1), Some(2), Some(3)]));
let value = vec.iter_mut().next().unwrap();
*value = Some(100);
assert_eq!(vec.get(0), Some(&100));
}
#[test]
fn test_eq() {
let mut vec_1 = SparseVec::new();
let mut vec_2 = SparseVec::new();
assert_eq!(vec_1, vec_2);
let _ = vec_1.insert(0, 1);
assert_ne!(vec_1, vec_2);
let _ = vec_2.insert(0, 2);
assert_ne!(vec_1, vec_2);
let _ = vec_2.remove(0);
let _ = vec_2.insert(1, 2);
assert_ne!(vec_1, vec_2);
let _ = vec_1.insert(1, 2);
let _ = vec_2.insert(0, 1);
assert_eq!(vec_1, vec_2);
let _ = vec_1.remove(0);
let _ = vec_2.remove(0);
assert_eq!(vec_1, vec_2);
}
}