#[cfg(feature = "alloc")]
mod btreemap;
#[cfg(any(feature = "std", feature = "indexmap"))]
mod hashmap;
#[cfg(feature = "slotmap")]
pub mod slotmap;
use core::{
fmt::{self, Debug},
ops::RangeBounds,
};
#[cfg(feature = "rayon")]
use rayon::iter::{IntoParallelIterator, Map as ParMap, ParallelIterator};
pub trait Map<T>: Default {
type Key: Copy + Eq + Debug + 'static;
type Iter<'a>: Iterator<Item = (Self::Key, &'a T)>
where
Self: 'a,
T: 'a;
type IterMut<'a>: Iterator<Item = (Self::Key, &'a mut T)>
where
Self: 'a,
T: 'a;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn contains_key(&self, index: Self::Key) -> bool {
self.get(index).is_some()
}
fn get(&self, index: Self::Key) -> Option<&T>;
fn get_mut(&mut self, index: Self::Key) -> Option<&mut T>;
fn remove(&mut self, index: Self::Key) -> Option<T>;
fn clear(&mut self);
fn iter(&self) -> Self::Iter<'_>;
fn iter_mut(&mut self) -> Self::IterMut<'_>;
}
pub trait MapWithCapacity<T>: Map<T> {
fn with_capacity(capacity: usize) -> Self;
fn capacity(&self) -> usize;
fn reserve(&mut self, additional: usize);
}
#[derive(Debug)]
pub struct OccupiedError;
impl fmt::Display for OccupiedError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("map entry is occupied")
}
}
#[cfg(feature = "std")]
impl std::error::Error for OccupiedError {}
pub trait ExtKeyMap<T>: Map<T> {
fn try_insert(&mut self, key: Self::Key, value: T) -> Result<(), OccupiedError>;
fn replace(&mut self, key: Self::Key, value: T) -> Option<T>;
}
pub trait IntKeyMap<T>: Map<T> {
fn insert(&mut self, value: T) -> Self::Key;
fn insert_with_key<F: FnOnce(Self::Key) -> T>(&mut self, f: F) -> Self::Key;
}
pub trait OrderedKeyMap<T>: ExtKeyMap<T>
where
Self::Key: Ord,
{
type Range<'a>: Iterator<Item = (Self::Key, &'a T)> + DoubleEndedIterator
where
Self: 'a,
T: 'a;
type RangeMut<'a>: Iterator<Item = (Self::Key, &'a mut T)> + DoubleEndedIterator
where
Self: 'a,
T: 'a;
fn range<R: RangeBounds<Self::Key>>(&self, range: R) -> Self::Range<'_>;
fn range_mut<R: RangeBounds<Self::Key>>(&mut self, range: R) -> Self::RangeMut<'_>;
fn first(&self) -> Option<(Self::Key, &T)> {
self.range(..).next()
}
fn first_mut(&mut self) -> Option<(Self::Key, &mut T)> {
self.range_mut(..).next()
}
fn last(&self) -> Option<(Self::Key, &T)> {
self.range(..).last()
}
fn last_mut(&mut self) -> Option<(Self::Key, &mut T)> {
self.range_mut(..).last()
}
}
#[cfg(feature = "rayon")]
pub trait ParIterMap<T>: Map<T> {
type ParIter<'a>: ParallelIterator<Item = (Self::Key, &'a T)>
where
Self: 'a,
T: 'a;
type ParIterMut<'a>: ParallelIterator<Item = (Self::Key, &'a mut T)>
where
Self: 'a,
T: 'a;
fn par_iter(&self) -> Self::ParIter<'_>;
fn par_iter_mut(&mut self) -> Self::ParIterMut<'_>;
}
#[cfg(feature = "rayon")]
impl<M, K, T> ParIterMap<T> for M
where
M: Map<T, Key = K>,
K: Copy + Eq + Debug + Send + Sync + 'static,
T: Send + Sync,
for<'a> &'a M: IntoParallelIterator<Item = (&'a K, &'a T)>,
for<'a> &'a mut M: IntoParallelIterator<Item = (&'a K, &'a mut T)>,
{
type ParIter<'a> = ParMap<
<&'a M as IntoParallelIterator>::Iter,
fn((&'a K, &'a T)) -> (K, &'a T)
> where Self: 'a, T: 'a;
type ParIterMut<'a> = ParMap<
<&'a mut M as IntoParallelIterator>::Iter,
fn((&'a K, &'a mut T)) -> (K, &'a mut T)
> where Self: 'a, T: 'a;
fn par_iter(&self) -> Self::ParIter<'_> {
IntoParallelIterator::into_par_iter(self).map(|(&k, v)| (k, v))
}
fn par_iter_mut(&mut self) -> Self::ParIterMut<'_> {
IntoParallelIterator::into_par_iter(self).map(|(&k, v)| (k, v))
}
}
pub trait KeySet<K: Copy + Eq + Debug + 'static> {
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn contains(&self, index: K) -> bool;
fn insert(&mut self, index: K) -> bool;
fn remove(&mut self, index: K) -> bool;
fn clear(&mut self);
}
impl<K: Copy + Eq + Debug + 'static, T: ExtKeyMap<(), Key = K>> KeySet<K> for T {
fn len(&self) -> usize {
Map::len(self)
}
fn is_empty(&self) -> bool {
Map::is_empty(self)
}
fn contains(&self, index: K) -> bool {
Map::contains_key(self, index)
}
fn insert(&mut self, index: K) -> bool {
ExtKeyMap::replace(self, index, ()).is_some()
}
fn remove(&mut self, index: K) -> bool {
Map::remove(self, index).is_some()
}
fn clear(&mut self) {
Map::clear(self)
}
}
pub trait VacantMapEntry {
type Value;
fn insert<'a>(self, value: Self::Value) -> &'a mut Self::Value
where
Self: 'a;
}
pub trait OccupiedMapEntry {
type Value;
fn get(&self) -> &Self::Value;
fn get_mut(&mut self) -> &mut Self::Value;
fn into_mut<'a>(self) -> &'a mut Self::Value
where
Self: 'a;
fn replace(&mut self, value: Self::Value) -> Self::Value;
fn remove(self) -> Self::Value;
}
#[derive(Clone, Debug)]
pub enum MapEntry<O, V> {
Vacant(V),
Occupied(O),
}
pub trait MapWithEntry<T>: ExtKeyMap<T> {
type VacantEntry<'a>: VacantMapEntry<Value = T>
where
Self: 'a;
type OccupiedEntry<'a>: OccupiedMapEntry<Value = T>
where
Self: 'a;
fn entry(&mut self, key: Self::Key)
-> MapEntry<Self::OccupiedEntry<'_>, Self::VacantEntry<'_>>;
}