#![allow(unsafe_code)]
use std::{
alloc::{Allocator, Global},
collections::TryReserveError,
fmt::{self, Debug, Formatter},
hash::{Hash, Hasher},
mem,
num::NonZeroUsize,
ops::{Deref, DerefMut, Index, IndexMut},
};
use crate::{SparseSetIndex, SparseVec};
#[derive(Clone)]
pub struct SparseSet<I, T, SA: Allocator = Global, DA: Allocator = Global> {
dense: Vec<T, DA>,
sparse: SparseVec<I, NonZeroUsize, SA>,
indices: Vec<I, DA>,
}
impl<I, T> SparseSet<I, T> {
#[must_use]
pub const fn new() -> Self {
Self::new_in(Global, Global, Global)
}
#[cfg(not(no_global_oom_handling))]
#[must_use]
pub fn with_capacity(sparse_capacity: usize, dense_capacity: usize) -> Self {
assert!(
sparse_capacity >= dense_capacity,
"Sparse capacity must be at least as large as the dense capacity."
);
Self::with_capacity_in(sparse_capacity, Global, dense_capacity, Global, Global)
}
}
impl<I, T, SA: Allocator, DA: Allocator> SparseSet<I, T, SA, DA> {
#[must_use]
pub const fn new_in(sparse_alloc: SA, dense_alloc: DA, indices_alloc: DA) -> Self {
Self {
dense: Vec::new_in(dense_alloc),
sparse: SparseVec::new_in(sparse_alloc),
indices: Vec::new_in(indices_alloc),
}
}
#[cfg(not(no_global_oom_handling))]
pub fn with_capacity_in(
sparse_capacity: usize,
sparse_alloc: SA,
dense_capacity: usize,
dense_alloc: DA,
indices_alloc: DA,
) -> Self {
Self {
dense: Vec::with_capacity_in(dense_capacity, dense_alloc),
sparse: SparseVec::with_capacity_in(sparse_capacity, sparse_alloc),
indices: Vec::with_capacity_in(dense_capacity, indices_alloc),
}
}
}
impl<I, T, SA: Allocator, DA: Allocator> SparseSet<I, T, SA, DA> {
#[must_use]
pub fn dense_allocator(&self) -> &DA {
self.dense.allocator()
}
#[must_use]
pub fn sparse_allocator(&self) -> &SA {
self.sparse.allocator()
}
#[must_use]
pub fn as_dense_slice(&self) -> &[T] {
&self.dense
}
#[must_use]
pub unsafe fn as_dense_mut_slice(&mut self) -> &mut [T] {
&mut self.dense
}
#[must_use]
pub fn as_dense_ptr(&self) -> *const T {
self.dense.as_ptr()
}
#[must_use]
pub unsafe fn as_dense_mut_ptr(&mut self) -> *mut T {
self.dense.as_mut_ptr()
}
#[must_use]
pub fn as_indices_slice(&self) -> &[I] {
&self.indices
}
#[must_use]
pub unsafe fn as_indices_mut_slice(&mut self) -> &mut [I] {
&mut self.indices
}
#[must_use]
pub fn as_indices_ptr(&self) -> *const I {
self.indices.as_ptr()
}
#[must_use]
pub unsafe fn as_indices_mut_ptr(&mut self) -> *mut I {
self.indices.as_mut_ptr()
}
#[must_use]
pub fn dense_capacity(&self) -> usize {
self.dense.capacity()
}
#[must_use]
pub fn sparse_capacity(&self) -> usize {
self.sparse.capacity()
}
pub fn clear(&mut self) {
self.dense.clear();
self.indices.clear();
self.sparse.clear();
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.dense_len() == 0
}
#[must_use]
pub fn dense_len(&self) -> usize {
self.dense.len()
}
#[must_use]
pub fn sparse_len(&self) -> usize {
self.sparse.len()
}
pub fn drain(
&mut self,
) -> impl Iterator<Item = (I, T)> + DoubleEndedIterator + ExactSizeIterator + '_ {
self.sparse.clear();
self.indices.drain(..).zip(self.dense.drain(..))
}
#[cfg(not(no_global_oom_handling))]
pub fn reserve_dense(&mut self, additional: usize) {
self.dense.reserve(additional);
}
#[cfg(not(no_global_oom_handling))]
pub fn reserve_sparse(&mut self, additional: usize) {
self.sparse.reserve(additional);
}
#[cfg(not(no_global_oom_handling))]
pub fn reserve_exact_dense(&mut self, additional: usize) {
self.dense.reserve_exact(additional);
}
#[cfg(not(no_global_oom_handling))]
pub fn reserve_exact_sparse(&mut self, additional: usize) {
self.sparse.reserve_exact(additional);
}
pub fn try_reserve_dense(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.dense.try_reserve(additional)
}
pub fn try_reserve_sparse(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.sparse.try_reserve(additional)
}
pub fn try_reserve_exact_dense(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.dense.try_reserve_exact(additional)
}
pub fn try_reserve_exact_sparse(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.sparse.try_reserve_exact(additional)
}
#[cfg(not(no_global_oom_handling))]
pub fn shrink_to_fit_dense(&mut self) {
self.dense.shrink_to_fit();
}
#[cfg(not(no_global_oom_handling))]
pub fn shrink_to_fit_sparse(&mut self) {
self.sparse.shrink_to_fit();
}
#[cfg(not(no_global_oom_handling))]
pub fn shrink_to_dense(&mut self, min_capacity: usize) {
self.dense.shrink_to(min_capacity);
}
#[cfg(not(no_global_oom_handling))]
pub fn shrink_to_sparse(&mut self, min_capacity: usize) {
self.sparse.shrink_to(min_capacity);
}
pub fn values(&self) -> impl Iterator<Item = &T> + DoubleEndedIterator + ExactSizeIterator {
self.dense.iter()
}
pub fn values_mut(
&mut self,
) -> impl Iterator<Item = &mut T> + DoubleEndedIterator + ExactSizeIterator {
self.dense.iter_mut()
}
}
impl<I: SparseSetIndex, T, SA: Allocator, DA: Allocator> SparseSet<I, T, SA, DA> {
#[must_use]
pub fn contains(&self, index: I) -> bool {
self.get(index).is_some()
}
#[must_use]
pub fn dense_index_of(&self, index: I) -> Option<usize> {
self
.sparse
.get(index)
.map(|dense_index| dense_index.get() - 1)
}
#[must_use]
pub fn entry(&mut self, index: I) -> Entry<'_, I, T, SA, DA> {
match self.dense_index_of(index) {
Some(dense_index) => Entry::Occupied(OccupiedEntry {
dense_index,
index,
sparse_set: self,
}),
None => Entry::Vacant(VacantEntry {
index,
sparse_set: self,
}),
}
}
#[must_use]
pub fn immutable_entry(&self, index: I) -> Option<ImmutableEntry<'_, I, T, SA, DA>> {
self
.dense_index_of(index)
.map(|dense_index| ImmutableEntry {
dense_index,
index,
sparse_set: self,
})
}
#[must_use]
pub fn get(&self, index: I) -> Option<&T> {
self
.dense_index_of(index)
.map(|dense_index| unsafe { self.dense.get_unchecked(dense_index) })
}
#[must_use]
pub fn get_with_index(&self, index: I) -> Option<(I, &T)> {
self.dense_index_of(index).map(|dense_index| {
(
*unsafe { self.indices.get_unchecked(dense_index) },
unsafe { self.dense.get_unchecked(dense_index) },
)
})
}
#[must_use]
pub fn get_mut(&mut self, index: I) -> Option<&mut T> {
self
.dense_index_of(index)
.map(|dense_index| unsafe { self.dense.get_unchecked_mut(dense_index) })
}
#[must_use]
pub fn get_mut_with_index(&mut self, index: I) -> Option<(I, &mut T)> {
self.dense_index_of(index).map(|dense_index| {
(
*unsafe { self.indices.get_unchecked_mut(dense_index) },
unsafe { self.dense.get_unchecked_mut(dense_index) },
)
})
}
pub fn indices(&self) -> impl Iterator<Item = I> + DoubleEndedIterator + ExactSizeIterator + '_ {
self.indices.iter().cloned()
}
pub fn iter(&self) -> impl Iterator<Item = (I, &T)> + DoubleEndedIterator + ExactSizeIterator {
self.indices.iter().cloned().zip(self.dense.iter())
}
pub fn iter_mut(
&mut self,
) -> impl Iterator<Item = (I, &mut T)> + DoubleEndedIterator + ExactSizeIterator {
self.indices.iter().cloned().zip(self.dense.iter_mut())
}
#[cfg(not(no_global_oom_handling))]
pub fn insert(&mut self, index: I, value: T) -> Option<T> {
self.insert_with_index(index, value).map(|(_, value)| value)
}
#[cfg(not(no_global_oom_handling))]
pub fn insert_with_index(&mut self, mut index: I, mut value: T) -> Option<(I, T)> {
match self.dense_index_of(index) {
Some(dense_index) => {
mem::swap(&mut index, unsafe {
self.indices.get_unchecked_mut(dense_index)
});
mem::swap(&mut value, unsafe {
self.dense.get_unchecked_mut(dense_index)
});
Some((index, value))
}
None => {
self.dense.push(value);
self.indices.push(index);
let _ = self.sparse.insert(index, unsafe {
NonZeroUsize::new_unchecked(self.dense_len())
});
None
}
}
}
#[must_use]
pub fn remove(&mut self, index: I) -> Option<T> {
self.remove_with_index(index).map(|(_, value)| value)
}
#[must_use]
pub fn remove_with_index(&mut self, index: I) -> Option<(I, T)> {
self
.sparse
.remove(index)
.map(|dense_index| unsafe { self.remove_at_dense_index(dense_index.get() - 1) })
}
unsafe fn remove_at_dense_index(&mut self, dense_index: usize) -> (I, T) {
let index = self.indices.swap_remove(dense_index);
let value = self.dense.swap_remove(dense_index);
if dense_index != self.dense.len() {
let swapped_index: usize = (*unsafe { self.indices.get_unchecked(dense_index) }).into();
*unsafe { self.sparse.get_unchecked_mut(swapped_index) } =
Some(unsafe { NonZeroUsize::new_unchecked(dense_index + 1) });
}
(index, value)
}
pub fn retain<F: FnMut(I, &mut T) -> bool>(&mut self, mut f: F) {
let mut i = 0;
while i < self.indices.len() {
let index = *unsafe { self.indices.get_unchecked(i) };
let value = unsafe { self.dense.get_unchecked_mut(i) };
if f(index, value) {
i += 1;
continue;
}
mem::drop(self.remove(index));
}
}
}
impl<I, T, SA: Allocator, DA: Allocator> AsRef<Self> for SparseSet<I, T, SA, DA> {
fn as_ref(&self) -> &Self {
self
}
}
impl<I, T, SA: Allocator, DA: Allocator> AsMut<Self> for SparseSet<I, T, SA, DA> {
fn as_mut(&mut self) -> &mut Self {
self
}
}
impl<I, T, SA: Allocator, DA: Allocator> AsRef<[T]> for SparseSet<I, T, SA, DA> {
fn as_ref(&self) -> &[T] {
&self.dense
}
}
impl<I, T, SA: Allocator, DA: Allocator> AsMut<[T]> for SparseSet<I, T, SA, DA> {
fn as_mut(&mut self) -> &mut [T] {
&mut self.dense
}
}
impl<I, T> Default for SparseSet<I, T> {
fn default() -> Self {
Self::new()
}
}
impl<I, T, SA: Allocator, DA: Allocator> Deref for SparseSet<I, T, SA, DA> {
type Target = [T];
fn deref(&self) -> &[T] {
&self.dense
}
}
impl<I, T, SA: Allocator, DA: Allocator> DerefMut for SparseSet<I, T, SA, DA> {
fn deref_mut(&mut self) -> &mut [T] {
&mut self.dense
}
}
impl<I: Debug + SparseSetIndex, T: Debug, SA: Allocator, DA: Allocator> Debug
for SparseSet<I, T, SA, DA>
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
formatter.debug_map().entries(self.iter()).finish()
}
}
#[cfg(not(no_global_oom_handling))]
impl<'a, I: SparseSetIndex, T: Copy + 'a, SA: Allocator + 'a, DA: Allocator + 'a> Extend<(I, &'a T)>
for SparseSet<I, T, SA, DA>
{
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, SA: Allocator, DA: Allocator> Extend<(I, T)>
for SparseSet<I, T, SA, DA>
{
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 SparseSet<I, T> {
fn from(slice: [(I, T); N]) -> Self {
let mut set = Self::with_capacity(slice.len(), slice.len());
for (index, value) in slice {
mem::drop(set.insert(index, value));
}
set
}
}
#[cfg(not(no_global_oom_handling))]
impl<I: SparseSetIndex, T> FromIterator<(I, T)> for SparseSet<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 set = Self::with_capacity(capacity, capacity);
for (index, value) in iter {
mem::drop(set.insert(index, value));
}
set
}
}
impl<I: Hash + SparseSetIndex, T: Hash, SA: Allocator, DA: Allocator> Hash
for SparseSet<I, T, SA, DA>
{
fn hash<H: Hasher>(&self, state: &mut H) {
for index in self.sparse.iter().flatten() {
unsafe { self.sparse.get_unchecked(index.get() - 1) }.hash(state);
unsafe { self.indices.get_unchecked(index.get() - 1) }.hash(state);
unsafe { self.dense.get_unchecked(index.get() - 1) }.hash(state);
}
}
}
impl<I: SparseSetIndex, T, SA: Allocator, DA: Allocator> Index<I> for SparseSet<I, T, SA, DA> {
type Output = T;
fn index(&self, index: I) -> &Self::Output {
self.get(index).unwrap()
}
}
impl<I: SparseSetIndex, T, SA: Allocator, DA: Allocator> IndexMut<I> for SparseSet<I, T, SA, DA> {
fn index_mut(&mut self, index: I) -> &mut Self::Output {
self.get_mut(index).unwrap()
}
}
impl<I, T, SA: Allocator, DA: Allocator> IntoIterator for SparseSet<I, T, SA, DA> {
type Item = (I, T);
type IntoIter = impl Iterator<Item = Self::Item> + DoubleEndedIterator + ExactSizeIterator;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.indices.into_iter().zip(self.dense)
}
}
impl<'a, I: SparseSetIndex, T, SA: Allocator, DA: Allocator> IntoIterator
for &'a SparseSet<I, T, SA, DA>
{
type Item = (I, &'a T);
type IntoIter = impl Iterator<Item = Self::Item> + DoubleEndedIterator + ExactSizeIterator;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, I: SparseSetIndex, T, SA: Allocator, DA: Allocator> IntoIterator
for &'a mut SparseSet<I, T, SA, DA>
{
type Item = (I, &'a mut T);
type IntoIter = impl Iterator<Item = Self::Item> + DoubleEndedIterator + ExactSizeIterator;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<I: PartialEq + SparseSetIndex, T: PartialEq, SA: Allocator, DA: Allocator> PartialEq
for SparseSet<I, T, SA, DA>
{
fn eq(&self, other: &Self) -> bool {
if self.indices.len() != other.indices.len() {
return false;
}
for index in &self.indices {
match (self.dense_index_of(*index), other.dense_index_of(*index)) {
(Some(index), Some(other_index)) => {
if unsafe { self.indices.get_unchecked(index) }
!= unsafe { other.indices.get_unchecked(other_index) }
{
return false;
}
if unsafe { self.dense.get_unchecked(index) }
!= unsafe { other.dense.get_unchecked(other_index) }
{
return false;
}
}
(None, None) => {}
_ => {
return false;
}
}
}
true
}
}
impl<I: Eq + SparseSetIndex, T: Eq, SA: Allocator, DA: Allocator> Eq for SparseSet<I, T, SA, DA> {}
pub struct ImmutableEntry<'a, I, T, SA: Allocator = Global, DA: Allocator = Global> {
dense_index: usize,
index: I,
sparse_set: &'a SparseSet<I, T, SA, DA>,
}
impl<I: SparseSetIndex, T, SA: Allocator, DA: Allocator> ImmutableEntry<'_, I, T, SA, DA> {
#[must_use]
pub fn dense_index(&self) -> usize {
self.dense_index
}
#[must_use]
pub fn get(&self) -> &T {
unsafe { self.sparse_set.dense.get_unchecked(self.dense_index) }
}
#[must_use]
pub fn entry_index(&self) -> I {
self.index
}
#[must_use]
pub fn stored_index(&self) -> I {
*unsafe { self.sparse_set.indices.get_unchecked(self.dense_index) }
}
}
impl<I: Debug + SparseSetIndex, T: Debug, SA: Allocator, DA: Allocator> Debug
for ImmutableEntry<'_, I, T, SA, DA>
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("ImmutableEntry")
.field("index", &self.entry_index())
.field("value", self.get())
.finish()
}
}
pub enum Entry<'a, I, T, SA: Allocator = Global, DA: Allocator = Global> {
Vacant(VacantEntry<'a, I, T, SA, DA>),
Occupied(OccupiedEntry<'a, I, T, SA, DA>),
}
impl<'a, I: SparseSetIndex, T, SA: Allocator, DA: Allocator> Entry<'a, I, T, SA, DA> {
#[must_use]
pub fn and_modify<F: FnOnce(&mut T)>(self, function: F) -> Self {
match self {
Entry::Vacant(entry) => Entry::Vacant(entry),
Entry::Occupied(mut entry) => {
function(entry.get_mut());
Entry::Occupied(entry)
}
}
}
#[must_use]
pub fn entry_index(&self) -> I {
match self {
Entry::Vacant(entry) => entry.entry_index(),
Entry::Occupied(entry) => entry.entry_index(),
}
}
pub fn or_insert(self, default: T) -> &'a mut T {
match self {
Entry::Vacant(entry) => entry.insert(default),
Entry::Occupied(entry) => entry.into_mut(),
}
}
pub fn or_insert_with<F: FnOnce() -> T>(self, default: F) -> &'a mut T {
match self {
Entry::Vacant(entry) => entry.insert(default()),
Entry::Occupied(entry) => entry.into_mut(),
}
}
pub fn insert_entry(self, value: T) -> OccupiedEntry<'a, I, T, SA, DA> {
match self {
Entry::Vacant(entry) => entry.insert_entry(value),
Entry::Occupied(mut entry) => {
mem::drop(entry.insert(value));
entry
}
}
}
}
impl<I: Debug + SparseSetIndex, T: Debug, SA: Allocator, DA: Allocator> Debug
for Entry<'_, I, T, SA, DA>
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
match self {
Entry::Vacant(entry) => formatter.debug_tuple("Entry").field(entry).finish(),
Entry::Occupied(entry) => formatter.debug_tuple("Entry").field(entry).finish(),
}
}
}
pub struct VacantEntry<'a, I, T, SA: Allocator = Global, DA: Allocator = Global> {
index: I,
sparse_set: &'a mut SparseSet<I, T, SA, DA>,
}
impl<'a, I: SparseSetIndex, T, SA: Allocator, DA: Allocator> VacantEntry<'a, I, T, SA, DA> {
#[must_use]
pub fn entry_index(&self) -> I {
self.index
}
pub fn insert(mut self, value: T) -> &'a mut T {
let dense_index = self.insert_raw(value);
unsafe { self.sparse_set.dense.get_unchecked_mut(dense_index) }
}
pub fn insert_entry(mut self, value: T) -> OccupiedEntry<'a, I, T, SA, DA> {
let dense_index = self.insert_raw(value);
OccupiedEntry {
dense_index,
index: self.index,
sparse_set: self.sparse_set,
}
}
#[must_use]
fn insert_raw(&mut self, value: T) -> usize {
self.sparse_set.dense.push(value);
self.sparse_set.indices.push(self.index);
let _ = self.sparse_set.sparse.insert(self.index, unsafe {
NonZeroUsize::new_unchecked(self.sparse_set.dense_len())
});
self.sparse_set.dense_len() - 1
}
}
impl<I: Debug, T, SA: Allocator, DA: Allocator> Debug for VacantEntry<'_, I, T, SA, DA> {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
formatter
.debug_tuple("VacantEntry")
.field(&self.index)
.finish()
}
}
pub struct OccupiedEntry<'a, I, T, SA: Allocator = Global, DA: Allocator = Global> {
dense_index: usize,
index: I,
sparse_set: &'a mut SparseSet<I, T, SA, DA>,
}
impl<'a, I: SparseSetIndex, T, SA: Allocator, DA: Allocator> OccupiedEntry<'a, I, T, SA, DA> {
#[must_use]
pub fn dense_index(&self) -> usize {
self.dense_index
}
#[must_use]
pub fn get(&self) -> &T {
unsafe { self.sparse_set.dense.get_unchecked(self.dense_index) }
}
#[must_use]
pub fn get_mut(&mut self) -> &mut T {
unsafe { self.sparse_set.dense.get_unchecked_mut(self.dense_index) }
}
#[must_use]
pub fn into_mut(self) -> &'a mut T {
unsafe { self.sparse_set.dense.get_unchecked_mut(self.dense_index) }
}
#[must_use]
pub fn entry_index(&self) -> I {
self.index
}
#[must_use]
pub fn stored_index(&self) -> I {
*unsafe { self.sparse_set.indices.get_unchecked(self.dense_index) }
}
pub fn insert(&mut self, value: T) -> T {
self.insert_with_index(value).1
}
pub fn insert_with_index(&mut self, mut value: T) -> (I, T) {
let mut index = self.index;
mem::swap(&mut index, unsafe {
self.sparse_set.indices.get_unchecked_mut(self.dense_index)
});
mem::swap(&mut value, unsafe {
self.sparse_set.dense.get_unchecked_mut(self.dense_index)
});
(index, value)
}
pub fn remove(self) -> T {
self.remove_with_index().1
}
pub fn remove_with_index(self) -> (I, T) {
let _ = self.sparse_set.sparse.remove(self.index);
unsafe { self.sparse_set.remove_at_dense_index(self.dense_index) }
}
}
impl<I: Debug + SparseSetIndex, T: Debug, SA: Allocator, DA: Allocator> Debug
for OccupiedEntry<'_, I, T, SA, DA>
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("OccupiedEntry")
.field("index", &self.entry_index())
.field("value", self.get())
.finish()
}
}
#[cfg(test)]
mod test {
use std::{cell::RefCell, collections::hash_map::DefaultHasher, rc::Rc};
use coverage_helper::test;
use super::*;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
struct Index {
index: usize,
other: u32,
}
impl Index {
pub fn new(index: usize, other: u32) -> Self {
Index { index, other }
}
}
impl From<Index> for usize {
fn from(value: Index) -> Self {
value.index
}
}
impl SparseSetIndex for Index {}
#[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 set: SparseSet<usize, usize> = SparseSet::new();
assert!(set.is_empty());
assert_eq!(set.dense_capacity(), 0);
assert_eq!(set.sparse_capacity(), 0);
}
#[test]
fn test_with_capacity() {
let set: SparseSet<usize, usize> = SparseSet::with_capacity(15, 10);
assert_eq!(set.sparse_capacity(), 15);
assert_eq!(set.dense_capacity(), 10);
}
#[test]
fn test_with_capacity_zero() {
let set: SparseSet<usize, usize> = SparseSet::with_capacity(0, 0);
assert_eq!(set.sparse_capacity(), 0);
assert_eq!(set.dense_capacity(), 0);
}
#[should_panic]
#[test]
fn test_with_capacity_dense_greater_than_sparse() {
let _set: SparseSet<usize, usize> = SparseSet::with_capacity(0, 1);
}
#[should_panic]
#[test]
fn test_with_capacity_sparse_overflow() {
let _set: SparseSet<usize, usize> = SparseSet::with_capacity(usize::MAX, 0);
}
#[should_panic]
#[test]
fn test_with_capacity_dense_overflow() {
let _set: SparseSet<usize, usize> = SparseSet::with_capacity(0, usize::MAX);
}
#[test]
fn test_dense_allocator() {
let set: SparseSet<usize, usize> = SparseSet::new();
let _ = set.dense_allocator();
}
#[test]
fn test_sparse_allocator() {
let set: SparseSet<usize, usize> = SparseSet::new();
let _ = set.sparse_allocator();
}
#[test]
fn test_as_dense_slice() {
let mut set: SparseSet<usize, usize> = SparseSet::new();
let _ = set.insert(0, 1);
assert_eq!(set.as_dense_slice(), &[1]);
}
#[test]
fn test_as_dense_mut_slice() {
let mut set: SparseSet<usize, usize> = SparseSet::new();
let _ = set.insert(0, 1);
assert_eq!(unsafe { set.as_dense_mut_slice() }, &mut [1]);
}
#[test]
fn test_as_dense_ptr() {
let set: SparseSet<usize, usize> = SparseSet::with_capacity(10, 10);
assert_eq!(set.as_dense_ptr(), set.as_dense_slice().as_ptr());
}
#[test]
fn test_as_dense_mut_ptr() {
let mut set: SparseSet<usize, usize> = SparseSet::with_capacity(10, 10);
assert_eq!(
unsafe { set.as_dense_mut_ptr() },
unsafe { set.as_dense_mut_slice() }.as_mut_ptr()
);
}
#[test]
fn test_as_indices_slice() {
let mut set: SparseSet<usize, usize> = SparseSet::new();
let _ = set.insert(0, 1);
assert_eq!(set.as_indices_slice(), &[0]);
}
#[test]
fn test_as_indices_ptr() {
let set: SparseSet<usize, usize> = SparseSet::with_capacity(10, 10);
assert_eq!(set.as_indices_ptr(), set.as_indices_slice().as_ptr());
}
#[test]
fn test_as_indices_ptr_mut() {
let mut set: SparseSet<usize, usize> = SparseSet::with_capacity(10, 10);
assert_eq!(
unsafe { set.as_indices_mut_ptr() },
unsafe { set.as_indices_mut_slice() }.as_mut_ptr()
);
}
#[test]
fn test_clear() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
set.clear();
assert!(set.is_empty());
}
#[test]
fn test_contains() {
let mut set = SparseSet::new();
assert!(!set.contains(0));
let _ = set.insert(0, 1);
assert!(set.contains(0));
let _ = set.remove(0);
assert!(!set.contains(0));
}
#[test]
fn test_dense_index_of() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(20, 3);
assert_eq!(set.dense_index_of(0), Some(0));
assert_eq!(set.dense_index_of(1), Some(1));
assert_eq!(set.dense_index_of(2), None);
assert_eq!(set.dense_index_of(20), Some(2));
let _ = set.remove(1);
assert_eq!(set.dense_index_of(20), Some(1));
}
#[test]
fn test_drain() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert!(set.drain().eq([(0, 1), (1, 2), (2, 3)]));
assert!(set.is_empty());
}
#[test]
fn test_get() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert_eq!(set.get(0), Some(&1));
assert_eq!(set.get(2), Some(&3));
assert_eq!(set.get(100), None);
}
#[test]
fn test_get_with_index() {
let mut set = SparseSet::new();
let _ = set.insert(Index::new(0, 0), 1);
let _ = set.insert(Index::new(1, 0), 2);
let _ = set.insert(Index::new(2, 0), 3);
assert_eq!(
set.get_with_index(Index::new(0, 1)),
Some((Index::new(0, 0), &1))
);
assert_eq!(
set.get_with_index(Index::new(2, 0)),
Some((Index::new(2, 0), &3))
);
assert_eq!(set.get_with_index(Index::new(100, 0)), None);
}
#[test]
fn test_get_mut() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let value = set.get_mut(2);
assert_eq!(value, Some(&mut 3));
*value.unwrap() = 10;
assert_eq!(set.get(2), Some(&10));
}
#[test]
fn test_get_mut_with_index() {
let mut set = SparseSet::new();
let _ = set.insert(Index::new(0, 0), 1);
let _ = set.insert(Index::new(1, 0), 2);
let _ = set.insert(Index::new(2, 0), 3);
let value = set.get_mut_with_index(Index::new(2, 1));
assert_eq!(value, Some((Index::new(2, 0), &mut 3)));
*value.unwrap().1 = 10;
assert_eq!(set.get(Index::new(2, 0)), Some(&10));
}
#[test]
fn test_indices() {
let mut set = SparseSet::new();
assert!(set.indices().eq([]));
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert!(set.indices().eq([0, 1, 2]));
}
#[test]
fn test_insert_capacity_increases() {
let mut set = SparseSet::with_capacity(1, 1);
let _ = set.insert(0, 1);
assert_eq!(set.sparse_capacity(), 1);
assert_eq!(set.dense_capacity(), 1);
let _ = set.insert(1, 2);
assert!(set.sparse_capacity() >= 2);
assert!(set.dense_capacity() >= 2);
assert_eq!(set.get(0), Some(&1));
assert_eq!(set.get(1), Some(&2));
}
#[test]
fn test_insert_len_increases() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
assert_eq!(set.dense_len(), 1);
assert_eq!(set.sparse_len(), 1);
let _ = set.insert(1, 2);
assert_eq!(set.dense_len(), 2);
assert_eq!(set.sparse_len(), 2);
let _ = set.insert(100, 101);
assert_eq!(set.dense_len(), 3);
assert_eq!(set.sparse_len(), 101);
}
#[test]
fn test_insert_overwrites() {
let mut set = SparseSet::new();
assert_eq!(set.insert(0, 1), None);
assert_eq!(set.get(0), Some(&1));
assert_eq!(set.insert(0, 2), Some(1));
assert_eq!(set.get(0), Some(&2));
}
#[test]
fn test_insert_with_index_capacity_increases() {
let mut set = SparseSet::with_capacity(1, 1);
let _ = set.insert_with_index(0, 1);
assert_eq!(set.sparse_capacity(), 1);
assert_eq!(set.dense_capacity(), 1);
let _ = set.insert_with_index(1, 2);
assert!(set.sparse_capacity() >= 2);
assert!(set.dense_capacity() >= 2);
assert_eq!(set.get(0), Some(&1));
assert_eq!(set.get(1), Some(&2));
}
#[test]
fn test_insert_with_index_len_increases() {
let mut set = SparseSet::new();
let _ = set.insert_with_index(0, 1);
assert_eq!(set.dense_len(), 1);
assert_eq!(set.sparse_len(), 1);
let _ = set.insert_with_index(1, 2);
assert_eq!(set.dense_len(), 2);
assert_eq!(set.sparse_len(), 2);
let _ = set.insert_with_index(100, 101);
assert_eq!(set.dense_len(), 3);
assert_eq!(set.sparse_len(), 101);
}
#[test]
fn test_insert_with_index_overwrites() {
let mut set = SparseSet::new();
assert_eq!(set.insert_with_index(Index::new(0, 0), 1), None);
assert_eq!(set.get(Index::new(0, 0)), Some(&1));
assert_eq!(
set.insert_with_index(Index::new(0, 1), 2),
Some((Index::new(0, 0), 1))
);
assert_eq!(set.get(Index::new(0, 0)), Some(&2));
}
#[test]
fn test_iter() {
let mut set = SparseSet::new();
assert!(set.iter().eq([]));
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert!(set.iter().eq([(0, &1), (1, &2), (2, &3)]));
}
#[test]
fn test_iter_mut() {
let mut set = SparseSet::new();
assert!(set.iter_mut().eq([]));
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert!(set.iter_mut().eq([(0, &mut 1), (1, &mut 2), (2, &mut 3)]));
let value = set.iter_mut().next().unwrap();
*(value.1) = 100;
assert_eq!(set.first(), Some(&100));
}
#[test]
fn test_is_empty() {
let mut set = SparseSet::new();
assert!(set.is_empty());
let _ = set.insert(0, 1);
assert!(!set.is_empty());
let _ = set.remove(0);
assert!(set.is_empty());
}
#[test]
fn test_dense_len() {
let mut set = SparseSet::new();
assert_eq!(set.dense_len(), 0);
let _ = set.insert(0, 1);
assert_eq!(set.dense_len(), 1);
}
#[test]
fn test_sparse_len() {
let mut set = SparseSet::new();
assert_eq!(set.sparse_len(), 0);
let _ = set.insert(0, 1);
assert_eq!(set.sparse_len(), 1);
let _ = set.insert(100, 1);
assert_eq!(set.sparse_len(), 101);
}
#[test]
fn test_remove_can_return_none() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
assert_eq!(set.remove(1), None);
assert_eq!(set.remove(100), None);
}
#[test]
fn test_remove_can_return_some() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
assert_eq!(set.remove(0), Some(1));
}
#[test]
fn test_remove_len_decreases() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
assert_eq!(set.dense_len(), 2);
assert_eq!(set.sparse_len(), 2);
assert_eq!(set.remove(0), Some(1));
assert_eq!(set.dense_len(), 1);
assert_eq!(set.sparse_len(), 2);
assert_eq!(set.remove(0), None);
assert_eq!(set.dense_len(), 1);
assert_eq!(set.sparse_len(), 2);
}
#[test]
fn test_remove_swaps_with_last() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert!(set.values().eq(&[1, 2, 3]));
let _ = set.remove(0);
assert!(set.values().eq(&[3, 2]));
}
#[test]
fn test_remove_with_index_can_return_none() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
assert_eq!(set.remove_with_index(1), None);
assert_eq!(set.remove_with_index(100), None);
}
#[test]
fn test_remove_with_index_can_return_some() {
let mut set = SparseSet::new();
let _ = set.insert(Index::new(0, 0), 1);
assert_eq!(
set.remove_with_index(Index::new(0, 1)),
Some((Index::new(0, 0), 1))
);
}
#[test]
fn test_remove_with_index_len_decreases() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
assert_eq!(set.dense_len(), 2);
assert_eq!(set.sparse_len(), 2);
assert_eq!(set.remove_with_index(0), Some((0, 1)));
assert_eq!(set.dense_len(), 1);
assert_eq!(set.sparse_len(), 2);
assert_eq!(set.remove_with_index(0), None);
assert_eq!(set.dense_len(), 1);
assert_eq!(set.sparse_len(), 2);
}
#[test]
fn test_remove_with_index_swaps_with_last() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert!(set.values().eq(&[1, 2, 3]));
let _ = set.remove_with_index(0);
assert!(set.values().eq(&[3, 2]));
}
#[test]
fn test_reserve_dense() {
let mut set = SparseSet::new();
assert_eq!(set.dense_capacity(), 0);
set.reserve_dense(3);
let capacity = set.dense_capacity();
assert!(capacity >= 2);
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
set.reserve_dense(1);
assert_eq!(set.dense_capacity(), capacity);
}
#[test]
fn test_reserve_sparse() {
let mut set = SparseSet::new();
assert_eq!(set.sparse_capacity(), 0);
set.reserve_sparse(3);
let capacity = set.sparse_capacity();
assert!(capacity >= 2);
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
set.reserve_sparse(1);
assert_eq!(set.sparse_capacity(), capacity);
}
#[test]
fn test_reserve_exact_dense() {
let mut set = SparseSet::new();
assert_eq!(set.dense_capacity(), 0);
set.reserve_exact_dense(3);
let capacity = set.dense_capacity();
assert!(capacity >= 2);
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
set.reserve_exact_dense(1);
assert_eq!(set.dense_capacity(), capacity);
}
#[test]
fn test_reserve_exact_sparse() {
let mut set = SparseSet::new();
assert_eq!(set.sparse_capacity(), 0);
set.reserve_exact_sparse(3);
let capacity = set.sparse_capacity();
assert!(capacity >= 2);
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
set.reserve_exact_sparse(1);
assert_eq!(set.sparse_capacity(), capacity);
}
#[test]
fn test_retain() {
let mut set = SparseSet::with_capacity(3, 3);
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
set.retain(|_index, value| *value > 2);
assert_eq!(set.dense_len(), 1);
assert!(set.indices().eq([2]));
assert!(set.values().eq([&3]));
assert_eq!(set.get(0), None);
assert_eq!(set.get(1), None);
assert_eq!(set.get(2), Some(&3));
}
#[test]
fn test_shrink_to_fit_dense() {
let mut set = SparseSet::with_capacity(3, 3);
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert_eq!(set.dense_capacity(), 3);
let _ = set.remove(2);
set.shrink_to_fit_dense();
assert_eq!(set.dense_capacity(), 2);
}
#[test]
fn test_shrink_to_fit_sparse() {
let mut set = SparseSet::with_capacity(3, 3);
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert_eq!(set.sparse_capacity(), 3);
assert_eq!(set.sparse_len(), 3);
let _ = set.remove(2);
set.shrink_to_fit_sparse();
assert_eq!(set.sparse_capacity(), 2);
assert_eq!(set.sparse_len(), 2);
}
#[test]
fn test_shrink_to_fit_max_index_zero() {
let mut set: SparseSet<usize, usize> = SparseSet::with_capacity(3, 3);
assert_eq!(set.sparse_capacity(), 3);
assert_eq!(set.sparse_len(), 0);
set.shrink_to_fit_sparse();
assert_eq!(set.sparse_capacity(), 0);
assert_eq!(set.sparse_len(), 0);
}
#[test]
fn test_shrink_to_dense_can_reduce() {
let mut set = SparseSet::with_capacity(3, 3);
let _ = set.insert(0, 1);
assert_eq!(set.dense_capacity(), 3);
set.shrink_to_dense(1);
assert_eq!(set.dense_capacity(), 1);
}
#[test]
fn test_shrink_to_dense_cannot_reduce() {
let mut set = SparseSet::with_capacity(3, 3);
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert_eq!(set.dense_capacity(), 3);
set.shrink_to_dense(0);
assert_eq!(set.dense_capacity(), 3);
}
#[test]
fn test_shrink_to_sparse_can_reduce() {
let mut set = SparseSet::with_capacity(3, 3);
let _ = set.insert(0, 1);
assert_eq!(set.sparse_capacity(), 3);
assert_eq!(set.sparse_len(), 1);
set.shrink_to_sparse(1);
assert_eq!(set.sparse_capacity(), 1);
assert_eq!(set.sparse_len(), 1);
}
#[test]
fn test_shrink_to_sparse_cannot_reduce() {
let mut set = SparseSet::with_capacity(3, 3);
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert_eq!(set.sparse_capacity(), 3);
assert_eq!(set.sparse_len(), 3);
set.shrink_to_sparse(0);
assert_eq!(set.sparse_capacity(), 3);
assert_eq!(set.sparse_len(), 3);
}
#[test]
fn test_shrink_to_max_index_zero() {
let mut set: SparseSet<usize, usize> = SparseSet::with_capacity(3, 3);
assert_eq!(set.sparse_capacity(), 3);
assert_eq!(set.sparse_len(), 0);
set.shrink_to_sparse(0);
assert_eq!(set.sparse_capacity(), 0);
assert_eq!(set.sparse_len(), 0);
}
#[test]
fn test_try_reserve_dense_succeeds() {
let mut set = SparseSet::new();
assert_eq!(set.dense_capacity(), 0);
assert!(set.try_reserve_dense(3).is_ok());
let capacity = set.dense_capacity();
assert!(capacity >= 2);
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
assert!(set.try_reserve_dense(1).is_ok());
assert_eq!(set.dense_capacity(), capacity);
}
#[test]
fn test_try_reserve_sparse_succeeds() {
let mut set = SparseSet::new();
assert_eq!(set.sparse_capacity(), 0);
assert!(set.try_reserve_sparse(3).is_ok());
let capacity = set.sparse_capacity();
assert!(capacity >= 2);
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
assert!(set.try_reserve_sparse(1).is_ok());
assert_eq!(set.sparse_capacity(), capacity);
}
#[test]
fn test_try_reserve_exact_succeeds() {
let mut set = SparseSet::new();
assert_eq!(set.dense_capacity(), 0);
assert!(set.try_reserve_exact_dense(3).is_ok());
let capacity = set.dense_capacity();
assert!(capacity >= 2);
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
assert!(set.try_reserve_exact_dense(1).is_ok());
assert_eq!(set.dense_capacity(), capacity);
}
#[test]
fn test_try_reserve_exact_sparse_succeeds() {
let mut set = SparseSet::new();
assert_eq!(set.sparse_capacity(), 0);
assert!(set.try_reserve_exact_sparse(3).is_ok());
let capacity = set.sparse_capacity();
assert!(capacity >= 2);
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
assert!(set.try_reserve_exact_sparse(1).is_ok());
assert_eq!(set.sparse_capacity(), capacity);
}
#[test]
fn test_values() {
let mut set = SparseSet::new();
assert!(set.values().eq(&[]));
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert!(set.values().eq(&[1, 2, 3]));
}
#[test]
fn test_values_mut() {
let mut set = SparseSet::new();
assert!(set.values_mut().eq(&[]));
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert!(set.values_mut().eq(&[1, 2, 3]));
let value = set.values_mut().next().unwrap();
*value = 100;
assert_eq!(set.get(0), Some(&100));
}
#[test]
fn test_as_ref() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let reference: &SparseSet<_, _> = set.as_ref();
assert_eq!(reference.first(), Some(&1));
let reference: &[usize] = set.as_ref();
assert_eq!(reference.first(), Some(&1));
}
#[test]
fn test_as_mut() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let reference: &mut SparseSet<_, _> = set.as_mut();
assert_eq!(reference.first(), Some(&1));
let reference: &mut [usize] = set.as_mut();
assert_eq!(reference.first(), Some(&1));
}
#[allow(clippy::redundant_clone)]
#[test]
fn test_clone() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let cloned_set = set.clone();
assert_eq!(set, cloned_set);
}
#[allow(clippy::redundant_clone)]
#[test]
fn test_clone_zero_capacity() {
let set: SparseSet<usize, usize> = SparseSet::new();
assert_eq!(set.dense_capacity(), 0);
let cloned_set = set.clone();
assert_eq!(set, cloned_set);
}
#[test]
fn test_clone_drops_are_separate() {
let num_dropped = Rc::new(RefCell::new(0));
{
let mut set = SparseSet::new();
let value = Value(num_dropped.clone());
mem::drop(set.insert(0, value.clone()));
mem::drop(set.insert(1, value.clone()));
mem::drop(set.insert(2, value));
let _cloned_set = set.clone();
}
assert_eq!(*num_dropped.borrow(), 6);
}
#[test]
fn test_debug() {
let mut set = SparseSet::new();
assert_eq!(format!("{:?}", set), "{}");
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert_eq!(format!("{:?}", set), "{0: 1, 1: 2, 2: 3}");
}
#[test]
fn test_default() {
let set: SparseSet<usize, usize> = SparseSet::default();
assert!(set.is_empty());
assert_eq!(set.dense_capacity(), 0);
assert_eq!(set.sparse_capacity(), 0);
}
#[test]
fn test_deref() {
let mut set: SparseSet<usize, usize> = SparseSet::default();
let _ = set.insert(0, 1);
assert_eq!(&*set, &[1]);
}
#[test]
fn test_deref_mut() {
let mut set: SparseSet<usize, usize> = SparseSet::default();
let _ = set.insert(0, 1);
assert_eq!(&mut *set, &mut [1]);
}
#[test]
fn test_drop() {
let num_dropped = Rc::new(RefCell::new(0));
{
let mut set = SparseSet::new();
let value = Value(num_dropped.clone());
mem::drop(set.insert(0, value.clone()));
mem::drop(set.insert(1, value.clone()));
mem::drop(set.insert(2, value));
}
assert_eq!(*num_dropped.borrow(), 3);
}
#[test]
fn test_extend() {
let mut set = SparseSet::new();
set.extend([(0, 1), (1, 2), (2, 3)]);
assert!(set.values().eq(&[1, 2, 3]));
}
#[test]
fn test_extend_ref() {
let mut set: SparseSet<usize, usize> = SparseSet::new();
set.extend([(0, &1), (1, &2), (2, &3)]);
assert!(set.values().eq(&[1, 2, 3]));
}
#[test]
fn test_from_array() {
let set = SparseSet::from([(0, 1), (1, 2), (2, 3)]);
assert!(set.values().eq(&[1, 2, 3]));
}
#[test]
fn test_from_iterator() {
let set = SparseSet::from_iter([(0, 1), (1, 2), (2, 3)]);
assert!(set.values().eq(&[1, 2, 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: &SparseSet<usize, usize>) -> u64 {
let mut hasher = TestHasher::default();
value.hash(&mut hasher);
assert!(hasher.writes_made >= value.len());
hasher.finish()
}
let mut set_1 = SparseSet::new();
let mut set_2 = SparseSet::new();
assert_eq!(set_1, set_2);
assert_eq!(hash(&set_1), hash(&set_2));
let _ = set_1.insert(0, 1);
assert_ne!(set_1, set_2);
let _ = set_2.insert(0, 2);
assert_ne!(set_1, set_2);
let _ = set_2.remove(0);
let _ = set_2.insert(1, 2);
assert_ne!(set_1, set_2);
let _ = set_1.insert(1, 2);
let _ = set_2.insert(0, 1);
assert_eq!(set_1, set_2);
assert_eq!(hash(&set_1), hash(&set_2));
let _ = set_1.remove(0);
let _ = set_2.remove(0);
assert_eq!(set_1, set_2);
assert_eq!(hash(&set_1), hash(&set_2));
}
#[test]
fn test_index() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert_eq!(set[0], 1);
assert_eq!(set[2], 3);
}
#[should_panic]
#[test]
fn test_index_panics() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let _ = &set[100];
}
#[test]
fn test_index_mut() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let value = &mut set[2];
assert_eq!(value, &mut 3);
*value = 10;
assert_eq!(set[2], 10);
}
#[should_panic]
#[test]
fn test_index_mut_panics() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let _ = &mut set[100];
}
#[test]
fn test_into_iterator() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert!(set.into_iter().eq([(0, 1), (1, 2), (2, 3)]));
}
#[test]
fn test_into_iterator_ref() {
let mut set = SparseSet::new();
assert!((&set).into_iter().eq([]));
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert!((&set).into_iter().eq([(0, &1), (1, &2), (2, &3)]));
}
#[test]
fn test_into_iterator_mut() {
let mut set = SparseSet::new();
assert!((&mut set).into_iter().eq([]));
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
assert!((&mut set)
.into_iter()
.eq([(0, &mut 1), (1, &mut 2), (2, &mut 3)]));
let value = (&mut set).into_iter().next().unwrap();
*(value.1) = 100;
assert_eq!(set.first(), Some(&100));
}
#[test]
fn test_eq() {
let mut set_1 = SparseSet::new();
let mut set_2 = SparseSet::new();
assert_eq!(set_1, set_2);
let _ = set_1.insert(0, 1);
assert_ne!(set_1, set_2);
let _ = set_2.insert(0, 2);
assert_ne!(set_1, set_2);
let _ = set_2.remove(0);
let _ = set_2.insert(1, 2);
assert_ne!(set_1, set_2);
let _ = set_1.insert(1, 2);
let _ = set_2.insert(0, 1);
assert_eq!(set_1, set_2);
let _ = set_1.remove(0);
let _ = set_2.remove(0);
assert_eq!(set_1, set_2);
}
#[test]
fn test_immutable_entry_dense_index() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let entry = set.immutable_entry(2).unwrap();
assert_eq!(entry.dense_index(), 2);
}
#[test]
fn test_immutable_entry_get() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let entry = set.immutable_entry(1).unwrap();
assert_eq!(entry.get(), &2);
}
#[test]
fn test_immutable_entry_entry_index() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let entry = set.immutable_entry(1).unwrap();
assert_eq!(entry.entry_index(), 1);
}
#[test]
fn test_immutable_entry_stored_index() {
let mut set = SparseSet::new();
let _ = set.insert(Index::new(0, 0), 1);
let _ = set.insert(Index::new(1, 0), 2);
let _ = set.insert(Index::new(2, 0), 3);
let entry = set.immutable_entry(Index::new(1, 1)).unwrap();
assert_eq!(entry.entry_index(), Index::new(1, 1));
assert_eq!(entry.stored_index(), Index::new(1, 0));
}
#[test]
fn test_immutable_entry_debug() {
let mut set: SparseSet<usize, usize> = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let entry = set.immutable_entry(1).unwrap();
assert_eq!(
format!("{:?}", entry),
"ImmutableEntry { index: 1, value: 2 }"
);
}
#[test]
fn test_entry_and_modify() {
let mut set: SparseSet<usize, usize> = SparseSet::new();
let _ = set.insert(0, 1);
assert_eq!(set.get(0), Some(&1));
let _ = set.entry(0).and_modify(|value| *value += 1);
assert_eq!(set.get(0), Some(&2));
assert_eq!(set.get(1), None);
let _ = set.entry(0).and_modify(|value| *value += 1);
assert_eq!(set.get(1), None);
}
#[test]
fn test_entry_or_insert() {
let mut set: SparseSet<usize, usize> = SparseSet::new();
let _ = set.insert(0, 1);
assert_eq!(set.get(0), Some(&1));
let value = set.entry(0).or_insert(2);
assert_eq!(value, &1);
assert_eq!(set.get(0), Some(&1));
assert_eq!(set.get(1), None);
let value = set.entry(1).or_insert(2);
assert_eq!(value, &2);
assert_eq!(set.get(1), Some(&2));
}
#[test]
fn test_entry_or_insert_with() {
let mut set: SparseSet<usize, usize> = SparseSet::new();
let _ = set.insert(0, 1);
assert_eq!(set.get(0), Some(&1));
let value = set.entry(0).or_insert_with(|| 2);
assert_eq!(value, &1);
assert_eq!(set.get(0), Some(&1));
assert_eq!(set.get(1), None);
let value = set.entry(1).or_insert_with(|| 2);
assert_eq!(value, &2);
assert_eq!(set.get(1), Some(&2));
}
#[test]
fn test_entry_entry_index() {
let mut set: SparseSet<usize, usize> = SparseSet::new();
let _ = set.insert(0, 1);
let entry = set.entry(0);
assert_eq!(entry.entry_index(), 0);
let entry = set.entry(1);
assert_eq!(entry.entry_index(), 1);
}
#[test]
fn test_entry_insert_entry() {
let mut set: SparseSet<usize, usize> = SparseSet::new();
let _ = set.insert(0, 1);
assert_eq!(set.get(0), Some(&1));
let entry = set.entry(0).insert_entry(2);
assert_eq!(entry.get(), &2);
assert_eq!(set.get(0), Some(&2));
assert_eq!(set.get(1), None);
let entry = set.entry(0).insert_entry(2);
assert_eq!(entry.get(), &2);
assert_eq!(set.get(0), Some(&2));
}
#[test]
fn test_entry_debug() {
let mut set: SparseSet<usize, usize> = SparseSet::new();
let _ = set.insert(0, 1);
let entry = set.entry(0);
assert_eq!(
format!("{:?}", entry),
"Entry(OccupiedEntry { index: 0, value: 1 })"
);
let entry = set.entry(1);
assert_eq!(format!("{:?}", entry), "Entry(VacantEntry(1))");
}
#[test]
fn test_vacant_entry_entry_index() {
let mut set: SparseSet<usize, usize> = SparseSet::new();
let entry = match set.entry(0) {
Entry::Vacant(entry) => entry,
Entry::Occupied(_) => panic!("expected vacant entry"),
};
assert_eq!(entry.entry_index(), 0);
}
#[test]
fn test_vacant_entry_insert() {
let mut set = SparseSet::new();
let entry = match set.entry(0) {
Entry::Vacant(entry) => entry,
Entry::Occupied(_) => panic!("expected vacant entry"),
};
assert_eq!(entry.insert(1), &mut 1);
assert_eq!(set.get(0), Some(&1));
}
#[test]
fn test_vacant_entry_insert_entry() {
let mut set = SparseSet::new();
let entry = match set.entry(0) {
Entry::Vacant(entry) => entry,
Entry::Occupied(_) => panic!("expected vacant entry"),
};
assert_eq!(entry.insert_entry(1).get(), &1);
assert_eq!(set.get(0), Some(&1));
}
#[test]
fn test_vacant_entry_debug() {
let mut set: SparseSet<usize, usize> = SparseSet::new();
let entry = match set.entry(0) {
Entry::Vacant(entry) => entry,
Entry::Occupied(_) => panic!("expected vacant entry"),
};
assert_eq!(format!("{:?}", entry), "VacantEntry(0)");
}
#[test]
fn test_occupied_entry_dense_index() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let entry = match set.entry(2) {
Entry::Vacant(_) => panic!("expected occupied entry"),
Entry::Occupied(entry) => entry,
};
assert_eq!(entry.dense_index(), 2);
}
#[test]
fn test_occupied_entry_get() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let entry = match set.entry(1) {
Entry::Vacant(_) => panic!("expected occupied entry"),
Entry::Occupied(entry) => entry,
};
assert_eq!(entry.get(), &2);
}
#[test]
fn test_occupied_entry_get_mut() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let mut entry = match set.entry(1) {
Entry::Vacant(_) => panic!("expected occupied entry"),
Entry::Occupied(entry) => entry,
};
let value = entry.get_mut();
assert_eq!(value, &mut 2);
*value = 3;
assert_eq!(set.get(1), Some(&3));
}
#[test]
fn test_occupied_entry_into_mut() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let entry = match set.entry(1) {
Entry::Vacant(_) => panic!("expected occupied entry"),
Entry::Occupied(entry) => entry,
};
let value = entry.into_mut();
assert_eq!(value, &mut 2);
*value = 3;
assert_eq!(set.get(1), Some(&3));
}
#[test]
fn test_occupied_entry_entry_index() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let entry = match set.entry(1) {
Entry::Vacant(_) => panic!("expected occupied entry"),
Entry::Occupied(entry) => entry,
};
assert_eq!(entry.entry_index(), 1);
}
#[test]
fn test_occupied_entry_stored_index() {
let mut set = SparseSet::new();
let _ = set.insert(Index::new(0, 0), 1);
let _ = set.insert(Index::new(1, 0), 2);
let _ = set.insert(Index::new(2, 0), 3);
let entry = match set.entry(Index::new(1, 1)) {
Entry::Vacant(_) => panic!("expected occupied entry"),
Entry::Occupied(entry) => entry,
};
assert_eq!(entry.entry_index(), Index::new(1, 1));
assert_eq!(entry.stored_index(), Index::new(1, 0));
}
#[test]
fn test_occupied_entry_insert() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let mut entry = match set.entry(1) {
Entry::Vacant(_) => panic!("expected occupied entry"),
Entry::Occupied(entry) => entry,
};
assert_eq!(entry.insert(3), 2);
assert_eq!(set.get(1), Some(&3));
}
#[test]
fn test_occupied_entry_insert_with_index() {
let mut set = SparseSet::new();
let _ = set.insert(Index::new(0, 0), 1);
let _ = set.insert(Index::new(1, 0), 2);
let _ = set.insert(Index::new(2, 0), 3);
let mut entry = match set.entry(Index::new(1, 1)) {
Entry::Vacant(_) => panic!("expected occupied entry"),
Entry::Occupied(entry) => entry,
};
assert_eq!(entry.stored_index(), Index::new(1, 0));
assert_eq!(entry.insert_with_index(3), (Index::new(1, 0), 2));
assert_eq!(entry.stored_index(), Index::new(1, 1));
assert_eq!(
set.get_with_index(Index::new(1, 0)),
Some((Index::new(1, 1), &3))
);
}
#[test]
fn test_occupied_entry_remove() {
let mut set = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let entry = match set.entry(1) {
Entry::Vacant(_) => panic!("expected occupied entry"),
Entry::Occupied(entry) => entry,
};
assert_eq!(entry.remove(), 2);
assert_eq!(set.get(1), None);
}
#[test]
fn test_occupied_entry_remove_with_index() {
let mut set = SparseSet::new();
let _ = set.insert(Index::new(0, 0), 1);
let _ = set.insert(Index::new(1, 0), 2);
let _ = set.insert(Index::new(2, 0), 3);
let entry = match set.entry(Index::new(1, 1)) {
Entry::Vacant(_) => panic!("expected occupied entry"),
Entry::Occupied(entry) => entry,
};
assert_eq!(entry.remove_with_index(), (Index::new(1, 0), 2));
assert_eq!(set.get_with_index(Index::new(1, 0)), None,);
}
#[test]
fn test_occupied_entry_debug() {
let mut set: SparseSet<usize, usize> = SparseSet::new();
let _ = set.insert(0, 1);
let _ = set.insert(1, 2);
let _ = set.insert(2, 3);
let entry = match set.entry(1) {
Entry::Vacant(_) => panic!("expected occupied entry"),
Entry::Occupied(entry) => entry,
};
assert_eq!(
format!("{:?}", entry),
"OccupiedEntry { index: 1, value: 2 }"
);
}
}