#![allow(dead_code)] use std::borrow::Borrow; /// Flat (Vec) backed map /// /// This preserves insertion order #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) struct FlatMap { keys: Vec, values: Vec, } impl FlatMap { pub(crate) fn new() -> Self { Default::default() } pub(crate) fn insert(&mut self, key: K, mut value: V) -> Option { for (index, existing) in self.keys.iter().enumerate() { if *existing == key { std::mem::swap(&mut self.values[index], &mut value); return Some(value); } } self.insert_unchecked(key, value); None } pub(crate) fn insert_unchecked(&mut self, key: K, value: V) { self.keys.push(key); self.values.push(value); } pub(crate) fn extend_unchecked(&mut self, iter: impl IntoIterator) { for (key, value) in iter { self.insert_unchecked(key, value); } } pub fn contains_key(&self, key: &Q) -> bool where K: Borrow, Q: Eq, { for existing in &self.keys { if existing.borrow() == key { return true; } } false } pub fn remove(&mut self, key: &Q) -> Option where K: Borrow, Q: std::hash::Hash + Eq, { self.remove_entry(key).map(|(_, v)| v) } pub fn remove_entry(&mut self, key: &Q) -> Option<(K, V)> where K: Borrow, Q: std::hash::Hash + Eq, { let index = some!(self .keys .iter() .enumerate() .find_map(|(i, k)| (k.borrow() == key).then_some(i))); let key = self.keys.remove(index); let value = self.values.remove(index); Some((key, value)) } pub(crate) fn is_empty(&self) -> bool { self.keys.is_empty() } pub fn entry(&mut self, key: K) -> Entry { for (index, existing) in self.keys.iter().enumerate() { if *existing == key { return Entry::Occupied(OccupiedEntry { v: self, index }); } } Entry::Vacant(VacantEntry { v: self, key }) } pub fn get(&self, k: &Q) -> Option<&V> where K: Borrow, Q: Eq, { for (index, existing) in self.keys.iter().enumerate() { if existing.borrow() == k { return Some(&self.values[index]); } } None } pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> where K: Borrow, Q: Eq, { for (index, existing) in self.keys.iter().enumerate() { if existing.borrow() == k { return Some(&mut self.values[index]); } } None } pub fn keys(&self) -> std::slice::Iter<'_, K> { self.keys.iter() } pub fn iter(&self) -> Iter { Iter { keys: self.keys.iter(), values: self.values.iter(), } } pub fn iter_mut(&mut self) -> IterMut { IterMut { keys: self.keys.iter_mut(), values: self.values.iter_mut(), } } } impl Default for FlatMap { fn default() -> Self { Self { keys: Default::default(), values: Default::default(), } } } pub enum Entry<'a, K: 'a, V: 'a> { Vacant(VacantEntry<'a, K, V>), Occupied(OccupiedEntry<'a, K, V>), } impl<'a, K: 'a, V: 'a> Entry<'a, K, V> { pub fn or_insert(self, default: V) -> &'a mut V { match self { Entry::Occupied(entry) => &mut entry.v.values[entry.index], Entry::Vacant(entry) => { entry.v.keys.push(entry.key); entry.v.values.push(default); entry.v.values.last_mut().unwrap() } } } pub fn or_insert_with V>(self, default: F) -> &'a mut V { match self { Entry::Occupied(entry) => &mut entry.v.values[entry.index], Entry::Vacant(entry) => { entry.v.keys.push(entry.key); entry.v.values.push(default()); entry.v.values.last_mut().unwrap() } } } } pub struct VacantEntry<'a, K: 'a, V: 'a> { v: &'a mut FlatMap, key: K, } pub struct OccupiedEntry<'a, K: 'a, V: 'a> { v: &'a mut FlatMap, index: usize, } pub struct Iter<'a, K: 'a, V: 'a> { keys: std::slice::Iter<'a, K>, values: std::slice::Iter<'a, V>, } impl<'a, K, V> Iterator for Iter<'a, K, V> { type Item = (&'a K, &'a V); fn next(&mut self) -> Option<(&'a K, &'a V)> { match self.keys.next() { Some(k) => { let v = self.values.next().unwrap(); Some((k, v)) } None => None, } } fn size_hint(&self) -> (usize, Option) { self.keys.size_hint() } } impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> { fn next_back(&mut self) -> Option<(&'a K, &'a V)> { match self.keys.next_back() { Some(k) => { let v = self.values.next_back().unwrap(); Some((k, v)) } None => None, } } } impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {} pub struct IterMut<'a, K: 'a, V: 'a> { keys: std::slice::IterMut<'a, K>, values: std::slice::IterMut<'a, V>, } impl<'a, K, V> Iterator for IterMut<'a, K, V> { type Item = (&'a K, &'a mut V); fn next(&mut self) -> Option<(&'a K, &'a mut V)> { match self.keys.next() { Some(k) => { let v = self.values.next().unwrap(); Some((k, v)) } None => None, } } fn size_hint(&self) -> (usize, Option) { self.keys.size_hint() } } impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> { fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> { match self.keys.next_back() { Some(k) => { let v = self.values.next_back().unwrap(); Some((k, v)) } None => None, } } } impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {}