use core::{
borrow::Borrow,
fmt,
iter::FromIterator,
mem::{self, MaybeUninit},
ops, ptr, slice,
};
use generic_array::{ArrayLength, GenericArray};
use crate::Vec;
pub struct LinearMap<K, V, N>(#[doc(hidden)] pub crate::i::LinearMap<GenericArray<(K, V), N>>)
where
N: ArrayLength<(K, V)>,
K: Eq;
impl<A> crate::i::LinearMap<A> {
pub const fn new() -> Self {
Self {
buffer: crate::i::Vec::new(),
}
}
}
impl<K, V, N> LinearMap<K, V, N>
where
N: ArrayLength<(K, V)>,
K: Eq,
{
pub fn new() -> Self {
LinearMap(crate::i::LinearMap::new())
}
pub fn capacity(&self) -> usize {
N::to_usize()
}
pub fn clear(&mut self) {
self.0.buffer.clear()
}
pub fn contains_key(&self, key: &K) -> bool {
self.get(key).is_some()
}
pub fn get<Q>(&self, key: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: Eq + ?Sized,
{
self.iter()
.find(|&(k, _)| k.borrow() == key)
.map(|(_, v)| v)
}
pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
Q: Eq + ?Sized,
{
self.iter_mut()
.find(|&(k, _)| k.borrow() == key)
.map(|(_, v)| v)
}
pub fn len(&self) -> usize {
self.0.buffer.len
}
pub fn insert(&mut self, key: K, mut value: V) -> Result<Option<V>, (K, V)> {
if let Some((_, v)) = self.iter_mut().find(|&(k, _)| *k == key) {
mem::swap(v, &mut value);
return Ok(Some(value));
}
self.0.buffer.push((key, value))?;
Ok(None)
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn iter(&self) -> Iter<'_, K, V> {
Iter {
iter: self.0.buffer.as_slice().iter(),
}
}
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
IterMut {
iter: self.0.buffer.as_mut_slice().iter_mut(),
}
}
pub fn keys(&self) -> impl Iterator<Item = &K> {
self.iter().map(|(k, _)| k)
}
pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
where
K: Borrow<Q>,
Q: Eq + ?Sized,
{
let idx = self
.keys()
.enumerate()
.find(|&(_, k)| k.borrow() == key)
.map(|(idx, _)| idx);
idx.map(|idx| self.0.buffer.swap_remove(idx).1)
}
pub fn values(&self) -> impl Iterator<Item = &V> {
self.iter().map(|(_, v)| v)
}
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
self.iter_mut().map(|(_, v)| v)
}
}
impl<'a, K, V, N, Q> ops::Index<&'a Q> for LinearMap<K, V, N>
where
N: ArrayLength<(K, V)>,
K: Borrow<Q> + Eq,
Q: Eq + ?Sized,
{
type Output = V;
fn index(&self, key: &Q) -> &V {
self.get(key).expect("no entry found for key")
}
}
impl<'a, K, V, N, Q> ops::IndexMut<&'a Q> for LinearMap<K, V, N>
where
N: ArrayLength<(K, V)>,
K: Borrow<Q> + Eq,
Q: Eq + ?Sized,
{
fn index_mut(&mut self, key: &Q) -> &mut V {
self.get_mut(key).expect("no entry found for key")
}
}
impl<K, V, N> Default for LinearMap<K, V, N>
where
N: ArrayLength<(K, V)>,
K: Eq,
{
fn default() -> Self {
Self::new()
}
}
impl<K, V, N> Clone for LinearMap<K, V, N>
where
N: ArrayLength<(K, V)>,
K: Eq + Clone,
V: Clone,
{
fn clone(&self) -> Self {
Self(crate::i::LinearMap {
buffer: self.0.buffer.clone(),
})
}
}
impl<K, V, N> fmt::Debug for LinearMap<K, V, N>
where
N: ArrayLength<(K, V)>,
K: Eq + fmt::Debug,
V: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_map().entries(self.iter()).finish()
}
}
impl<K, V, N> FromIterator<(K, V)> for LinearMap<K, V, N>
where
N: ArrayLength<(K, V)>,
K: Eq,
{
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = (K, V)>,
{
let mut out = Self::new();
out.0.buffer.extend(iter);
out
}
}
pub struct IntoIter<K, V, N>
where
N: ArrayLength<(K, V)>,
K: Eq,
{
inner: <Vec<(K, V), N> as IntoIterator>::IntoIter,
}
impl<K, V, N> Iterator for IntoIter<K, V, N>
where
N: ArrayLength<(K, V)>,
K: Eq,
{
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<K, V, N> IntoIterator for LinearMap<K, V, N>
where
N: ArrayLength<(K, V)>,
K: Eq,
{
type Item = (K, V);
type IntoIter = IntoIter<K, V, N>;
fn into_iter(mut self) -> Self::IntoIter {
let lm = mem::replace(&mut self.0, unsafe { MaybeUninit::uninit().assume_init() });
mem::forget(self);
Self::IntoIter {
inner: crate::Vec(lm.buffer).into_iter(),
}
}
}
impl<'a, K, V, N> IntoIterator for &'a LinearMap<K, V, N>
where
N: ArrayLength<(K, V)>,
K: Eq,
{
type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub struct Iter<'a, K, V> {
iter: slice::Iter<'a, (K, V)>,
}
impl<'a, K, V> Iterator for Iter<'a, K, V> {
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|&(ref k, ref v)| (k, v))
}
}
impl<'a, K, V> Clone for Iter<'a, K, V> {
fn clone(&self) -> Self {
Self {
iter: self.iter.clone(),
}
}
}
impl<K, V, N> Drop for LinearMap<K, V, N>
where
N: ArrayLength<(K, V)>,
K: Eq,
{
fn drop(&mut self) {
unsafe { ptr::drop_in_place(self.0.buffer.as_mut_slice()) }
}
}
pub struct IterMut<'a, K, V> {
iter: slice::IterMut<'a, (K, V)>,
}
impl<'a, K, V> Iterator for IterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|&mut (ref k, ref mut v)| (k, v))
}
}
impl<K, V, N, N2> PartialEq<LinearMap<K, V, N2>> for LinearMap<K, V, N>
where
K: Eq,
V: PartialEq,
N: ArrayLength<(K, V)>,
N2: ArrayLength<(K, V)>,
{
fn eq(&self, other: &LinearMap<K, V, N2>) -> bool {
self.len() == other.len()
&& self
.iter()
.all(|(key, value)| other.get(key).map_or(false, |v| *value == *v))
}
}
impl<K, V, N> Eq for LinearMap<K, V, N>
where
K: Eq,
V: PartialEq,
N: ArrayLength<(K, V)>,
{
}
#[cfg(test)]
mod test {
use crate::{consts::*, LinearMap};
#[test]
fn static_new() {
static mut _L: LinearMap<i32, i32, U8> = LinearMap(crate::i::LinearMap::new());
}
#[test]
fn partial_eq() {
{
let mut a = LinearMap::<_, _, U1>::new();
a.insert("k1", "v1").unwrap();
let mut b = LinearMap::<_, _, U2>::new();
b.insert("k1", "v1").unwrap();
assert!(a == b);
b.insert("k2", "v2").unwrap();
assert!(a != b);
}
{
let mut a = LinearMap::<_, _, U2>::new();
a.insert("k1", "v1").unwrap();
a.insert("k2", "v2").unwrap();
let mut b = LinearMap::<_, _, U2>::new();
b.insert("k2", "v2").unwrap();
b.insert("k1", "v1").unwrap();
assert!(a == b);
}
}
}