You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
3.9 KiB
181 lines
3.9 KiB
//! Iterators for `Populator`
|
|
use super::*;
|
|
use std::iter::{
|
|
self,
|
|
DoubleEndedIterator,
|
|
FusedIterator,
|
|
};
|
|
use std::fmt::{self, Debug};
|
|
|
|
#[derive(Debug, Clone)]
|
|
struct FullIter<T>(std::vec::IntoIter<T>);
|
|
#[derive(Debug)]
|
|
struct PartialIter<T>(std::vec::IntoIter<MaybeUninit<T>>,
|
|
std::vec::IntoIter<AtomicBool>, usize);
|
|
|
|
impl<T> Iterator for FullIter<T>
|
|
{
|
|
type Item = T;
|
|
#[inline]
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
self.0.next()
|
|
}
|
|
#[inline]
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
self.0.size_hint()
|
|
}
|
|
}
|
|
|
|
impl<T> PartialIter<T> {
|
|
#[inline(always)]
|
|
fn next_raw(&mut self) -> Option<(MaybeUninit<T>, bool)>
|
|
{
|
|
let a = self.0.next()?;
|
|
let b = if cfg!(debug_assertions) { self.1.next()? } else { unsafe { self.1.next().unwrap_unchecked() } };
|
|
|
|
self.2-=1;
|
|
Some((a, b.into_inner()))
|
|
}
|
|
}
|
|
|
|
|
|
|
|
impl<T> Iterator for PartialIter<T>
|
|
{
|
|
type Item = T;
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
Some(loop {
|
|
match self.next_raw()? {
|
|
(value, true) => break unsafe { value.assume_init() },
|
|
_ => (),
|
|
}
|
|
})
|
|
}
|
|
#[inline]
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
(self.2, Some(self.2))
|
|
}
|
|
}
|
|
|
|
impl<T> FusedIterator for FullIter<T>{}
|
|
impl<T> ExactSizeIterator for FullIter<T>{}
|
|
|
|
impl<T> FusedIterator for PartialIter<T>{}
|
|
impl<T> ExactSizeIterator for PartialIter<T>{}
|
|
|
|
trait PopulaterIter<T>: private::Sealed + Iterator<Item=T> + FusedIterator + ExactSizeIterator{
|
|
fn as_debug(&self) -> &dyn Debug
|
|
where T: Debug;
|
|
}
|
|
|
|
impl<T> private::Sealed for PartialIter<T>{}
|
|
impl<T> private::Sealed for FullIter<T>{}
|
|
|
|
impl<'a, T: 'a + Debug> Debug for dyn PopulaterIter<T> + 'a {
|
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result
|
|
{
|
|
self.as_debug().fmt(fmt)
|
|
}
|
|
}
|
|
|
|
impl<T> PopulaterIter<T> for PartialIter<T>
|
|
{
|
|
#[inline(always)]
|
|
fn as_debug(&self) -> &dyn Debug
|
|
where T: Debug {
|
|
self
|
|
}
|
|
}
|
|
|
|
impl<T> PopulaterIter<T> for FullIter<T>
|
|
{
|
|
#[inline(always)]
|
|
fn as_debug(&self) -> &dyn Debug
|
|
where T: Debug {
|
|
self
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct IntoIter<'a, T: 'a>(Box<dyn PopulaterIter<T> + 'a>);
|
|
|
|
/*
|
|
impl<'a, Iter, T: 'a> From<Iter> for IntoIter<'a, T>
|
|
where Iter: private::Sealed + PopulaterIter<T> + 'a
|
|
{
|
|
#[inline(always)]
|
|
fn from(v: Iter) -> Self {
|
|
Self(Box::new(v))
|
|
}
|
|
}
|
|
*/
|
|
|
|
#[inline(always)]
|
|
unsafe fn assume_init_boxed<T>(bx: Box<[MaybeUninit<T>]>) -> Box<[T]>
|
|
{
|
|
let raw = Box::into_raw(bx);
|
|
|
|
Box::from_raw(raw as *mut [T])
|
|
}
|
|
|
|
impl<'a, T> IntoIter<'a, T>
|
|
{
|
|
pub(super) fn create_from(mut pop: Populator<'a, T>) -> Self
|
|
{
|
|
Self(if pop.is_full_exclusive() {
|
|
let values = pop.take_values();
|
|
|
|
Box::new(FullIter(Vec::from(unsafe { assume_init_boxed(values) }).into_iter()))
|
|
} else {
|
|
let (values, populates) = pop.take_all();
|
|
|
|
Box::new(PartialIter(Vec::from(values).into_iter(),
|
|
Vec::from(populates).into_iter(),
|
|
*pop.populated.get_mut()))
|
|
})
|
|
}
|
|
}
|
|
|
|
impl<'a, T> Iterator for IntoIter<'a, T>
|
|
{
|
|
type Item = T;
|
|
#[inline]
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
self.0.next()
|
|
}
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
self.0.size_hint()
|
|
}
|
|
}
|
|
impl<'a, T> FusedIterator for IntoIter<'a, T>{}
|
|
impl<'a, T> ExactSizeIterator for IntoIter<'a, T>{}
|
|
|
|
#[derive(Debug)]
|
|
struct FullIterRef<'a, T>(std::slice::Iter<'a, T>);
|
|
//struct PartialIterRef<'a, T>(&) //XXX: This probably isn't possible unless it takes an exclusive reference of Populator<'a, T>. Having to pass 'a around really sucks hey.
|
|
|
|
impl<'a, T> Iterator for FullIterRef<'a, T>
|
|
{
|
|
type Item = &'a T;
|
|
#[inline]
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
self.0.next()
|
|
}
|
|
#[inline]
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
self.0.size_hint()
|
|
}
|
|
}
|
|
|
|
impl<'a, T> DoubleEndedIterator for FullIterRef<'a, T>
|
|
{
|
|
fn next_back(&mut self) -> Option<Self::Item> {
|
|
self.0.next_back()
|
|
}
|
|
}
|
|
|
|
impl<'a, T> FusedIterator for FullIterRef<'a, T>{}
|
|
impl<'a, T> ExactSizeIterator for FullIterRef<'a, T>{}
|
|
|
|
|