use std::iter::{FusedIterator, IntoIterator}; use alloc::rc::Rc; use std::cell::RefCell;
/// A wrapper for `Rc<RefCell<I>>`, that implements the `Iterator` trait. #[derive(Debug)] pubstruct RcIter<I> { /// The boxed iterator. pub rciter: Rc<RefCell<I>>,
}
/// Return an iterator inside a `Rc<RefCell<_>>` wrapper. /// /// The returned `RcIter` can be cloned, and each clone will refer back to the /// same original iterator. /// /// `RcIter` allows doing interesting things like using `.zip()` on an iterator with /// itself, at the cost of runtime borrow checking which may have a performance /// penalty. /// /// Iterator element type is `Self::Item`. /// /// ``` /// use itertools::rciter; /// use itertools::zip; /// /// // In this example a range iterator is created and we iterate it using /// // three separate handles (two of them given to zip). /// // We also use the IntoIterator implementation for `&RcIter`. /// /// let mut iter = rciter(0..9); /// let mut z = zip(&iter, &iter); /// /// assert_eq!(z.next(), Some((0, 1))); /// assert_eq!(z.next(), Some((2, 3))); /// assert_eq!(z.next(), Some((4, 5))); /// assert_eq!(iter.next(), Some(6)); /// assert_eq!(z.next(), Some((7, 8))); /// assert_eq!(z.next(), None); /// ``` /// /// **Panics** in iterator methods if a borrow error is encountered in the /// iterator methods. It can only happen if the `RcIter` is reentered in /// `.next()`, i.e. if it somehow participates in an “iterator knot” /// where it is an adaptor of itself. pubfn rciter<I>(iterable: I) -> RcIter<I::IntoIter> where I: IntoIterator
{
RcIter { rciter: Rc::new(RefCell::new(iterable.into_iter())) }
}
impl<I> Clone for RcIter<I> {
clone_fields!(rciter);
}
impl<A, I> Iterator for RcIter<I> where I: Iterator<Item = A>
{ type Item = A; #[inline] fn next(&mutself) -> Option<Self::Item> { self.rciter.borrow_mut().next()
}
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { // To work sanely with other API that assume they own an iterator, // so it can't change in other places, we can't guarantee as much // in our size_hint. Other clones may drain values under our feet.
(0, self.rciter.borrow().size_hint().1)
}
}
impl<I> DoubleEndedIterator for RcIter<I> where I: DoubleEndedIterator
{ #[inline] fn next_back(&mutself) -> Option<Self::Item> { self.rciter.borrow_mut().next_back()
}
}
/// Return an iterator from `&RcIter<I>` (by simply cloning it). impl<'a, I> IntoIterator for &'a RcIter<I> where I: Iterator
{ type Item = I::Item; type IntoIter = RcIter<I>;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.