use std::fmt;
use std::fmt::Debug;
use std::marker::PhantomData;
use crate::map::iter::ValuesMut;
use crate::map::total;
use crate::map::Drain;
use crate::map::Entry;
use crate::map::IntoIter;
use crate::map::Iter;
use crate::map::IterMut;
use crate::map::Keys;
use crate::map::Values;
use crate::Ordinal;
pub struct OrdinalMap<K, V> {
map: Box<[Option<V>]>,
_phantom: PhantomData<K>,
}
impl<K: Ordinal, V> OrdinalMap<K, V> {
#[inline]
pub fn new() -> Self {
OrdinalMap {
map: Box::default(),
_phantom: PhantomData,
}
}
#[inline]
pub fn get<'a>(&'a self, key: &K) -> Option<&'a V> {
self.map.get(key.ordinal())?.as_ref()
}
#[inline]
pub fn get_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
self.map.get_mut(key.ordinal())?.as_mut()
}
#[inline]
pub fn contains_key(&self, key: &K) -> bool {
self.map.get(key.ordinal()).is_some()
}
#[inline]
pub fn len(&self) -> usize {
self.iter().count()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.iter().next().is_none()
}
fn init_full_map(&mut self) {
if self.map.is_empty() {
let mut map = Vec::with_capacity(K::ORDINAL_SIZE);
for _ in 0..K::ORDINAL_SIZE {
map.push(None);
}
self.map = map.into_boxed_slice();
}
}
#[inline]
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
self.init_full_map();
self.map[key.ordinal()].replace(value)
}
pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
self.init_full_map();
let entry = &mut self.map[key.ordinal()];
Entry::new(key, entry)
}
#[inline]
pub fn remove(&mut self, key: &K) -> Option<V> {
self.map.get_mut(key.ordinal())?.take()
}
#[inline]
pub fn iter(&self) -> Iter<'_, K, V> {
Iter::new(total::Iter::new(self.map.iter(), 0))
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
IterMut::new(total::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(total::IterMut::new(self.map.iter_mut()))
}
#[inline]
pub fn clear(&mut self) {
self.drain();
}
}
impl<K: Ordinal, V> Default for OrdinalMap<K, V> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<K: Ordinal, V> FromIterator<(K, V)> for OrdinalMap<K, V> {
fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
let mut map = OrdinalMap::new();
for (k, v) in iter {
map.insert(k, v);
}
map
}
}
impl<K, V: Clone> Clone for OrdinalMap<K, V> {
fn clone(&self) -> Self {
OrdinalMap {
map: self.map.clone(),
_phantom: PhantomData,
}
}
}
impl<K: Ordinal + Debug, V: Debug> Debug for OrdinalMap<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_map().entries(self.iter()).finish()
}
}
impl<K: Ordinal, V> IntoIterator for OrdinalMap<K, V> {
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
IntoIter::new(total::IntoIter::new(self.map.into_vec().into_iter()))
}
}
impl<'a, K: Ordinal, V> IntoIterator for &'a OrdinalMap<K, V> {
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 crate::map::OrdinalMap;
#[quickcheck]
fn qc(values: Vec<(u8, u32)>, check: Vec<u8>) {
let mut map: OrdinalMap<u8, u32> = OrdinalMap::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));
}
}
}