#![feature(generator_trait)]
use std::collections::LinkedList;
use std::{
ops::{Generator, GeneratorState},
pin::Pin,
};
#[cfg(feature = "rayon")]
use rayon::prelude::*;
pub struct YieldIter<G>(G);
impl<G> Unpin for YieldIter<G> {}
impl<G: Generator + Unpin> YieldIter<G> {
#[inline]
pub fn new(generator: G) -> Self {
Self(generator)
}
}
impl<G: Generator + Unpin> Iterator for YieldIter<G> {
type Item = G::Yield;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
Pin::new(self).next()
}
}
impl<G: Generator + Unpin> YieldIter<G> {
#[inline]
pub unsafe fn new_unchecked(generator: G) -> Self {
Self(generator)
}
}
impl<G: Generator> Iterator for Pin<&mut YieldIter<G>> {
type Item = G::Yield;
fn next(&mut self) -> Option<Self::Item> {
let this: Pin<&mut YieldIter<G>> = self.as_mut();
let gen = unsafe { this.map_unchecked_mut(|gen| &mut gen.0) };
match gen.resume(()) {
GeneratorState::Yielded(y) => Some(y),
GeneratorState::Complete(_) => None,
}
}
}
#[cfg(feature = "rayon")]
impl<G> IntoParallelIterator for YieldIter<G>
where
G: Generator + Unpin,
G::Yield: Sync + Send,
{
type Iter = rayon::vec::IntoIter<Self::Item>;
type Item = G::Yield;
fn into_par_iter(self) -> Self::Iter {
Vec::from_iter(self).into_par_iter()
}
}
#[macro_export]
macro_rules! generator {
($($x:tt)*) => {
unsafe {
$crate::YieldIter::new_unchecked(|| {
$($x)*
})
} };
}