use core::alloc::{Layout, LayoutError};
use core::borrow::Borrow;
use core::fmt::Debug;
use core::iter::FusedIterator;
use core::marker::PhantomData;
use core::mem::MaybeUninit;
use crate::storage::{Capacity, LayoutSpec, Storage};
use self::Entry::{Occupied, Vacant};
pub struct ListMapLayout<K, V>(PhantomData<(K, V)>);
impl<K, V> LayoutSpec for ListMapLayout<K, V> {
fn layout_with_capacity(items: usize) -> Result<Layout, LayoutError> {
let keys_array = Layout::array::<K>(items)?;
let values_array = Layout::array::<V>(items)?;
let (extended, _) = keys_array.extend(values_array)?;
Ok(extended.pad_to_align())
}
}
pub struct ListMap<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> {
buf: S,
len: I,
pairs: PhantomData<(K, V)>,
}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> From<S> for ListMap<K, V, S, I> {
fn from(buf: S) -> Self {
ListMap { buf, len: I::from_usize(0), pairs: PhantomData }
}
}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> ListMap<K, V, S, I> {
#[inline]
pub fn capacity(&self) -> usize {
self.buf.capacity()
}
#[inline]
pub fn keys(&self) -> &[K] {
let ptr = self.buf.get_ptr().cast();
unsafe { core::slice::from_raw_parts(ptr, self.len.as_usize()) }
}
#[inline(always)]
fn values_offset(&self) -> usize {
let cap = self.capacity();
let keys_array = Layout::array::<K>(cap).unwrap();
let values_array = Layout::array::<V>(cap).unwrap();
let (_, offset) = keys_array.extend(values_array).unwrap();
offset
}
#[inline]
pub fn values(&self) -> &[V] {
unsafe {
let ptr = self.buf.get_ptr().add(self.values_offset()).cast();
core::slice::from_raw_parts(ptr, self.len())
}
}
#[inline]
pub fn values_mut(&mut self) -> &mut [V] {
unsafe {
let ptr = self.buf.get_mut_ptr().add(self.values_offset()).cast();
core::slice::from_raw_parts_mut(ptr, self.len())
}
}
pub fn iter(&self) -> Iter<'_, K, V, S, I> {
Iter { map: self, front: I::from_usize(0) }
}
pub fn iter_mut(&mut self) -> IterMut<'_, K, V, S, I> {
IterMut { map: self, front: I::from_usize(0) }
}
#[inline]
pub fn len(&self) -> usize {
self.len.as_usize()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len.as_usize() == 0
}
#[inline]
pub fn is_full(&self) -> bool {
self.len.as_usize() == self.buf.capacity()
}
pub fn drain(&mut self) -> Drain<'_, K, V, S, I> {
Drain { map: self }
}
pub fn drain_filter<F: FnMut(&K, &mut V) -> bool>(&mut self, pred: F) -> DrainFilter<'_, K, V, S, I, F> {
DrainFilter { map: self, should_remove: pred, front: I::from_usize(0) }
}
pub fn clear(&mut self) {
unsafe {
let keys = self.buf.get_mut_ptr().cast::<K>();
let values = self.buf.get_mut_ptr().add(self.values_offset()).cast::<V>();
for i in 0..self.len() {
keys.add(i).drop_in_place();
values.add(i).drop_in_place();
}
self.len = I::from_usize(0);
}
}
pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S, I>
where
K: Eq
{
self.try_entry(key).ok().expect("map is already at capacity")
}
pub fn try_entry(&mut self, key: K) -> Result<Entry<'_, K, V, S, I>, K>
where
K: Eq
{
if let Some((idx, _)) = self.lookup(&key) {
Ok(Occupied(OccupiedEntry { key, idx, map: self, }))
} else if self.is_full() {
Err(key)
} else {
Ok(Vacant(VacantEntry { key, map: self }))
}
}
#[inline(always)]
fn lookup<Q>(&self, key: &Q) -> Option<(usize, &K)>
where
K: Borrow<Q> + Eq,
Q: Eq + ?Sized,
{
self.keys().iter().enumerate().find(|(_, k)| (*k).borrow() == key)
}
pub fn get<Q>(&self, key: &Q) -> Option<&V>
where
K: Borrow<Q> + Eq,
Q: Eq + ?Sized,
{
let (idx, _) = self.lookup(key)?;
Some(&self.values()[idx])
}
pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
where
K: Borrow<Q> + Eq,
Q: Eq + ?Sized,
{
let (idx, k) = self.lookup(key)?;
Some((k, &self.values()[idx]))
}
pub fn contains_key<Q>(&self, key: &Q) -> bool
where
K: Borrow<Q> + Eq,
Q: Eq + ?Sized,
{
self.lookup(key).is_some()
}
pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
where
K: Borrow<Q> + Eq,
Q: Eq + ?Sized,
{
let (idx, _) = self.lookup(key)?;
Some(&mut self.values_mut()[idx])
}
#[inline]
#[track_caller]
pub fn insert(&mut self, key: K, value: V) -> Option<V> where K: Eq {
self.try_insert(key, value).ok().expect("map is already at capacity")
}
pub fn try_insert(&mut self, key: K, value: V) -> Result<Option<V>, (K, V)> where K: Eq {
if let Some((idx, _)) = self.lookup(&key) {
return Ok(Some(core::mem::replace(&mut self.values_mut()[idx], value)));
} else if self.is_full() {
return Err((key, value));
}
let idx = self.len();
unsafe {
let buf_ptr = self.buf.get_mut_ptr();
let key_ptr = buf_ptr.cast::<K>().add(idx);
key_ptr.write(key);
let value_ptr = buf_ptr.add(self.values_offset()).cast::<V>().add(idx);
value_ptr.write(value);
}
self.len = I::from_usize(idx + 1);
Ok(None)
}
pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
where
K: Borrow<Q> + Eq,
Q: Eq + ?Sized,
{
let (idx, _) = self.lookup(key)?;
let new_len = self.len() - 1;
unsafe {
let buf_ptr = self.buf.get_mut_ptr();
let keys = buf_ptr.cast::<K>();
keys.add(idx).drop_in_place();
let values = buf_ptr.add(self.values_offset()).cast::<V>();
let result = values.add(idx).read();
if idx != new_len {
core::ptr::copy_nonoverlapping(keys.add(new_len), keys.add(idx), 1);
core::ptr::copy_nonoverlapping(values.add(new_len), values.add(idx), 1);
}
self.len = I::from_usize(new_len);
Some(result)
}
}
pub fn remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
where
K: Borrow<Q> + Eq,
Q: Eq + ?Sized,
{
let (idx, _) = self.lookup(key)?;
let new_len = self.len() - 1;
unsafe {
let buf_ptr = self.buf.get_mut_ptr();
let keys = buf_ptr.cast::<K>();
let k = keys.add(idx).read();
let values = buf_ptr.add(self.values_offset()).cast::<V>();
let v = values.add(idx).read();
if idx != new_len {
core::ptr::copy_nonoverlapping(keys.add(new_len), keys.add(idx), 1);
core::ptr::copy_nonoverlapping(values.add(new_len), values.add(idx), 1);
}
self.len = I::from_usize(new_len);
Some((k, v))
}
}
pub fn retain<F: FnMut(&K, &mut V) -> bool>(&mut self, mut pred: F) {
self.drain_filter(|k, v| !(pred)(k, v)).for_each(drop);
}
pub fn into_keys(self) -> IntoKeys<K, V, S, I> {
IntoKeys { base: self.into_iter() }
}
pub fn into_values(self) -> IntoValues<K, V, S, I> {
IntoValues { base: self.into_iter() }
}
}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> Drop for ListMap<K, V, S, I> {
fn drop(&mut self) {
self.clear();
}
}
impl<K: Debug, V: Debug, S: Storage<ListMapLayout<K, V>>, I: Capacity> Debug for ListMap<K, V, S, I> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_map().entries(self.iter()).finish()
}
}
impl<Q, K, V, S, I> core::ops::Index<&'_ Q> for ListMap<K, V, S, I>
where
Q: Eq + ?Sized,
K: Eq + Borrow<Q>,
S: Storage<ListMapLayout<K, V>>,
I: Capacity,
{
type Output = V;
fn index(&self, key: &Q) -> &V {
self.get(key).expect("no entry found for key")
}
}
impl<K, V, S, I> Extend<(K, V)> for ListMap<K, V, S, I>
where
K: Eq,
S: Storage<ListMapLayout<K, V>>,
I: Capacity
{
fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
let iter = iter.into_iter();
iter.for_each(move |(k, v)| { self.insert(k, v); });
}
}
impl<'a, K, V, S, I> Extend<(&'a K, &'a V)> for ListMap<K, V, S, I>
where
K: Clone + Eq,
V: Clone,
S: Storage<ListMapLayout<K, V>>,
I: Capacity
{
fn extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) {
let iter = iter.into_iter();
iter.for_each(|(k, v)| {
self.insert(k.clone(), v.clone());
});
}
}
impl<K, V, S1, I1, S2, I2> PartialEq<ListMap<K, V, S2, I2>> for ListMap<K, V, S1, I1>
where
K: Eq,
V: PartialEq,
S1: Storage<ListMapLayout<K, V>>,
S2: Storage<ListMapLayout<K, V>>,
I1: Capacity,
I2: Capacity,
{
fn eq(&self, other: &ListMap<K, V, S2, I2>) -> bool {
if self.len() != other.len() {
return false;
}
self.iter().all(|(key, value)| other.get(key).map_or(false, |v| *value == *v))
}
}
impl<K: Eq, V: Eq, S: Storage<ListMapLayout<K, V>>, I: Capacity> Eq for ListMap<K, V, S, I> {}
#[cfg(feature = "alloc")]
#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
impl<K, V, I: Capacity> crate::collections::AllocListMap<K, V, I> {
pub fn with_capacity(capacity: usize) -> Self {
Self::from(crate::storage::AllocStorage::with_capacity(capacity))
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
impl<K: Clone, V: Clone, I: Capacity> Clone for crate::collections::AllocListMap<K, V, I> {
fn clone(&self) -> Self {
let buf = crate::storage::AllocStorage::with_capacity(self.capacity());
let mut result = ListMap {
buf, len: self.len, pairs: PhantomData
};
unsafe {
let base_ptr = result.buf.get_mut_ptr();
let keys_ptr = base_ptr.cast::<K>();
let values_ptr = base_ptr.add(result.values_offset()).cast::<V>();
for (idx, (k, v)) in self.iter().enumerate() {
keys_ptr.add(idx).write(k.clone());
values_ptr.add(idx).write(v.clone());
}
}
result
}
}
#[repr(C)]
pub struct InlineStorage<K, V, const N: usize> {
keys: [MaybeUninit<K>; N],
values: [MaybeUninit<V>; N],
}
unsafe impl<K, V, const N: usize> Storage<ListMapLayout<K, V>> for InlineStorage<K, V, N> {
fn get_ptr(&self) -> *const u8 {
(self as *const Self).cast()
}
fn get_mut_ptr(&mut self) -> *mut u8 {
(self as *mut Self).cast()
}
fn capacity(&self) -> usize {
N
}
}
impl<K, V, I: Capacity, const N: usize> ListMap<K, V, InlineStorage<K, V, N>, I> {
pub fn new() -> Self {
let buf = unsafe { InlineStorage {
keys: MaybeUninit::uninit().assume_init(),
values: MaybeUninit::uninit().assume_init(),
}};
Self::from(buf)
}
}
impl<K, V, I: Capacity, const N: usize> Default for ListMap<K, V, InlineStorage<K, V, N>, I> {
fn default() -> Self {
Self::new()
}
}
impl<K: Clone, V: Clone, I: Capacity, const N: usize> Clone for ListMap<K, V, InlineStorage<K, V, N>, I> {
fn clone(&self) -> Self {
let buf = unsafe { InlineStorage {
keys: MaybeUninit::uninit().assume_init(),
values: MaybeUninit::uninit().assume_init(),
}};
let mut result = ListMap {
buf, len: self.len, pairs: PhantomData,
};
unsafe {
let base_ptr = result.buf.get_mut_ptr();
let keys_ptr = base_ptr.cast::<K>();
let values_ptr = base_ptr.add(result.values_offset()).cast::<V>();
for (idx, (k, v)) in self.iter().enumerate() {
keys_ptr.add(idx).write(k.clone());
values_ptr.add(idx).write(v.clone());
}
}
result
}
}
pub struct OccupiedEntry<'a, K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> {
key: K,
idx: usize,
map: &'a mut ListMap<K, V, S, I>,
}
impl<'a, K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> OccupiedEntry<'a, K, V, S, I> {
pub fn key(&self) -> &K {
&self.key
}
pub fn remove_entry(self) -> (K, V) {
unsafe {
let base_ptr = self.map.buf.get_mut_ptr();
let keys_ptr = base_ptr.cast::<K>();
let k = keys_ptr.add(self.idx).read();
let values_ptr = base_ptr.add(self.map.values_offset()).cast::<V>();
let v = values_ptr.add(self.idx).read();
let new_len = self.map.len() - 1;
if self.idx != new_len {
core::ptr::copy_nonoverlapping(keys_ptr.add(new_len), keys_ptr.add(self.idx), 1);
core::ptr::copy_nonoverlapping(values_ptr.add(new_len), values_ptr.add(self.idx), 1);
}
self.map.len = I::from_usize(new_len);
(k , v)
}
}
pub fn get(&self) -> &V {
unsafe {
let base_ptr = self.map.buf.get_ptr();
let values_ptr = base_ptr.add(self.map.values_offset()).cast::<V>();
&*values_ptr.add(self.idx)
}
}
pub fn get_mut(&mut self) -> &mut V {
unsafe {
let base_ptr = self.map.buf.get_mut_ptr();
let values_ptr = base_ptr.add(self.map.values_offset()).cast::<V>();
&mut *values_ptr.add(self.idx)
}
}
pub fn into_mut(self) -> &'a mut V {
unsafe {
let base_ptr = self.map.buf.get_mut_ptr();
let values_ptr = base_ptr.add(self.map.values_offset()).cast::<V>();
&mut *values_ptr.add(self.idx)
}
}
pub fn insert(&mut self, value: V) -> V {
unsafe {
let base_ptr = self.map.buf.get_mut_ptr();
let values_ptr = base_ptr.add(self.map.values_offset()).cast::<V>();
values_ptr.add(self.idx).replace(value)
}
}
pub fn remove(self) -> V {
unsafe {
let base_ptr = self.map.buf.get_mut_ptr();
let values_ptr = base_ptr.add(self.map.values_offset()).cast::<V>();
let value = values_ptr.add(self.idx).read();
let new_len = self.map.len() - 1;
if self.idx != new_len {
let keys_ptr = base_ptr.cast::<K>();
core::ptr::copy_nonoverlapping(keys_ptr.add(new_len), keys_ptr.add(self.idx), 1);
core::ptr::copy_nonoverlapping(values_ptr.add(new_len), values_ptr.add(self.idx), 1);
}
self.map.len = I::from_usize(new_len);
value
}
}
pub fn replace_entry(self, value: V) -> (K, V) {
unsafe {
let base_ptr = self.map.buf.get_mut_ptr();
let keys_ptr = base_ptr.cast::<K>();
let k = keys_ptr.add(self.idx).replace(self.key);
let values_ptr = base_ptr.add(self.map.values_offset()).cast::<V>();
let v = values_ptr.add(self.idx).replace(value);
(k, v)
}
}
pub fn replace_key(self) -> K {
unsafe {
let keys_ptr = self.map.buf.get_mut_ptr().cast::<K>();
keys_ptr.add(self.idx).replace(self.key)
}
}
}
impl<K: Debug, V: Debug, S: Storage<ListMapLayout<K, V>>, I: Capacity> Debug for OccupiedEntry<'_, K, V, S, I> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("OccupiedEntry")
.field("key", &self.key)
.field("value", self.get())
.finish()
}
}
pub struct VacantEntry<'a, K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> {
key: K,
map: &'a mut ListMap<K, V, S, I>,
}
impl<'a, K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> VacantEntry<'a, K, V, S, I> {
pub fn key(&self) -> &K {
&self.key
}
pub fn into_key(self) -> K {
self.key
}
pub fn insert(self, value: V) -> &'a mut V {
unsafe {
let len = self.map.len();
let base_ptr = self.map.buf.get_mut_ptr();
let keys_ptr = base_ptr.cast::<K>();
keys_ptr.add(len).write(self.key);
let values_ptr = base_ptr.add(self.map.values_offset()).cast::<V>();
let v_ptr = values_ptr.add(len);
v_ptr.write(value);
self.map.len = I::from_usize(len + 1);
&mut *v_ptr
}
}
}
impl<K: Debug, V: Debug, S: Storage<ListMapLayout<K, V>>, I: Capacity> Debug for VacantEntry<'_, K, V, S, I> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("VacantEntry").field(&self.key).finish()
}
}
pub enum Entry<'a, K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> {
Occupied(OccupiedEntry<'a, K, V, S, I>),
Vacant(VacantEntry<'a, K, V, S, I>),
}
impl<'a, K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> Entry<'a, K, V, S, I> {
pub fn or_insert(self, default: V) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(default),
}
}
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(default()),
}
}
pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => {
let value = default(entry.key());
entry.insert(value)
}
}
}
pub fn key(&self) -> &K {
match *self {
Occupied(ref entry) => entry.key(),
Vacant(ref entry) => entry.key(),
}
}
#[must_use]
pub fn and_modify<F: FnOnce(&mut V)>(self, f: F) -> Self {
match self {
Occupied(mut entry) => {
f(entry.get_mut());
Occupied(entry)
},
Vacant(entry) => Vacant(entry),
}
}
}
impl<'a, K, V: Default, S: Storage<ListMapLayout<K, V>>, I: Capacity> Entry<'a, K, V, S, I> {
pub fn or_default(self) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(V::default())
}
}
}
impl<K: Debug, V: Debug, S: Storage<ListMapLayout<K, V>>, I: Capacity> Debug for Entry<'_, K, V, S, I> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match *self {
Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
}
}
}
pub struct Iter<'a, K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> {
map: &'a ListMap<K, V, S, I>,
front: I,
}
impl<'a, K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> Iterator for Iter<'a, K, V, S, I> {
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
let front = self.front.as_usize();
if front >= self.map.len() { return None; }
let k = &self.map.keys()[front];
let v = &self.map.values()[front];
self.front = I::from_usize(front + 1);
Some((k, v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
let front = self.front.as_usize();
let len = self.map.len() - front;
(len, Some(len))
}
}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> ExactSizeIterator for Iter<'_, K, V, S, I> {}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> FusedIterator for Iter<'_, K, V, S, I> {}
impl<'a, K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> IntoIterator for &'a ListMap<K, V, S, I> {
type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V, S, I>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub struct IterMut<'a, K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> {
map: &'a mut ListMap<K, V, S, I>,
front: I,
}
impl<'a, K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> Iterator for IterMut<'a, K, V, S, I> {
type Item = (&'a K, &'a mut V);
fn next(&mut self) -> Option<Self::Item> {
let front = self.front.as_usize();
if front >= self.map.len() { return None; }
let (k, v) = unsafe {
let base_ptr = self.map.buf.get_mut_ptr();
let keys_ptr = base_ptr.cast::<K>();
let k = keys_ptr.add(front).as_ref().unwrap();
let values_ptr = base_ptr.add(self.map.values_offset()).cast::<V>();
let v = values_ptr.add(front).as_mut().unwrap();
(k, v)
};
self.front = I::from_usize(front + 1);
Some((k, v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
let front = self.front.as_usize();
let len = self.map.len() - front;
(len, Some(len))
}
}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> ExactSizeIterator for IterMut<'_, K, V, S, I> {}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> FusedIterator for IterMut<'_, K, V, S, I> {}
impl<'a, K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> IntoIterator for &'a mut ListMap<K, V, S, I> {
type Item = (&'a K, &'a mut V);
type IntoIter = IterMut<'a, K, V, S, I>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
pub struct IntoIter<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> {
map: ListMap<K, V, S, I>,
}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> Iterator for IntoIter<K, V, S, I> {
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
if self.map.is_empty() { return None; }
let new_len = self.map.len() - 1;
self.map.len = I::from_usize(new_len);
unsafe {
let base_ptr = self.map.buf.get_ptr();
let keys_ptr = base_ptr.cast::<K>();
let k = keys_ptr.add(new_len).read();
let values_ptr = base_ptr.add(self.map.values_offset()).cast::<V>();
let v = values_ptr.add(new_len).read();
Some((k, v))
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.map.len();
(len, Some(len))
}
}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> ExactSizeIterator for IntoIter<K, V, S, I> {}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> FusedIterator for IntoIter<K, V, S, I> {}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> IntoIterator for ListMap<K, V, S, I> {
type Item = (K, V);
type IntoIter = IntoIter<K, V, S, I>;
fn into_iter(self) -> Self::IntoIter {
IntoIter { map: self }
}
}
pub struct IntoKeys<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> {
base: IntoIter<K, V, S, I>,
}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> Iterator for IntoKeys<K, V, S, I> {
type Item = K;
fn next(&mut self) -> Option<Self::Item> {
self.base.next().map(|(k, _)| k)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.base.size_hint()
}
}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> ExactSizeIterator for IntoKeys<K, V, S, I> {}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> FusedIterator for IntoKeys<K, V, S, I> {}
pub struct IntoValues<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> {
base: IntoIter<K, V, S, I>,
}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> Iterator for IntoValues<K, V, S, I> {
type Item = V;
fn next(&mut self) -> Option<Self::Item> {
self.base.next().map(|(_, v)| v)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.base.size_hint()
}
}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> ExactSizeIterator for IntoValues<K, V, S, I> {}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> FusedIterator for IntoValues<K, V, S, I> {}
pub struct Drain<'a, K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> {
map: &'a mut ListMap<K, V, S, I>,
}
impl<'a, K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> Iterator for Drain<'a, K, V, S, I> {
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
let len = self.map.len();
if len == 0 { return None; }
let new_len = len - 1;
self.map.len = I::from_usize(new_len);
unsafe {
let base_ptr = self.map.buf.get_ptr();
let keys_ptr = base_ptr.cast::<K>();
let k = keys_ptr.add(new_len).read();
let values_ptr = base_ptr.add(self.map.values_offset()).cast::<V>();
let v = values_ptr.add(new_len).read();
Some((k, v))
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.map.len();
(len, Some(len))
}
}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> ExactSizeIterator for Drain<'_, K, V, S, I> {}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> FusedIterator for Drain<'_, K, V, S, I> {}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity> Drop for Drain<'_, K, V, S, I> {
fn drop(&mut self) {
self.for_each(drop);
}
}
pub struct DrainFilter<'a, K, V, S, I, F>
where
S: Storage<ListMapLayout<K, V>>,
I: Capacity,
F: FnMut(&K, &mut V) -> bool,
{
map: &'a mut ListMap<K, V, S, I>,
should_remove: F,
front: I,
}
impl<'a, K, V, S, I, F> Iterator for DrainFilter<'a, K, V, S, I, F>
where
S: Storage<ListMapLayout<K, V>>,
I: Capacity,
F: FnMut(&K, &mut V) -> bool
{
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
let mut front = self.front.as_usize();
while front < self.map.len() {
unsafe {
let base_ptr = self.map.buf.get_mut_ptr();
let keys_ptr = base_ptr.cast::<K>();
let values_ptr = base_ptr.add(self.map.values_offset()).cast::<V>();
let k = keys_ptr.add(front).as_ref().unwrap();
let v = values_ptr.add(front).as_mut().unwrap();
if (self.should_remove)(k, v) {
let new_len = self.map.len() - 1;
self.map.len = I::from_usize(new_len);
let k = keys_ptr.add(front).read();
let v = values_ptr.add(front).read();
if front < new_len {
core::ptr::copy_nonoverlapping(keys_ptr.add(new_len), keys_ptr.add(front), 1);
core::ptr::copy_nonoverlapping(values_ptr.add(new_len), values_ptr.add(front), 1);
}
self.front = I::from_usize(front);
return Some((k, v));
}
}
front += 1;
}
self.front = I::from_usize(front);
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
let max_len = self.map.len() - self.front.as_usize();
(0, Some(max_len))
}
}
impl<K, V, S: Storage<ListMapLayout<K, V>>, I: Capacity, F: FnMut(&K, &mut V) -> bool> FusedIterator for DrainFilter<'_, K, V, S, I, F> {}
impl<'a, K, V, S, I, F> Drop for DrainFilter<'a, K, V, S, I, F>
where
S: Storage<ListMapLayout<K, V>>,
I: Capacity,
F: FnMut(&K, &mut V) -> bool
{
fn drop(&mut self) {
self.for_each(drop);
}
}