use bitmaps::{Bitmap, Bits, Iter as BitmapIter};
use super::SparseChunk;
use crate::types::ChunkLength;
/// An iterator over references to the elements of a `SparseChunk`.
pub struct Iter<'a, A, N: Bits + ChunkLength> {
pub(crate) indices: BitmapIter<'a, N>,
pub(crate) chunk: &'a SparseChunk,
}
impl<'a, A, N: Bits + ChunkLength> Iterator for Iter<'a, A, N> {
type Item = &'a A;
fn next(&mut self) -> Option {
self.indices.next().map(|index| &self.chunk.values()[index])
}
fn size_hint(&self) -> (usize, Option) {
(0, Some(SparseChunk::::CAPACITY))
}
}
/// An iterator over mutable references to the elements of a `SparseChunk`.
pub struct IterMut<'a, A, N: Bits + ChunkLength> {
pub(crate) bitmap: Bitmap,
pub(crate) chunk: &'a mut SparseChunk,
}
impl<'a, A, N: Bits + ChunkLength> Iterator for IterMut<'a, A, N> {
type Item = &'a mut A;
fn next(&mut self) -> Option {
if let Some(index) = self.bitmap.first_index() {
self.bitmap.set(index, false);
unsafe {
let p: *mut A = &mut self.chunk.values_mut()[index];
Some(&mut *p)
}
} else {
None
}
}
fn size_hint(&self) -> (usize, Option) {
(0, Some(SparseChunk::::CAPACITY))
}
}
/// A draining iterator over the elements of a `SparseChunk`.
///
/// "Draining" means that as the iterator yields each element, it's removed from
/// the `SparseChunk`. When the iterator terminates, the chunk will be empty.
pub struct Drain> {
pub(crate) chunk: SparseChunk,
}
impl<'a, A, N: Bits + ChunkLength> Iterator for Drain {
type Item = A;
fn next(&mut self) -> Option {
self.chunk.pop()
}
fn size_hint(&self) -> (usize, Option) {
let len = self.chunk.len();
(len, Some(len))
}
}
/// An iterator over `Option`s of references to the elements of a `SparseChunk`.
///
/// Iterates over every index in the `SparseChunk`, from zero to its full capacity,
/// returning an `Option<&A>` for each index.
pub struct OptionIter<'a, A, N: Bits + ChunkLength> {
pub(crate) index: usize,
pub(crate) chunk: &'a SparseChunk,
}
impl<'a, A, N: Bits + ChunkLength> Iterator for OptionIter<'a, A, N> {
type Item = Option<&'a A>;
fn next(&mut self) -> Option {
if self.index < N::USIZE {
let result = self.chunk.get(self.index);
self.index += 1;
Some(result)
} else {
None
}
}
fn size_hint(&self) -> (usize, Option) {
(
SparseChunk::::CAPACITY - self.index,
Some(SparseChunk::::CAPACITY - self.index),
)
}
}
/// An iterator over `Option`s of mutable references to the elements of a `SparseChunk`.
///
/// Iterates over every index in the `SparseChunk`, from zero to its full capacity,
/// returning an `Option<&mut A>` for each index.
pub struct OptionIterMut<'a, A, N: Bits + ChunkLength> {
pub(crate) index: usize,
pub(crate) chunk: &'a mut SparseChunk,
}
impl<'a, A, N: Bits + ChunkLength> Iterator for OptionIterMut<'a, A, N> {
type Item = Option<&'a mut A>;
fn next(&mut self) -> Option {
if self.index < N::USIZE {
let result = if self.chunk.map.get(self.index) {
unsafe {
let p: *mut A = &mut self.chunk.values_mut()[self.index];
Some(Some(&mut *p))
}
} else {
Some(None)
};
self.index += 1;
result
} else {
None
}
}
fn size_hint(&self) -> (usize, Option) {
(
SparseChunk::::CAPACITY - self.index,
Some(SparseChunk::::CAPACITY - self.index),
)
}
}
/// A draining iterator over `Option`s of the elements of a `SparseChunk`.
///
/// Iterates over every index in the `SparseChunk`, from zero to its full capacity,
/// returning an `Option` for each index.
pub struct OptionDrain> {
pub(crate) index: usize,
pub(crate) chunk: SparseChunk,
}
impl<'a, A, N: Bits + ChunkLength> Iterator for OptionDrain {
type Item = Option;
fn next(&mut self) -> Option {
if self.index < N::USIZE {
let result = self.chunk.remove(self.index);
self.index += 1;
Some(result)
} else {
None
}
}
fn size_hint(&self) -> (usize, Option) {
(
SparseChunk::::CAPACITY - self.index,
Some(SparseChunk::::CAPACITY - self.index),
)
}
}
#[cfg(test)]
mod test {
use super::*;
use std::iter::FromIterator;
use typenum::U64;
#[test]
fn iter() {
let vec: Vec