#[cfg(feature = "alloc")]
use crate::config::DefaultMapConfig;
use crate::config::{KeyConfig, MapConfig, SecondaryMapConfig, SecondaryMapConfigFor};
use crate::error::{GetDisjointMutAtError, GetDisjointMutError, SecondaryInsertError};
use crate::key::Key;
use crate::key_piece::KeyPiece;
use crate::map::{decrement_len, increment_len, MapGen, MapIdx, MapKeyConfig};
use crate::parity::Odd;
use crate::replace_strategy::ReplaceStrategy;
use crate::slot::SecondarySlot;
use crate::storage::{ReserveStorage, SlotStorage};
use core::fmt;
use core::iter::{Enumerate, FusedIterator};
use core::ops::{Index, IndexMut};
use core::slice;
pub type SecondaryMapSlot<T, C> = SecondarySlot<MapKeyConfig<C>, T>;
type Slots<T, C> = <C as SecondaryMapConfig<SecondaryMapSlot<T, C>>>::Storage;
type Strategy<T, C> = <C as SecondaryMapConfig<SecondaryMapSlot<T, C>>>::ReplaceStrategy;
pub type SecondaryStorageError<T, C> = <Slots<T, C> as SlotStorage>::Error;
type InsertResult<T, C> = Result<Option<T>, SecondaryInsertError<T, SecondaryStorageError<T, C>>>;
#[inline]
unsafe fn key_from_parts_unchecked<C: MapConfig>(
position: usize,
generation: Odd<MapGen<C>>,
) -> Key<MapKeyConfig<C>> {
debug_assert!(
MapIdx::<C>::from_usize(position)
.and_then(|idx| <MapKeyConfig<C> as KeyConfig>::pack(idx, generation))
.is_some(),
"the index and the generation fit the key"
);
unsafe {
let idx = MapIdx::<C>::from_usize_unchecked(position);
Key::from_repr(<MapKeyConfig<C> as KeyConfig>::pack_unchecked(
idx, generation,
))
}
}
pub struct SecondaryMap<
T,
#[cfg(feature = "alloc")] C: SecondaryMapConfigFor<T> = DefaultMapConfig,
#[cfg(not(feature = "alloc"))] C: SecondaryMapConfigFor<T>,
> {
slots: Slots<T, C>,
len: MapIdx<C>,
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> SecondaryMap<T> {
#[inline]
#[must_use]
pub fn new() -> Self {
Self::new_with_config()
}
#[inline]
#[must_use]
pub fn with_capacity(capacity: usize) -> Self
where
Slots<T, DefaultMapConfig>: ReserveStorage,
{
Self {
slots: Slots::<T, DefaultMapConfig>::with_capacity(capacity),
len: MapIdx::<DefaultMapConfig>::ZERO,
}
}
}
impl<T, C: SecondaryMapConfigFor<T>> SecondaryMap<T, C> {
#[inline]
#[must_use]
pub fn new_with_config() -> Self {
Self {
slots: Slots::<T, C>::empty(),
len: MapIdx::<C>::ZERO,
}
}
#[inline]
pub fn capacity(&self) -> usize {
self.slots.capacity()
}
#[inline]
pub fn len(&self) -> usize {
unsafe { self.len.into_usize_unchecked() }
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len == MapIdx::<C>::ZERO
}
#[inline]
pub fn slots_len(&self) -> usize {
self.slots.len()
}
#[inline]
pub fn contains_key(&self, key: Key<MapKeyConfig<C>>) -> bool {
self.get(key).is_some()
}
#[inline]
pub fn get(&self, key: Key<MapKeyConfig<C>>) -> Option<&T> {
let position = key.idx().into_usize()?;
self.slots
.as_slice()
.get(position)?
.get_odd(key.generation())
}
#[inline]
pub fn get_mut(&mut self, key: Key<MapKeyConfig<C>>) -> Option<&mut T> {
let position = key.idx().into_usize()?;
self.slots
.as_mut_slice()
.get_mut(position)?
.get_odd_mut(key.generation())
}
#[inline]
pub unsafe fn get_unchecked(&self, key: Key<MapKeyConfig<C>>) -> &T {
debug_assert!(self.contains_key(key));
unsafe {
self.slots
.as_slice()
.get_unchecked(key.idx().into_usize_unchecked())
.get_odd_unchecked()
}
}
#[inline]
pub unsafe fn get_unchecked_mut(&mut self, key: Key<MapKeyConfig<C>>) -> &mut T {
debug_assert!(self.contains_key(key));
unsafe {
self.slots
.as_mut_slice()
.get_unchecked_mut(key.idx().into_usize_unchecked())
.get_odd_unchecked_mut()
}
}
#[inline]
pub fn key_at(&self, idx: MapIdx<C>) -> Option<Key<MapKeyConfig<C>>> {
let position = idx.into_usize()?;
let (generation, _) = self.slots.as_slice().get(position)?.get()?;
Some(unsafe { key_from_parts_unchecked::<C>(position, generation) })
}
#[inline]
pub unsafe fn key_at_unchecked(&self, idx: MapIdx<C>) -> Key<MapKeyConfig<C>> {
debug_assert!(self.key_at(idx).is_some());
unsafe {
let position = idx.into_usize_unchecked();
let slot = self.slots.as_slice().get_unchecked(position);
key_from_parts_unchecked::<C>(position, Odd::new_unchecked(slot.generation()))
}
}
#[inline]
pub fn get_at(&self, idx: MapIdx<C>) -> Option<(Key<MapKeyConfig<C>>, &T)> {
let position = idx.into_usize()?;
let (generation, value) = self.slots.as_slice().get(position)?.get()?;
let key = unsafe { key_from_parts_unchecked::<C>(position, generation) };
Some((key, value))
}
#[inline]
pub fn get_at_mut(&mut self, idx: MapIdx<C>) -> Option<(Key<MapKeyConfig<C>>, &mut T)> {
let position = idx.into_usize()?;
let (generation, value) = self.slots.as_mut_slice().get_mut(position)?.get_mut()?;
let key = unsafe { key_from_parts_unchecked::<C>(position, generation) };
Some((key, value))
}
#[inline]
pub unsafe fn get_at_unchecked(&self, idx: MapIdx<C>) -> (Key<MapKeyConfig<C>>, &T) {
debug_assert!(self.key_at(idx).is_some());
unsafe {
let position = idx.into_usize_unchecked();
let slot = self.slots.as_slice().get_unchecked(position);
let generation = Odd::new_unchecked(slot.generation());
let key = key_from_parts_unchecked::<C>(position, generation);
(key, slot.get_odd_unchecked())
}
}
#[inline]
pub unsafe fn get_at_unchecked_mut(
&mut self,
idx: MapIdx<C>,
) -> (Key<MapKeyConfig<C>>, &mut T) {
debug_assert!(self.key_at(idx).is_some());
unsafe {
let position = idx.into_usize_unchecked();
let slot = self.slots.as_mut_slice().get_unchecked_mut(position);
let generation = Odd::new_unchecked(slot.generation());
let key = key_from_parts_unchecked::<C>(position, generation);
(key, slot.get_odd_unchecked_mut())
}
}
#[inline]
pub fn generation_at(&self, idx: MapIdx<C>) -> Option<MapGen<C>> {
Some(self.slots.as_slice().get(idx.into_usize()?)?.generation())
}
#[inline]
pub unsafe fn generation_at_unchecked(&self, idx: MapIdx<C>) -> MapGen<C> {
debug_assert!(self.generation_at(idx).is_some());
unsafe {
self.slots
.as_slice()
.get_unchecked(idx.into_usize_unchecked())
.generation()
}
}
#[inline]
#[allow(clippy::type_complexity)]
pub fn get_disjoint_mut_at<const N: usize>(
&mut self,
idxs: [MapIdx<C>; N],
) -> Result<[(Key<MapKeyConfig<C>>, &mut T); N], GetDisjointMutAtError> {
for (i, idx) in idxs.iter().enumerate() {
if self.key_at(*idx).is_none() {
return Err(GetDisjointMutAtError::NoValue);
}
if idxs[..i].contains(idx) {
return Err(GetDisjointMutAtError::OverlappingIndices);
}
}
Ok(unsafe { self.get_disjoint_mut_at_unchecked(idxs) })
}
#[inline]
pub unsafe fn get_disjoint_mut_at_unchecked<const N: usize>(
&mut self,
idxs: [MapIdx<C>; N],
) -> [(Key<MapKeyConfig<C>>, &mut T); N] {
debug_assert!(idxs.iter().all(|idx| self.key_at(*idx).is_some()));
debug_assert!(idxs
.iter()
.enumerate()
.all(|(i, idx)| !idxs[..i].contains(idx)));
let slots = self.slots.as_mut_slice().as_mut_ptr();
idxs.map(|idx| {
unsafe {
let position = idx.into_usize_unchecked();
let slot = &mut *slots.add(position);
let generation = Odd::new_unchecked(slot.generation());
let key = key_from_parts_unchecked::<C>(position, generation);
(key, slot.get_odd_unchecked_mut())
}
})
}
#[inline]
pub fn get_disjoint_mut<const N: usize>(
&mut self,
keys: [Key<MapKeyConfig<C>>; N],
) -> Result<[&mut T; N], GetDisjointMutError> {
for (i, key) in keys.iter().enumerate() {
if !self.contains_key(*key) {
return Err(GetDisjointMutError::InvalidKey);
}
if keys[..i].iter().any(|earlier| earlier.idx() == key.idx()) {
return Err(GetDisjointMutError::OverlappingKeys);
}
}
Ok(unsafe { self.get_disjoint_mut_unchecked(keys) })
}
#[inline]
pub unsafe fn get_disjoint_mut_unchecked<const N: usize>(
&mut self,
keys: [Key<MapKeyConfig<C>>; N],
) -> [&mut T; N] {
debug_assert!(keys.iter().all(|key| self.contains_key(*key)));
debug_assert!(keys
.iter()
.enumerate()
.all(|(i, key)| keys[..i].iter().all(|earlier| earlier.idx() != key.idx())));
let slots = self.slots.as_mut_slice().as_mut_ptr();
keys.map(|key| {
unsafe { (*slots.add(key.idx().into_usize_unchecked())).get_odd_unchecked_mut() }
})
}
pub fn insert(&mut self, key: Key<MapKeyConfig<C>>, value: T) -> InsertResult<T, C> {
if key.idx() == MapIdx::<C>::MAX {
return Err(SecondaryInsertError::IndexReserved(value));
}
let generation = key.generation();
let slot = match Self::get_or_grow_slot(&mut self.slots, key.idx()) {
Ok(slot) => slot,
Err(error) => return Err(SecondaryInsertError::StorageFull(value, error)),
};
if let Some(old) = slot.get_odd_mut(generation) {
return Ok(Some(core::mem::replace(old, value)));
}
match slot.get().map(|(current, _)| current) {
None => {
slot.replace(generation, value);
increment_len(&mut self.len);
Ok(None)
}
Some(current)
if <Strategy<T, C> as ReplaceStrategy<MapKeyConfig<C>>>::replaces(
current, generation,
) =>
{
Ok(slot.replace(generation, value))
}
Some(_) => Err(SecondaryInsertError::Refused(value)),
}
}
fn get_or_grow_slot(
slots: &mut Slots<T, C>,
idx: MapIdx<C>,
) -> Result<&mut SecondaryMapSlot<T, C>, SecondaryStorageError<T, C>> {
let Some(position) = idx.into_usize() else {
return Err(slots
.ensure_room(usize::MAX)
.expect_err("no storage has room for `usize::MAX` more slots"));
};
let len = slots.len();
if position >= len {
slots.ensure_room((position - len).saturating_add(1))?;
for _ in len..=position {
if slots.try_push(SecondarySlot::empty()).is_err() {
panic!("SlotStorage::try_push failed although ensure_room returned Ok");
}
}
}
debug_assert!(position < slots.len());
Ok(unsafe { slots.as_mut_slice().get_unchecked_mut(position) })
}
#[inline]
pub fn remove(&mut self, key: Key<MapKeyConfig<C>>) -> Option<T> {
let position = key.idx().into_usize()?;
let slot = self.slots.as_mut_slice().get_mut(position)?;
slot.get_odd(key.generation())?;
let value = slot.take()?;
decrement_len(&mut self.len);
Some(value)
}
pub fn retain<F: FnMut(Key<MapKeyConfig<C>>, &mut T) -> bool>(&mut self, mut f: F) {
for (position, slot) in self.slots.as_mut_slice().iter_mut().enumerate() {
if let Some((generation, value)) = slot.get_mut() {
let key = unsafe { key_from_parts_unchecked::<C>(position, generation) };
if !f(key, value) {
decrement_len(&mut self.len);
drop(slot.take());
}
}
}
}
pub fn clear(&mut self) {
for slot in self.slots.as_mut_slice() {
if slot.get().is_some() {
decrement_len(&mut self.len);
drop(slot.take());
}
}
}
#[inline]
pub fn iter(&self) -> SecondaryIter<'_, T, C> {
let remaining = self.len();
SecondaryIter {
slots: self.slots.as_slice().iter().enumerate(),
remaining,
}
}
#[inline]
pub fn keys(&self) -> SecondaryKeys<'_, T, C> {
SecondaryKeys { inner: self.iter() }
}
#[inline]
pub fn values(&self) -> SecondaryValues<'_, T, C> {
SecondaryValues { inner: self.iter() }
}
#[inline]
pub fn iter_mut(&mut self) -> SecondaryIterMut<'_, T, C> {
let remaining = self.len();
SecondaryIterMut {
slots: self.slots.as_mut_slice().iter_mut().enumerate(),
remaining,
}
}
#[inline]
pub fn values_mut(&mut self) -> SecondaryValuesMut<'_, T, C> {
SecondaryValuesMut {
inner: self.iter_mut(),
}
}
#[inline]
pub fn drain(&mut self) -> SecondaryDrain<'_, T, C> {
SecondaryDrain {
map: self,
position: 0,
}
}
}
impl<T, C: SecondaryMapConfigFor<T>> SecondaryMap<T, C>
where
Slots<T, C>: ReserveStorage,
{
#[inline]
#[must_use]
pub fn with_capacity_and_config(capacity: usize) -> Self {
Self {
slots: Slots::<T, C>::with_capacity(capacity),
len: MapIdx::<C>::ZERO,
}
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.slots.reserve(additional);
}
#[inline]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), SecondaryStorageError<T, C>> {
self.slots.try_reserve(additional)
}
}
impl<T, C: SecondaryMapConfigFor<T>> Default for SecondaryMap<T, C> {
#[inline]
fn default() -> Self {
Self::new_with_config()
}
}
impl<T: Clone, C: SecondaryMapConfigFor<T>> Clone for SecondaryMap<T, C> {
fn clone(&self) -> Self {
let mut slots = Slots::<T, C>::with_capacity(self.slots.len());
for slot in self.slots.as_slice() {
if slots.try_push(slot.clone()).is_err() {
panic!("SlotStorage::try_push failed while cloning a storage of the same type");
}
}
Self {
slots,
len: self.len,
}
}
}
impl<T: fmt::Debug, C: SecondaryMapConfigFor<T>> fmt::Debug for SecondaryMap<T, C> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_map().entries(self.iter()).finish()
}
}
impl<T, C: SecondaryMapConfigFor<T>> Index<Key<MapKeyConfig<C>>> for SecondaryMap<T, C> {
type Output = T;
#[inline]
fn index(&self, key: Key<MapKeyConfig<C>>) -> &T {
self.get(key).expect("invalid SecondaryMap key")
}
}
impl<T, C: SecondaryMapConfigFor<T>> IndexMut<Key<MapKeyConfig<C>>> for SecondaryMap<T, C> {
#[inline]
fn index_mut(&mut self, key: Key<MapKeyConfig<C>>) -> &mut T {
self.get_mut(key).expect("invalid SecondaryMap key")
}
}
pub struct SecondaryIter<'a, T: 'a, C: SecondaryMapConfigFor<T> + 'a> {
slots: Enumerate<slice::Iter<'a, SecondaryMapSlot<T, C>>>,
remaining: usize,
}
impl<'a, T, C: SecondaryMapConfigFor<T>> Iterator for SecondaryIter<'a, T, C> {
type Item = (Key<MapKeyConfig<C>>, &'a T);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
for (position, slot) in self.slots.by_ref() {
if let Some((generation, value)) = slot.get() {
self.remaining -= 1;
let key = unsafe { key_from_parts_unchecked::<C>(position, generation) };
return Some((key, value));
}
}
None
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.remaining, Some(self.remaining))
}
}
impl<T, C: SecondaryMapConfigFor<T>> DoubleEndedIterator for SecondaryIter<'_, T, C> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
while let Some((position, slot)) = self.slots.next_back() {
if let Some((generation, value)) = slot.get() {
self.remaining -= 1;
let key = unsafe { key_from_parts_unchecked::<C>(position, generation) };
return Some((key, value));
}
}
None
}
}
impl<T, C: SecondaryMapConfigFor<T>> ExactSizeIterator for SecondaryIter<'_, T, C> {}
impl<T, C: SecondaryMapConfigFor<T>> FusedIterator for SecondaryIter<'_, T, C> {}
impl<T, C: SecondaryMapConfigFor<T>> Clone for SecondaryIter<'_, T, C> {
#[inline]
fn clone(&self) -> Self {
Self {
slots: self.slots.clone(),
remaining: self.remaining,
}
}
}
pub struct SecondaryIterMut<'a, T: 'a, C: SecondaryMapConfigFor<T> + 'a> {
slots: Enumerate<slice::IterMut<'a, SecondaryMapSlot<T, C>>>,
remaining: usize,
}
impl<'a, T, C: SecondaryMapConfigFor<T>> Iterator for SecondaryIterMut<'a, T, C> {
type Item = (Key<MapKeyConfig<C>>, &'a mut T);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
for (position, slot) in self.slots.by_ref() {
if let Some((generation, value)) = slot.get_mut() {
self.remaining -= 1;
let key = unsafe { key_from_parts_unchecked::<C>(position, generation) };
return Some((key, value));
}
}
None
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.remaining, Some(self.remaining))
}
}
impl<T, C: SecondaryMapConfigFor<T>> DoubleEndedIterator for SecondaryIterMut<'_, T, C> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
while let Some((position, slot)) = self.slots.next_back() {
if let Some((generation, value)) = slot.get_mut() {
self.remaining -= 1;
let key = unsafe { key_from_parts_unchecked::<C>(position, generation) };
return Some((key, value));
}
}
None
}
}
impl<T, C: SecondaryMapConfigFor<T>> ExactSizeIterator for SecondaryIterMut<'_, T, C> {}
impl<T, C: SecondaryMapConfigFor<T>> FusedIterator for SecondaryIterMut<'_, T, C> {}
pub struct SecondaryKeys<'a, T: 'a, C: SecondaryMapConfigFor<T> + 'a> {
inner: SecondaryIter<'a, T, C>,
}
impl<T, C: SecondaryMapConfigFor<T>> Iterator for SecondaryKeys<'_, T, C> {
type Item = Key<MapKeyConfig<C>>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(key, _)| key)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<T, C: SecondaryMapConfigFor<T>> DoubleEndedIterator for SecondaryKeys<'_, T, C> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|(key, _)| key)
}
}
impl<T, C: SecondaryMapConfigFor<T>> ExactSizeIterator for SecondaryKeys<'_, T, C> {}
impl<T, C: SecondaryMapConfigFor<T>> FusedIterator for SecondaryKeys<'_, T, C> {}
impl<T, C: SecondaryMapConfigFor<T>> Clone for SecondaryKeys<'_, T, C> {
#[inline]
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
pub struct SecondaryValues<'a, T: 'a, C: SecondaryMapConfigFor<T> + 'a> {
inner: SecondaryIter<'a, T, C>,
}
impl<'a, T, C: SecondaryMapConfigFor<T>> Iterator for SecondaryValues<'a, T, C> {
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(_, value)| value)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<T, C: SecondaryMapConfigFor<T>> DoubleEndedIterator for SecondaryValues<'_, T, C> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|(_, value)| value)
}
}
impl<T, C: SecondaryMapConfigFor<T>> ExactSizeIterator for SecondaryValues<'_, T, C> {}
impl<T, C: SecondaryMapConfigFor<T>> FusedIterator for SecondaryValues<'_, T, C> {}
impl<T, C: SecondaryMapConfigFor<T>> Clone for SecondaryValues<'_, T, C> {
#[inline]
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
pub struct SecondaryValuesMut<'a, T: 'a, C: SecondaryMapConfigFor<T> + 'a> {
inner: SecondaryIterMut<'a, T, C>,
}
impl<'a, T, C: SecondaryMapConfigFor<T>> Iterator for SecondaryValuesMut<'a, T, C> {
type Item = &'a mut T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(_, value)| value)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<T, C: SecondaryMapConfigFor<T>> DoubleEndedIterator for SecondaryValuesMut<'_, T, C> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|(_, value)| value)
}
}
impl<T, C: SecondaryMapConfigFor<T>> ExactSizeIterator for SecondaryValuesMut<'_, T, C> {}
impl<T, C: SecondaryMapConfigFor<T>> FusedIterator for SecondaryValuesMut<'_, T, C> {}
pub struct SecondaryDrain<'a, T: 'a, C: SecondaryMapConfigFor<T> + 'a> {
map: &'a mut SecondaryMap<T, C>,
position: usize,
}
impl<T, C: SecondaryMapConfigFor<T>> Iterator for SecondaryDrain<'_, T, C> {
type Item = (Key<MapKeyConfig<C>>, T);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
while let Some(slot) = self.map.slots.as_mut_slice().get_mut(self.position) {
let position = self.position;
self.position += 1;
if let Some((generation, value)) =
core::mem::replace(slot, SecondarySlot::empty()).into_inner()
{
decrement_len(&mut self.map.len);
let key = unsafe { key_from_parts_unchecked::<C>(position, generation) };
return Some((key, value));
}
}
None
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.map.len();
(len, Some(len))
}
}
impl<T, C: SecondaryMapConfigFor<T>> ExactSizeIterator for SecondaryDrain<'_, T, C> {}
impl<T, C: SecondaryMapConfigFor<T>> FusedIterator for SecondaryDrain<'_, T, C> {}
impl<T, C: SecondaryMapConfigFor<T>> Drop for SecondaryDrain<'_, T, C> {
fn drop(&mut self) {
for _ in self.by_ref() {}
}
}
pub struct SecondaryIntoIter<T, C: SecondaryMapConfigFor<T>>
where
Slots<T, C>: IntoIterator<Item = SecondaryMapSlot<T, C>>,
{
slots: Enumerate<<Slots<T, C> as IntoIterator>::IntoIter>,
remaining: usize,
}
impl<T, C: SecondaryMapConfigFor<T>> Iterator for SecondaryIntoIter<T, C>
where
Slots<T, C>: IntoIterator<Item = SecondaryMapSlot<T, C>>,
{
type Item = (Key<MapKeyConfig<C>>, T);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
for (position, slot) in self.slots.by_ref() {
if let Some((generation, value)) = slot.into_inner() {
self.remaining -= 1;
let key = unsafe { key_from_parts_unchecked::<C>(position, generation) };
return Some((key, value));
}
}
None
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.remaining, Some(self.remaining))
}
}
impl<T, C: SecondaryMapConfigFor<T>> DoubleEndedIterator for SecondaryIntoIter<T, C>
where
Slots<T, C>: IntoIterator<Item = SecondaryMapSlot<T, C>>,
<Slots<T, C> as IntoIterator>::IntoIter: DoubleEndedIterator + ExactSizeIterator,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
while let Some((position, slot)) = self.slots.next_back() {
if let Some((generation, value)) = slot.into_inner() {
self.remaining -= 1;
let key = unsafe { key_from_parts_unchecked::<C>(position, generation) };
return Some((key, value));
}
}
None
}
}
impl<T, C: SecondaryMapConfigFor<T>> ExactSizeIterator for SecondaryIntoIter<T, C> where
Slots<T, C>: IntoIterator<Item = SecondaryMapSlot<T, C>>
{
}
impl<T, C: SecondaryMapConfigFor<T>> FusedIterator for SecondaryIntoIter<T, C> where
Slots<T, C>: IntoIterator<Item = SecondaryMapSlot<T, C>>
{
}
impl<T, C: SecondaryMapConfigFor<T>> IntoIterator for SecondaryMap<T, C>
where
Slots<T, C>: IntoIterator<Item = SecondaryMapSlot<T, C>>,
{
type Item = (Key<MapKeyConfig<C>>, T);
type IntoIter = SecondaryIntoIter<T, C>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
SecondaryIntoIter {
remaining: self.len(),
slots: self.slots.into_iter().enumerate(),
}
}
}
impl<'a, T, C: SecondaryMapConfigFor<T>> IntoIterator for &'a SecondaryMap<T, C> {
type Item = (Key<MapKeyConfig<C>>, &'a T);
type IntoIter = SecondaryIter<'a, T, C>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T, C: SecondaryMapConfigFor<T>> IntoIterator for &'a mut SecondaryMap<T, C> {
type Item = (Key<MapKeyConfig<C>>, &'a mut T);
type IntoIter = SecondaryIterMut<'a, T, C>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}