use std::fmt;
use std::fmt::Debug;
use crate::map::iter::IntoIterArray;
use crate::map::iter::Iter;
use crate::map::iter::IterMut;
use crate::map::iter::ValuesMut;
use crate::map::total::array_map::OrdinalTotalArrayMap;
use crate::map::Drain;
use crate::map::Entry;
use crate::map::Keys;
use crate::map::Values;
use crate::Ordinal;
pub struct OrdinalArrayMap<K, V, const S: usize> {
map: OrdinalTotalArrayMap<K, Option<V>, S>,
}
impl<K: Ordinal, V, const S: usize> OrdinalArrayMap<K, V, S> {
#[inline]
pub fn new() -> Self {
OrdinalArrayMap {
map: OrdinalTotalArrayMap::new(|_| None),
}
}
#[inline]
pub fn len(&self) -> usize {
self.iter().count()
}
pub fn is_empty(&self) -> bool {
self.iter().next().is_none()
}
#[inline]
pub fn get<'a>(&'a self, key: &K) -> Option<&'a V> {
self.map.get(key).as_ref()
}
#[inline]
pub fn get_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
self.map.get_mut(key).as_mut()
}
#[inline]
pub fn contains_key(&self, key: &K) -> bool {
self.get(key).is_some()
}
#[inline]
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
self.map.get_mut(&key).replace(value)
}
#[inline]
pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
let entry = &mut self.map[&key];
Entry::new(key, entry)
}
#[inline]
pub fn remove(&mut self, key: &K) -> Option<V> {
self.map.get_mut(key).take()
}
#[inline]
pub fn iter<'a>(&'a self) -> Iter<'a, K, V> {
Iter::new(self.map.iter())
}
#[inline]
pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a, K, V> {
IterMut::new(self.map.iter_mut())
}
#[inline]
pub fn keys(&self) -> Keys<'_, K, V> {
Keys::new(self.iter())
}
#[inline]
pub fn values(&self) -> Values<'_, K, V> {
Values::new(self.iter())
}
#[inline]
pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
ValuesMut::new(self.iter_mut())
}
#[inline]
pub fn drain(&mut self) -> Drain<'_, K, V> {
Drain::new(self.map.iter_mut())
}
#[inline]
pub fn clear(&mut self) {
self.drain();
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(K, &mut V) -> bool,
{
for (key, value_opt) in self.map.iter_mut() {
if let Some(value) = value_opt {
if !f(key, value) {
*value_opt = None;
}
}
}
}
}
impl<K: Ordinal, V, const S: usize> Default for OrdinalArrayMap<K, V, S> {
#[inline]
fn default() -> Self {
OrdinalArrayMap::new()
}
}
impl<K: Ordinal, V, const S: usize> FromIterator<(K, V)> for OrdinalArrayMap<K, V, S> {
fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
let mut map = OrdinalArrayMap::new();
for (key, value) in iter {
map.insert(key, value);
}
map
}
}
impl<K: Ordinal, V: Clone, const S: usize> Clone for OrdinalArrayMap<K, V, S> {
fn clone(&self) -> Self {
OrdinalArrayMap {
map: self.map.clone(),
}
}
}
impl<K: Ordinal + Debug, V: Debug, const S: usize> Debug for OrdinalArrayMap<K, V, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_map().entries(self.iter()).finish()
}
}
impl<K: Ordinal, V, const S: usize> IntoIterator for OrdinalArrayMap<K, V, S> {
type Item = (K, V);
type IntoIter = IntoIterArray<K, V, S>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
IntoIterArray::new(self.map.into_iter())
}
}
impl<'a, K: Ordinal, V, const S: usize> IntoIterator for &'a OrdinalArrayMap<K, V, S> {
type Item = (K, &'a V);
type IntoIter = Iter<'a, K, V>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use std::collections::HashSet;
use crate::map::OrdinalArrayMap;
use crate::Ordinal;
#[quickcheck]
fn qc(values: Vec<(u8, u32)>, check: Vec<u8>) {
let mut map: OrdinalArrayMap<u8, u32, { u8::ORDINAL_SIZE }> = OrdinalArrayMap::new();
let mut control: HashMap<u8, u32> = HashMap::new();
for (key, value) in &values {
let control_inserted = control.insert(*key, *value);
let inserted = map.insert(*key, *value);
assert_eq!(control_inserted, inserted);
assert_eq!(control.len(), map.len());
}
for key in &check {
assert_eq!(control.get(key), map.get(key));
}
}
#[quickcheck]
fn qc_retain(values: Vec<(u8, u32)>, retain: Vec<u8>) -> bool {
let retain: HashSet<u8> = HashSet::from_iter(retain);
let mut map = OrdinalArrayMap::<u8, u32, { u8::ORDINAL_SIZE }>::from_iter(values.clone());
let mut control: HashMap<u8, u32> = HashMap::from_iter(values);
map.retain(|key, _| retain.contains(&key));
control.retain(|key, _| retain.contains(key));
control == HashMap::from_iter(map)
}
}